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
Post
Replies
Boosts
Views
Activity
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 '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'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")
}
}
}
}
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.
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 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
}
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.
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,
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).