Post

Replies

Boosts

Views

Activity

Xcode 14b2 Previews with SPM: AppHostMustHaveGetTaskAllowError: XCPreviewAgent.app not code signed properly "XCPreviewAgent.app" must be code signed in order to use on-device previews. Check your code signing settings for the target. com.apple.dt.U
I'm trying to use Previews in a Swift Package in Xcode 14b2 but it's not working (it was working in Xcode 13). I have the following error message but I don't know how to solve it. "XCPreviewAgent.app" must be code signed in order to use on-device previews. Check your code signing settings for the target. com.apple.dt.UVPreviewAgent-watchOS.watchkitapp {     url: file:///Applications/Xcode-beta.app/Contents/Developer/Platforms/WatchOS.platform/Developer/Library/Xcode/Agents/XCPreviewAgent.app     version: 20.0.32.2     attributes: [         ObjectIdentifier(0x00000001638e5d18): ["OS_ACTIVITY_DT_MODE": "YES", "SQLITE_ENABLE_THREAD_ASSERTIONS": "1"],     ] }
1
0
1.4k
Jun ’22
Are Privacy Nutrition Labels in App Store Connect automatically updated based on Privacy Manifest files in the app and third-party SDKs?
Hello, I include a Privacy Manifest file in my app and specify one Privacy Nutrition Label Type (Email Address, for marketing purposes). My app uses some third-party SDKs like RevenueCat that contain Privacy Manifest files with nutrition label types specified (Purchases History for RevenueCat for example). Xcode can generate a report that aggregates all the data types that are collected by the app. But is App Store Connect updated when I upload a build? Or do I have to manually setup the App Privacy info? Thanks
1
0
746
Jun ’24
Automatic Grammar Agreement with formatted number: use integer value to switch categories
Hello, I want to use Automatic Grammar Agreement to localise a string in my app, let say "three remaining activities". The string "three" is obtained by using a NumberFormatter with a numberStyle set to .spellOut (so I'm not using an Integer) var formatter: NumberFormatter = NumberFormatter() formatter.numberStyle = .spellOut let formattedCount: String = numberFormatter.string(from: count as NSNumber)! Text("key_with_string_\(formattedCount)") In my string catalog, I have translated the key key_with_string_%@ like this ^[%@ remaining activity](inflect: true), but it does not work. I've tried to add the integer value used by the number formatter in the key key_with_string_%@_%lld but it does not work. Should Automatic Grammar Agreement work normally just by using the formatted string provided by the NumberFormatter? If not, is there a way to specify to use a secondary variable (my count integer) to switch between different categories like one and other automatically? Thanks ! Axel
1
0
886
Jun ’24
SwiftData thread-safety: passing models between threads
Hello, I'm trying to understand how dangerous it is to read and/or update model properties from a thread different than the one that instantiated the model. I know this is wrong when using Core Data and we should always use perform/performAndWait before manipulating an object but I haven't found any information about that for SwiftData. Question: is it safe to pass an object from one thread (like MainActor) to another thread (in a detached Task for example) and manipulate it, or should we re fetch the object using its persistentModelID as soon as we cross threads? When running the example app below with the -com.apple.CoreData.ConcurrencyDebug 1 argument passed at launch enabled, I don't get any Console warning when I tap on the "Update directly" button. I'm sure it would trigger a warning if I were using Core Data. Thanks in advance for explaining. Axel -- @main struct SwiftDataPlaygroundApp: App { var body: some Scene { WindowGroup { ContentView() .modelContainer(for: Item.self) } } } struct ContentView: View { @Environment(\.modelContext) private var context @Query private var items: [Item] var body: some View { VStack { Button("Add") { context.insert(Item(timestamp: Date.now)) } if let firstItem = items.first { Button("Update directly") { Task.detached { // Not the main thread, but firstItem is from the main thread // No warning in Xcode firstItem.timestamp = Date.now } } Button("Update using persistentModelID") { let container: ModelContainer = context.container let itemIdentifier: Item.ID = firstItem.persistentModelID Task.detached { let backgroundContext: ModelContext = ModelContext(container) guard let itemInBackgroundThread: Item = backgroundContext.model(for: itemIdentifier) as? Item else { return } // Item on a background thread itemInBackgroundThread.timestamp = Date.now try? backgroundContext.save() } } } } } } @Model final class Item: Identifiable { var timestamp: Date init(timestamp: Date) { self.timestamp = timestamp } }
1
1
780
Oct ’24
SwiftData updates in the background are not merged in the main UI context
Hello, SwiftData is not working correctly with Swift Concurrency. And it’s sad after all this time. I personally found a regression. The attached code works perfectly fine on iOS 17.5 but doesn’t work correctly on iOS 18 or iOS 18.1. A model can be updated from the background (Task, Task.detached or ModelActor) and refreshes the UI, but as soon as the same item is updated from the View (fetched via a Query), the next background updates are not reflected anymore in the UI, the UI is not refreshed, the updates are not merged into the main. How to reproduce: Launch the app Tap the plus button in the navigation bar to create a new item Tap on the “Update from Task”, “Update from Detached Task”, “Update from ModelActor” many times Notice the time is updated Tap on the “Update from View” (once or many times) Notice the time is updated Tap again on “Update from Task”, “Update from Detached Task”, “Update from ModelActor” many times Notice that the time is not update anymore Am I doing something wrong? Or is this a bug in iOS 18/18.1? Many other posts talk about issues where updates from background thread are not merged into the main thread. I don’t know if they all are related but it would be nice to have 1/ bug fixed, meaning that if I update an item from a background, it’s reflected in the UI, and 2/ proper documentation on how to use SwiftData with Swift Concurrency (ModelActor). I don’t know if what I’m doing in my buttons is correct or not. Thanks, Axel import SwiftData import SwiftUI @main struct FB_SwiftData_BackgroundApp: App { var body: some Scene { WindowGroup { ContentView() .modelContainer(for: Item.self) } } } struct ContentView: View { @Environment(\.modelContext) private var modelContext @State private var simpleModelActor: SimpleModelActor! @Query private var items: [Item] var body: some View { NavigationView { VStack { if let firstItem: Item = items.first { Text(firstItem.timestamp, format: Date.FormatStyle(date: .omitted, time: .standard)) .font(.largeTitle) .fontWeight(.heavy) Button("Update from Task") { let modelContainer: ModelContainer = modelContext.container let itemID: Item.ID = firstItem.persistentModelID Task { let context: ModelContext = ModelContext(modelContainer) guard let itemInContext: Item = context.model(for: itemID) as? Item else { return } itemInContext.timestamp = Date.now.addingTimeInterval(.random(in: 0...2000)) try context.save() } } .buttonStyle(.bordered) Button("Update from Detached Task") { let container: ModelContainer = modelContext.container let itemID: Item.ID = firstItem.persistentModelID Task.detached { let context: ModelContext = ModelContext(container) guard let itemInContext: Item = context.model(for: itemID) as? Item else { return } itemInContext.timestamp = Date.now.addingTimeInterval(.random(in: 0...2000)) try context.save() } } .buttonStyle(.bordered) Button("Update from ModelActor") { let container: ModelContainer = modelContext.container let persistentModelID: Item.ID = firstItem.persistentModelID Task.detached { let actor: SimpleModelActor = SimpleModelActor(modelContainer: container) await actor.updateItem(identifier: persistentModelID) } } .buttonStyle(.bordered) Button("Update from ModelActor in State") { let container: ModelContainer = modelContext.container let persistentModelID: Item.ID = firstItem.persistentModelID Task.detached { let actor: SimpleModelActor = SimpleModelActor(modelContainer: container) await MainActor.run { simpleModelActor = actor } await actor.updateItem(identifier: persistentModelID) } } .buttonStyle(.bordered) Divider() .padding(.vertical) Button("Update from View") { firstItem.timestamp = Date.now.addingTimeInterval(.random(in: 0...2000)) } .buttonStyle(.bordered) } else { ContentUnavailableView( "No Data", systemImage: "slash.circle", // 􀕧 description: Text("Tap the plus button in the toolbar") ) } } .toolbar { ToolbarItem(placement: .primaryAction) { Button(action: addItem) { Label("Add Item", systemImage: "plus") } } } } } private func addItem() { modelContext.insert(Item(timestamp: Date.now)) try? modelContext.save() } } @ModelActor final actor SimpleModelActor { var context: String = "" func updateItem(identifier: Item.ID) { guard let item = self[identifier, as: Item.self] else { return } item.timestamp = Date.now.addingTimeInterval(.random(in: 0...2000)) try! modelContext.save() } } @Model final class Item: Identifiable { var timestamp: Date init(timestamp: Date) { self.timestamp = timestamp } }
1
1
774
Apr ’25
Are data in an iCloud NSUbiquitousKeyValueStore directly available at app launch on another device?
Hello, I'm planning to had an onboarding to one of my apps. I am thinking about a way for a user to not see the onboarding again if he installs the app on another device. So for example, the user completes the onboarding on its iPhone, then downloads the app on its iPad and launch it, he doesn't see the onboarding a second time. I thought about using iCloud NSUbiquitousKeyValueStored to store the onboarding completion state. But I'm not sure when the data is synced to the other device logged into the same Apple account: Immediately even if the app is not installed on the other device (independent from the app, only iCloud thing)? At the same time as the app install on the other device? After the app is first launched on the other device? Of course synchronisation will depend on the Internet connection, speed, etc. so the app should handle the case where the data is not here but what would be the best case scenario? Thank you, Axel
1
0
74
Aug ’25
StoreKit 2 • How to know when a user cancelled the subscription during free trial?
Hello, When a user cancels a subscription during a free trial, we should stop providing access to content. How can we know that? From the in app management in Xcode, when I cancel a subscription during free trial period (cancelling in the few seconds after the purchase), the currentEntitlements still provide the subscription. How to know when a user cancelled the subscription during free trial? Thanks
2
0
2.7k
Nov ’21
StoreKit 2: how can we test Family Sharing?
I'm not a member of any Family in iCloud. I want to understand what happens when a user is subscribed through Family Sharing but also how to use StoreKit when the user is subscribed twice: as an individual who purchased the product and as a member of a family when the purchase is shared with him. How can I test Family Sharing for an app offering a product with Family Sharing enabled? Is it possible to create a fake Family in App Store Connect and add testers to it?
2
0
1.9k
Dec ’21
CloudKit: how to handle CKError partialFailure when using NSPersistentCloudKitContainer?
I'm using NSPersistentCloudKitContainer with Core Data and I receive errors because my iCloud space is full. The errors printed are the following: <CKError 0x280df8e40: "Quota Exceeded" (25/2035); server message = "Quota exceeded"; op = 61846C533467A5DF; uuid = 6A144513-033F-42C2-9E27-693548EF2150; Retry after 342.0 seconds>. I want to inform the user about this issue, but I can't find a way to access the details of the error. I'm listening to NSPersistentCloudKitContainer.eventChangedNotification, I receive a error of type .partialFailure. But when I want to access the underlying errors, the partialErrorsByItemID property on the error is nil. How can I access this Quota Exceeded error? import Foundation import CloudKit import Combine import CoreData class SyncMonitor { fileprivate var subscriptions = Set<AnyCancellable>() init() { NotificationCenter.default.publisher(for: NSPersistentCloudKitContainer.eventChangedNotification) .sink { notification in if let cloudEvent = notification.userInfo?[NSPersistentCloudKitContainer.eventNotificationUserInfoKey] as? NSPersistentCloudKitContainer.Event { guard let ckerror = cloudEvent.error as? CKError else { return } print("Error: \(ckerror.localizedDescription)") if ckerror.code == .partialFailure { guard let errors = ckerror.partialErrorsByItemID else { return } for (_, error) in errors { if let currentError = error as? CKError { print(currentError.localizedDescription) } } } } } // end of sink .store(in: &subscriptions) } }
2
1
1.4k
Aug ’25
SwiftUI: Fatal error: No ObservableObject of type * found. A View.environmentObject(_:) for * may be missing as an ancestor of this view.
Hello, The app displays a list of posts (Post), and for each post, a list of tags (Tag). The Post detail view shows a list of tags for a given post. The Tag detail view shows the post name and the tag name. Both Post and Tag are ObservableObject, and both are passed to the environment when a NavigationLink is tapped. On the master List with all the posts, you tap on a post. The post is passed in the environment. It's working because the detail view for the selected post is correctly displayed, and you can choose to display a tag from the tags in the displayed post. But when you tap on a tag to view the details, the app crashes: the post object is not in the environment. No ObservableObject of type Post found. A View.environmentObject(_:) for Post may be missing as an ancestor of this view. Why? The post object in the PostView, so it should be also available in the TagView because the TagView can only be displayed from the PostView. Thanks Axel import SwiftUI class Store: ObservableObject {     @Published var posts: [Post] = [         Post(name: "Post 1", tags: [.init(name: "Tag 1"), .init(name: "Tag 2")]),         Post(name: "Post 2", tags: [.init(name: "Tag 1"), .init(name: "Tag 2")])     ] } class Post: ObservableObject, Identifiable, Hashable {     @Published var name: String = ""     @Published var tags: [Tag] = []     var id: String { name }     init(name: String, tags: [Tag]) {         self.name = name         self.tags = tags     }     static func == (lhs: Post, rhs: Post) -> Bool {         return lhs.id == rhs.id     }     func hash(into hasher: inout Hasher) {         hasher.combine(id)     } } class Tag: ObservableObject, Identifiable, Hashable {     @Published var name: String = ""     var id: String { name }     init(name: String) {         self.name = name     }     static func == (lhs: Tag, rhs: Tag) -> Bool {         return lhs.id == rhs.id     }     func hash(into hasher: inout Hasher) {         hasher.combine(id)     } } struct PassEnvironmentObject: View {     @StateObject private var store: Store = .init()     var body: some View {       NavigationStack {             List {                 ForEach(store.posts) { post in                     NavigationLink(post.name, value: post)                 }             }             .navigationDestination(for: Post.self) { post in                 PostView()                     .environmentObject(post)           }             .navigationDestination(for: Tag.self) { tag in                 TagView()                     .environmentObject(tag)             }         }     } } struct PostView: View {     @EnvironmentObject private var post: Post     var body: some View {         List {             ForEach(post.tags) { tag in                 NavigationLink(tag.name, value: tag)             }         }     } } struct TagView: View {     @EnvironmentObject private var post: Post     @EnvironmentObject private var tag: Tag     var body: some View {         VStack {             Text(post.name)             Text(tag.name)         }     } } struct PassEnvironmentObject_Previews: PreviewProvider {     static var previews: some View {         PassEnvironmentObject()     } }
2
0
2.0k
Jun ’22
iOS Location Services: updates not received when device has been locked for a while.
Hello I’ve a question regarding CLLocationManager as I’m observing a strange behaviour when receiving location updates. And I don’t really know what could be the culprit here. Some information regarding the device: Device: iPhone Xs Max OS: iOS 16.1 beta 4 App Background Modes: locations updates checked. CLLocationManager setup: CLAuthorizationStatus: authorizedWhenInUse CLAccuracyAuthorization: fullAccuracy allowsBackgroundLocationUpdates is ON pausesLocationUpdatesAutomatically is OFF (but toggle to turn in on in the POC) activityType (CLActivityType): .otherNavigation (but tried other options). desiredAccuracy (CLLocationAccuracy) : kCLLocationAccuracyNearestTenMeters (to receive GPS updates, and not cell towers) distanceFilter CLLocationDistance): kCLDistanceFilterNone (-1) or 0. When I record with the device unlocked, everything is working fine with the app either in foreground or in background. It receives location updates as I walk around with quite good accuracy (between 5 and 15 meters, see attachment). But I notice that when the device is locked in my pocket, the location service stops receiving updates after a while (like few minutes). I tried with Wi-Fi off and it behaves the same. You can see that in my screenshots attached: many values are incorrect (speed, course). When I open the app again (not crashed), the locations are received again but the horizontalAccuracy is not very good: it’s as if it was not using the GPS anymore. I tried with low power mode enabled and disabled, and I think it behaves the same but maybe not? Is the low power mode responsible for this discrepancies?  As far as I know, it does not modify location services accuracy (only network, background tasks, etc.). Thanks
2
0
2.6k
Nov ’22
Xcode Export Localizations for an iOS app using Swift Package Manager packages fails: No such module UIKit
I'm building an iOS app (the supported destinations in the app target are iOS, iPad and Mac - Designed for iPad). I've many SPM frameworks in order to split my codebase in different features. I want to export the localisations for the different packages and the app using Xcode but it fails. I followed the Apple guide regarding SPM localization: the packages contains a Resources folder with a folder for each language supported. I specified the platforms .iOS(.v16) in the packages. But it seems that exporting the localisations using the Product > Export Localizations feature in Xcode compiles also the packages and app for macOS. Here is the error message: Showing Recent Messages /Users/axel/Developer/AppName/Packages/Helpers/Sources/Helpers/UIKit/UIImage+Extension.swift:7:14: No such module 'UIKit' /Users/axel/Developer/AppName/Packages/Helpers/Sources/Helpers/UIKit/UIImage+Extension.swift:7:14: UIKit is not available when building for macOS. Consider using `#if canImport(UIKit)` to conditionally import this framework. Is there a way to have the export feature work when building an iOS app with packages specified for iOS?
2
0
2.2k
Feb ’23
Swift Packages: exclude developments resources/assets from package used in archived app.
When using Swift Packages in Xcode, is there a way to exclude files conditionally (in DEBUG or similar)? I know I can exclude files but I want them while in development. I have a package that contains developments resource/assets (used to seed a Core Data database for the simulator + for Previews, with images and files), but I don't want to include these files in the package used by the real app when archiving. Can we achieve that?
2
0
2.7k
Feb ’23
SwiftUI Map: is it possible to add an inset to the map visible rectangle?
In UIKit, we can add an insets to a MKMapView with setVisibleMapRect to have additional space around a specified MKMapRect. It's useful for UIs like Apple Maps or FlightyApp (see first screenshot attached). This means we can have a modal sheet above the map but still can see all the content added to the map. I'm trying to do the same for a SwiftUI Map (on iOS 17) but I can't find a way to do it: see screenshot 2 below. Is it possible to obtain the same result or should I file a feedback for an improvement?
2
0
1.8k
Feb ’24