When a user gets a new iPhone, iCloud can restore app data from a different device, which copies info from UserDefaults and the Keychain.
This presents problems for my app when a user migrates from iPhone A -> iPhone B, because the app stores a device-specific security key that changes irregularly.
- The restored security key may be expired (an old backup).
- The user may continue using both iPhone A and iPhone B, causing their stored security keys get out-of-sync with rotations.
This would be easy to fix if I could detect the iCloud data restore, or an upgrade to a new device. This would allow me to reset the persisted device identifier and clear out the persisted old security key.
But I can find no way to do so, because Apple blocks accessing any unique device identifier so you can't tell if the app has moved to a new device. It also gives no callbacks about when an iCloud restore happened. I could check the hardware device model for changes, but sometimes a user replaces a phone with identical hardware when a phone is damaged or lost.
Is there any way to detect migration of an app to a new device and/or prevent cloning of iCloud backups of my app data from one device to another?
You can detect if an app is installed from iCloud backup by saving a file in the
.applicationSupportDirectory. That directory is not backed up, so if your app crates a file there and doesn't see it, then that means it is (a) the first time your app has run or (b) the app was restored from backup.You can use this as a flag to perform any special cleanup when a restore is detected.
And if you need to discern between a first time install and a restore, just save a second flag to
UserDefaults. If the flag exists inUserDefaultsbut the flag file does not exist in.applicationSupportDirectorythen you know it was an iCloud restore.This technique has passed App Store review once as of this writing.