You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
For certain versions of iOS under certain conditions iOS can prewarm apps. RevenueCat writes about this in the documentation. There's also some community discussion.
The documentation only writes about issues when not using anonymous identifiers. But the problem scope is bigger. When an app is launched for prewarming, access to the file system is not possible, which includes UserDefaults (which are used by RevenueCat during the configuration).
This resulted in end users reporting losing access (they lost entitlements and got a new anonymous ID) after a reboot until they restored purchases. I fixed with a workaround of detecting the prewarming state and in this case configuring RevenueCat later. But as prewarming will only get more common with the popularity of live activities and the dynamic island a mission critical SDK like RevenueCat should mitigate this internally. Most developers don't know about prewarming and the behavior of completeFileProtectionUntilFirstUserAuthentication, which is the default for most files. So this results in very difficult bugs and frustrated end users.
Environment
Platform: iOS
SDK version: 5.14.3
StoreKit version:
StoreKit 1 (default on versions <5.0.0. Can be enabled in versions >=5.0.0 with .with(storeKitVersion: .storeKit1))
StoreKit 2 (default on versions >=5.0.0)
OS version: iOS 18.1.1
Xcode version: 16.1
Device and/or simulator:
Device
Simulator
Environment:
Sandbox
TestFlight
Production
How widespread is the issue. Percentage of devices affected.
Debug logs that reproduce the issue. Complete logs with Purchases.logLevel = .verbose will help us debug this issue.
I can't access logs as it's not available, when iOS does prewarming while the device is locked after the reboot.
Steps to reproduce, with a description of expected vs. actual behavior
Create a sample app with a live activity for the lock screen / dynamic island and add RevenueCat SDK
Configure Purchases in AppDelegate init or didFinishLaunchingWithOptions
Run app and schedule live activity, lock device and allow live activities on the lock screen
Reboot device
Wait up to 60 sec while locked after reboot
Unlock device
Open sample app
Expected: RevenueCat and UserDefaults works normally
Actual: All UserDefaults.standard accesses return wrong values resulting in all kinds of other potential issues, RevenueCat cache is returning wrong values
I made a sample here that still needs adjustment to use and configure RevenueCat.
@KaiOelfkeThis blog post goes into detail about the same issue, that UserDefaults became unreliable. Especially in the context of Live Activities. There's also a proposed solution to this dilemma in a follow-up blog post - a replacement for the UserDefaults.
This obviously doesn't help, if dependencies are relying on UserDefaults. RC advices in their documentation to move the initialisation of the SDK from didFinishLaunchingWithOptions to the viewDidLoad of the first ViewController.
In certain cases on iOS 15 devices, iOS may prewarm your app - this essentially means your app will be launched silently in the background to improve app launch times for your users.
If you are not using RevenueCat's anonymous IDs as described above, and are instead providing your own app user ID on configuration, do not call configure in application:didFinishLaunchingWithOptions:. Instead, call the configure method in your root view controller's initialization method.
I still wonder if RC is aware of how unreliable UserDefaults are at times. It seems that UserDefaults are unavailable at different times than just during the prewarm period.
There is also this discussion in the Apple's developer forum, where one of Apple's engineers is clarifying a few things about prewarming.
It would be really nice to have a follow-up on this topic, since we can't follow RC's internal tickets.
Thank you. I know the blog post. I can't use this library for some internal reasons and have my own workarounds in place. Using such a library isn't enough anyway. It's necessary to delay the setup of the RevenueCat SDK until this bug is addressed, if an app must support prewarming (e.g. has live activities). Depending on the iOS version UserDefaults will not work until the the next app launch or until the file system becomes available. With this library you can protect your app data, but it's still a very broken experience, if a given user suddenly lost all his entitlements etc. This is exactly what happened to my users until I added the logic to delay RC SDK setup during prewarming until the device is unlocked.
Describe the bug
For certain versions of iOS under certain conditions iOS can prewarm apps. RevenueCat writes about this in the documentation. There's also some community discussion.
The documentation only writes about issues when not using anonymous identifiers. But the problem scope is bigger. When an app is launched for prewarming, access to the file system is not possible, which includes UserDefaults (which are used by RevenueCat during the configuration).
This resulted in end users reporting losing access (they lost entitlements and got a new anonymous ID) after a reboot until they restored purchases. I fixed with a workaround of detecting the prewarming state and in this case configuring RevenueCat later. But as prewarming will only get more common with the popularity of live activities and the dynamic island a mission critical SDK like RevenueCat should mitigate this internally. Most developers don't know about prewarming and the behavior of
completeFileProtectionUntilFirstUserAuthentication
, which is the default for most files. So this results in very difficult bugs and frustrated end users..with(storeKitVersion: .storeKit1)
)Purchases.logLevel = .verbose
will help us debug this issue.I can't access logs as it's not available, when iOS does prewarming while the device is locked after the reboot.
Expected: RevenueCat and UserDefaults works normally
Actual: All UserDefaults.standard accesses return wrong values resulting in all kinds of other potential issues, RevenueCat cache is returning wrong values
I made a sample here that still needs adjustment to use and configure RevenueCat.
https://github.com/pointfreeco/swift-composable-architecture/discussions/3440
Other information (e.g. stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, etc.)
Additional context
Add any other context about the problem here.
The text was updated successfully, but these errors were encountered: