Hello,
I have a SwiftUI application with a Core Data model. This model contains some entities, with properties. The canvas is working as expected, showing the preview.
But whenever I add a new entity, event without any property, the canvas fail to show the preview (event a basic view with only a text view in it). The error message is the following:
Cannot preview in this file - The operation couldn't be completed. Transaction failed. Process failed to launch. I tried to clean my cache, the derived data folder, reset the simulators, etc. When I click on Diagnostics, here is the message:
Error Domain=FBProcessExit Code=4 "The process crashed." UserInfo={NSLocalizedFailureReason=The process crashed., BSErrorCodeDescription=crash, NSUnderlyingError=0x600002f29dd0 {Error Domain=signal Code=4 "SIGILL(4)" UserInfo={NSLocalizedFailureReason=SIGILL(4)}}} RemoteHumanReadableError: The operation couldn’t be completed. Transaction failed. Process failed to launch. (process launch failed) BSTransactionError (1):
==error-description: Process failed to launch.
==precipitating-error: Error Domain=FBProcessExit Code=4 "The process crashed." UserInfo={NSLocalizedFailureReason=The process crashed., BSErrorCodeDescription=crash, NSUnderlyingError=0x600002f29dd0 {Error Domain=signal Code=4 "SIGILL(4)" UserInfo={NSLocalizedFailureReason=SIGILL(4)}}}
==NSLocalizedFailureReason: Transaction failed. Process failed to launch. (process launch failed)
==transaction: <FBApplicationProcessLaunchTransaction: 0x60000186d960>
==error-reason: process launch failed Any idea why I have that?
Thanks,
Axel
PS: I'm using Xcode 12 beta 6 (also tried on beta 5). I'm on macOS Big Sur (20A5364e).
Post
Replies
Boosts
Views
Activity
Hello,
I'm implementing Sign In With Apple in a SwiftUI application (iOS 14, SwiftUI 2). I'm importing the AuthenticationServices framework. The app build successfully, and can run on an iOS device or simulator. But I cannot preview the view in the Preview / Canvas (it would be easier to design the view).
Cannot find 'SignInWithAppleButton' in scope
Any idea why?
Thanks
Axel
PS: Xcode 12 beta 6, macOS Big Sur beta 5
Hello,
According to Apple's documentation regarding Picker in SwiftUI using an Enum, - https://developer.apple.com/documentation/swiftui/picker if the enum conforms to the Identifiable protocol in addition to CaseIterable, a picker iterating over all cases should update the bound variable natively.
I tested it, and it does not work as expected.
However, if I pass a tag for each view, it works.
See my Stack Overflow question for screenshots - https://stackoverflow.com/questions/64276333/swiftui-picker-driven-by-an-enum-value-not-updated
What's happening here? Is the Apple documentation wrong? The selectedFlavor variable expects a value of type Flavor, but the id used in the picker is actually a String.
Thanks.
I currently have an app using Core Data in the App Store: the app allows people to record their water and sailing activities (think of it like Strava for sailors). I have not updated the app for 3 years, the app seems to be still working fine on latest iOS versions but I recently planned to improve the app.
I am currently working on an update for this app, and need to change the data model and schema. I would like to have an automatic lightweight migration. I renamed some entities, properties and relationships, but I made sure to put the previous ids in the Renaming ID field in the editor. I want to take advantage of the opportunity to sync the updated schema on CloudKit. I followed the instruction on Apple Developer documentation to setup the sync. I also made sure to initialize the schema using initializeCloudKitSchema(). When I visit the dashboard, I see the correct schema. The container is only in development mode, not pushed into production.
When I launch the app with a sqlite file generated by the available app, it seems the migration works well because the data is still here and correct. I can navigate in the app normally and when I visit the CloudKit dashboard, the data is correctly saved.
But sometimes, the app crashes at launch with the following error:
Older devices can't process the new relationships.
NSUnderlyingException=CloudKit integration forbids renaming 'crewMembers' to 'sailors'.
Older devices can't process the new relationships.}}}
Fatal error: Unresolved error Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration."
The concerned entities were renamed, as the relationships and the relationship is a many-to-many, optional on both sides. This is occurring even if I reset the CloudKit development container. I don’t really have a clear idea of when this is appearing (seems random, after I updated some data or after I update the Core Data model). Any idea why the app is crashing? I would like as much as possible to keep the new naming for my entities and relationships.
SKPRCrewMemberMO renamed to Sailor
SKPRTrackMO renamed to Activity
crewMembers <<--->> tracks renamed sailors <<--->> activities
Here are some screenshots of the previous and updated data model for the entity at the origin of the migration issue, as well as some code regarding my Core Data stack initialization and the console error il getting.
https://stackoverflow.com/questions/64383629/core-data-and-cloudkit-integration-issue-when-renaming-relationship-code-134110
PS: the app is used by few hundreds of people. That’s not a lot, but still, some of them have dozens of recorded activities and I don’t want to break anything and lose or corrupt data. I could launch a new app but users would lose their progress as it’s only saved locally in a shared container (app group was used as I wanted to share the Core Data with an Apple Watch extension). And I would lose the user base and App Store related things.
		container = NSPersistentCloudKitContainer(name: "Skipper")
		
		guard let description = container.persistentStoreDescriptions.first else {
				fatalError("###\(#function): Failed to retrieve a persistent store description.")
		}
		description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
		description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
		let id = "iCloud.com.alepennec.sandbox20201013"
		let options = NSPersistentCloudKitContainerOptions(containerIdentifier: id)
		description.cloudKitContainerOptions = options
		
		container.loadPersistentStores(completionHandler: { (storeDescription, error) in
				if let error = error as NSError? {
						fatalError("Unresolved error \(error), \(error.userInfo)")
				}
		})
		
		do {
				try container.initializeCloudKitSchema()
		} catch {
				print("Unable to initialize CloudKit schema: \(error.localizedDescription)")
		}
		
		container.viewContext.automaticallyMergesChangesFromParent = true
		container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
}
Like in a lot of apps, I have a list of items (populated by a Core Data fetch request), a sheet to create new items, and a sheet to edit an item when tapping on a row in my list. I'm trying to unify both forms to create and edit an update, and put the cancel / save logic in a superview of the form.
So I've something like this:
ListView: a list with row populated by a Core Data fetch request
AddView: a NavigationView with the FormView embed + cancel and save button
EditView: a NavigationView with the FormView embed + cancel and save button
FormView: a TextField to update the name of the item
In the init() for the AddView, I create a new NSManagedObject without any context (I do that because I don't want my ListView to be updated when I create a new item in the AddView, but only when I save this item -> alternative could be to use a child context, or filter the fetch request results based on the isInserted or objectID.isTemporaryID of the return objects). AddView contains a NavigationView with the FormView embed, a cancel button, and a save button. This save button is disabled based on a computed property on the managed object (name for the object can't be nil).
In the EditView, I pass the item that was tapped from the ListView. This item is an existing NSManagedObject attached to the main viewContext of the app (coming from the fetch request of the ListView). EditView contains a NavigationView with the FormView embed, a cancel button and a save button (exactly like the AddView). This save button is also disabled based on the same computed property.
My issue is that when I update the name of the item from the TextField in my FormView, the condition to enable / disable the save button is not working for the AddView (this AddView is actually not refreshed when I change the item name from the FormView) but working for the EditView (this EditView is refreshed when I change the item name from the FormView). If I attach a context to the new NSManagedObject in the init() of the AddView, the condition is working like in the EditView.
So it appears that a NSManagedObject without any context is not observed by SwiftUI? Am I missing anything or is that a bug?
Like in a lot of apps, I have a list of items (populated by a Core Data fetch request), a sheet to create new items, and a sheet to edit an item when tapping on a row in my list. I'm trying to unify both forms to create and edit an update, and put the cancel / save logic in a superview of the form.
So I've something like this:
ListView: a list with row populated by a Core Data fetch request
AddView: a NavigationView with the FormView embed + cancel and save button
EditView: a NavigationView with the FormView embed + cancel and save button
FormView: a TextField to update the name of the item
In the init() for the AddView, I create a new NSManagedObject without any context (I do that because I don't want my ListView to be updated when I create a new item in the AddView, but only when I save this item -> alternative could be to use a child context, or filter the fetch request results based on the isInserted or objectID.isTemporaryID of the return objects). AddView contains a NavigationView with the FormView embed, a cancel button, and a save button. This save button is disabled based on a computed property on the managed object (name for the object can't be nil).
In the EditView, I pass the item that was tapped from the ListView. This item is an existing NSManagedObject attached to the main viewContext of the app (coming from the fetch request of the ListView). EditView contains a NavigationView with the FormView embed, a cancel button and a save button (exactly like the AddView). This save button is also disabled based on the same computed property.
My issue is that when I update the name of the item from the TextField in my FormView, the condition to enable / disable the save button is not working for the AddView (this AddView is actually not refreshed when I change the item name from the FormView) but working for the EditView (this EditView is refreshed when I change the item name from the FormView). If I attach a context to the new NSManagedObject in the init() of the AddView, the condition is working like in the EditView.
So it appears that a NSManagedObject without any context is not observed by SwiftUI? Am I missing anything or is that a bug?
I have two entities in my app: User & Expense. A user has many expenses. Expense as an attribute amount (of type Int32).
I added a derived attribute expensesCount (of type Int16) on the user to count the number of expenses, using the derivation expenses.@count. It's working fine, the app compiles, launches, and when I save a relationship, the value for the expensesCount attribute is updated.
I also added a derived attribute expensesAmount on the user to count the total amount of all related expenses. I use the derivation expenses.amount.@sum. The app compiles but crash at launch with the following error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'currently unsupported (unsupported function on to many (not count or sum))'
Any idea why?
PS: I also tried another synthax recommended on Twitter (by Scott Perry from Apple team): sum:(expenses.amount), but I got the same crash.
Hello,
I'm currently adding StoreKit 2 into my app. I've watched the WWDC21 session (Meet SK2) and downloaded the sample SKDemo app. When I want to test the Ask To Buy flow, it does not work: I see the sheet on the device, I see the alert and tap on the "Ask" button. In Xcode, I then approve the transaction but the func listenForTransactions() -> Task<Void, Error> is never called. I'm testing the app in Debug mode, on a real device and on a simulator (using the Products.storekit local configuration file).
What's wrong?
Thanks,
Axel
Version 13.2 beta 2 (13C5081f)
iOS 15.2 (19C5044b)
func listenForTransactions() -> Task<Void, Error> {
return Task.detached {
for await result in Transaction.updates {
do {
let transaction = try self.checkVerified(result)
await self.updatePurchasedIdentifiers(transaction)
await transaction.finish()
} catch {
print("Transaction failed verification")
}
}
}
}
Hello,
When 'Ask To Buy' is enabled, and the user cancels the request (left button on the provided screenshot below), the purchaseResult in iOS 15 is set to .pending when we call try await product.purchase(). It's wrong, it should be set to .userCancelled because the parent will never receive any approval request in this case. It breaks the logic in my app because tracking real pending requests is then not possible.
I also think that a declined transaction should be made available to the app in the transactions observer: how can we remove a pending transaction that had been declined? We can't for the moment.
Thanks,
Axel
Hello,
I want to access the latest transaction for a Subscription Group. I use the following method static func status(for groupID: String) async throws -> [Product.SubscriptionInfo.Status] to access the statuses for the group, and from there, I can get a verified transaction from the status.
But when I set the GroupID equal to the Subscription Group Reference Name I put in the .storekit configuration file in Xcode, I don't have any status (so wrong ID). Actually, I have to use a subscriptionGroupID like 3F19ED53 (found using a previous transaction: https://developer.apple.com/documentation/storekit/transaction/3749718-subscriptiongroupid).
When I look into a Product, this ID is set for subscriptionFamilyId.
So my question is how can I know the ID if it's not the one I provided in App Store Connect or the config file? Do I first have to access a Product from this group?
Thanks.
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
Let's imagine an app with two plans, one for individual (level of service 2) and one for family (level of service 1).
If a user is subscribed as an individual, but if someone in his family shares a family plan with him, will Transaction.currentEntitlements show both subscriptions?
Or only the transaction where the user is the owner (in this case the individual subscription)?
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?
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)
}
}
When dealing with auto-renewable subscriptions, there are multiple ways to access the latest transaction. We can access it when a purchase is made, or we can request the latest transaction for a given productID at a later time. To do so, we can use Transaction.latest(for:), access the transaction history using Transaction.all, get the currentEntitlements, or use the array of Product.SubscriptionInfo.Statusthan contains the latest transaction for a subscription group. It's also necessary to listen to transactions when the app is running using the AsyncSequenceTransaction.updates`.
In my app (and also in the SKDemo project from Apple), when I want to access the latest transaction as soon as the app is launched, it's missing the transactions that renewed or happened while the app was not running. I tried using the different methods mentioned above but they never give me the latest transaction, always the latest transaction while the app was running before I killed it. I have to wait for a new renewal event to receive the latest transaction in the Transaction.updates listener, which is not good. For example, when I set the Subscription Renewal Rate to Monthly Renewal Every 30 seconds, and I quit the app when the latest transactionId is 100, I wait for 5 minutes, I expect to see the transactionId 110 but I see 100. In the real life, it means that if the app is not running when a monthly or annual subscription renews, I have to wait weeks or months to receive the missing transaction. I thought that the Transaction.updates listener would be called at launch with all the transactions that occurred while the app was not running.
Is that a bug in Xcode or have I misunderstood something? How can I access the real latest transaction that happened when the app was not running at launch? I need to access that to know what the user has access to. I think the transaction management panel from Xcode displays all the transactions, even the one when the app was not running.
PS: I'm using Xcode 13.2.1 and iOS 15.0 (simulator). Transaction.updates is not working on iOS 15.2 (my device, or simulator) from what I've seen so far.