Issue with UserDefaults Data Loss after App Transfer and TestFlight Installation

Hello, I recently encountered an issue following the transfer of my app between Apple Developer accounts and would appreciate any insights or solutions.

Here's a summary of the situation:

App Transfer: I transferred an app from one Apple Developer account to another. The app's bundle ID remained unchanged during this process.

App Update: After the transfer, I integrated a new feature into the app and pushed the updated version to TestFlight under the new account.

Installation Issue: When I installed the TestFlight version of the app from the new account on my device, which already had the app installed from the old account, the app logged out the user. It appears that the UserDefaults data was not retained, resulting in the loss of stored user data.

My hypothesis is that the transfer between accounts caused the user defaults to reset, leading to the data loss. Has anyone else experienced this issue, and if so, are there any recommended solutions or best practices to prevent UserDefaults from resetting during such transfers?

Thank you in advance for your assistance.

Answered by DTS Engineer in 794074022

User defaults are stored in your app’s container and that’s preserved across an app transfer. The most likely cause of this problem is the keychain. I talk about that topic in detail in App ID Prefix Change and Keychain Access.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

User defaults are stored in your app’s container and that’s preserved across an app transfer. The most likely cause of this problem is the keychain. I talk about that topic in detail in App ID Prefix Change and Keychain Access.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Since there is no access to old keychain items across app transfers, does that mean there is no way to access the old data stored on UserDefaults too? @DTS Engineer

does that mean there is no way to access the old data stored on UserDefaults too?

[Hmmm… negative questions… tricky]

In general, values that you store in user defaults should still be present across an app transfer. That’s because the underlying data is stored in your app’s container, and everything in your app’s container is preserved.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hello, Thank you for your response. After investigating further, I can confirm that my app does not use the keychain, so that does not appear to be the source of the issue. However, I'm still experiencing the problem where UserDefaults data is not being retained after the app transfer and update.

To provide more context:

  1. The app's bundle ID remained unchanged during the transfer.
  2. No significant changes were made to the app's configuration or entitlements that could affect user defaults.

Given that the app does not use a keychain, are there any other potential causes or overlooked factors that might lead to UserDefaults data not being retained across the app transfer? @DTS Engineer

@DTS Engineer Due to the critical nature of our situation and the delay in resolving this issue, we kindly request your assistance in escalating our case or providing additional guidance to expedite its resolution.

Your prompt attention to this matter would be greatly appreciated.

are there any other potential causes or overlooked factors that might lead to UserDefaults data not being retained across the app transfer?

I’m aware of two other edge cases:

  • Data protection — This is a very unlikely edge case, so I’ve relegated it to a footnote [1].

  • App groups — So far I’ve assumed that you’re talking about standard user defaults, that is, the default you access via the standard class property. However, if you’re getting defaults from an app group, using the init(suiteName:) initialiser, then that’s definitely going to be affected by an app transfer (because you can’t transfer app groups).

So, is your app using standard user defaults? Or user defaults tied to an app group?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] As discussed in this thread. In short, using the com.apple.developer.default-data-protection entitlement entitlement to change the default data protection on your app’s container can cause problems for user defaults. This isn’t related to app transfer, so it’s unlikely to be a factor here. However, it could be, because on doing an app transfer you have to redo your code signing and it’s possible that you might’ve enabled data protection by accident while doing that.

Yes. Our app uses standard user defaults. So, does this issue happen on the App Store to App Store App Upgrade? @DTS Engineer

First up, I’d like to confirm one thing: I’ve been assuming that your app runs on iOS, or one of its child platforms. That is, not on macOS. Is that correct?

Our app uses standard user defaults.

Thanks for confirming.

So, does this issue happen on the App Store to App Store App Upgrade?

Which issue? I’m not actually aware of an issue that accounts for the behaviour you’re reporting.

However, in general, the behaviour you see in TestFlight is likely to be a good match for the behaviour you see in an App Store upgrade.

Do you create any regular files in your app’s container? If so, do those get preserved across this update?


My usual process for debugging problems like this is to create an isolated test case. For example:

  1. Create a small test app with the same bundle ID as your real app.

  2. Have it write out a simple test file and a simple test user default.

  3. Update it to the new version.

  4. Run it and check whether the test file and test user default are still valid.

However, that’s tricky to do in this case because:

  • App transfer makes it hard to create test versions of your old app.

  • TestFlight means that you can’t ship a test app in the guise of your real app.

Getting around the second challenge isn’t too hard. Instead of using a small test app, you add a small ‘hidden’ [1] piece of functionality to your main app. So, add a debug feature that displays a UI that lets you read and write your test file and test user default. Easy peasy.

Getting around the first challenge is trickier. How can you add this test functionality to your old app? I don’t see an easy way of doing that. One possibility is to transfer your app back to your old team, ship this debugging update from there, and then transfer it again to your new team. That’ll work, but it’s not exactly easy.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] To be clear, I mean hidden from your users. If your app goes through App Review, add a review note to ensure that App Review knows about this functionality.

That's correct! Our app runs on iOS.

We are unable to implement the feature you described, as it involves simulating updates or altering app behaviour for end users outside of official releases, which is not feasible or allowed.

We need confirmation regarding the issue observed when upgrading from TestFlight to the App Store version of our app. Specifically, we need to ascertain whether this issue occurs solely during upgrades from TestFlight to App Store releases, or if it also affects updates from one App Store version to another.

If this issue is specific to TestFlight to App Store upgrades, please confirm. If it affects updates between two App Store versions as well, kindly inform us so we can effectively communicate this to our user base.

Additionally, please provide any relevant documentation or guidelines that we can share with our customers to ensure clarity on the behaviour of app updates from the App Store. @DTS Engineer

You keep writing “this issue”, which suggests that you think that this is a well-known limitation or bug. That’s not the case. I’m not aware of any systematic problems that would cause an app to lose all user defaults after an app transfer.

Now, it’s possible that there is such a problem and I’ve just missed the memo. However, that seems unlikely given that I’ve not seen other reports like this here on DevForums, or as part of a DTS case.

My best guess is that this is a bug in your code, and I’ve suggested ways that you might investigate that possibility.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

We need to just confirm that after the app transfer while upgrading the app store to app store app update. The user defaults persist or not.@DTS Engineer

I understand what you “need”, I just can’t give it to you. All I can do is relay my experience:

  • I’m not aware of any systematic problem that causes user defaults to get lost during an app transfer.

  • In general, TestFlight does an excellent job of replicating the App Store experience.

So if you’re seeing user defaults being lost in your TestFlight build, that warrants further investigation.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Issue with UserDefaults Data Loss after App Transfer and TestFlight Installation
 
 
Q