Technical Note TN2285

Testing iOS App Updates

This technote discusses how to test an update to an iOS app that has already been deployed through the App Store. General testing methodology is beyond the scope of this document. For information on optimizing update delivery, see "Reducing Download Size for iOS App Updates" and "Reducing the Size of my App".

Recommended Testing Procedure
To create an Archived build that you can both test and submit:
Managing Data Across Updates
Debugging Ad Hoc Builds
Next Steps
Document Revision History

Recommended Testing Procedure

Install an ad hoc distribution of an archived build of the update using iTunes on a device that already has the old version of the app installed.

Xcode's app install process is optimized for development, but is slightly different than how iTunes and the App Store install apps. This is good during development because it's faster, but using Xcode to install an app over an older old build may create a "frankenbuild" with legacy files inside the .app bundle that won't exist after an App Store update.

When an app is updated, the old .app bundle is completely replaced, and all data in the old app container may be preserved as well.

Additionally, running with Xcode's debugger attached will mask "watchdog crashes" that can happen if an upgrade takes too long to launch.

To create an Archived build that you can both test and submit:

1) In Xcode choose "Archive" from the "Product" menu to archive a build of your app. You can find the archive in the Archives tab in the Organizer window.

2) Package the build as an "Ad Hoc" .ipa file by selecting it in the Organizer window and pressing "Distribute…"; then select "Save for Enterprise or Ad-Hoc Deployment". Choose any "Code Signing Identity:" that will let you install on your test device.

3) Test updating to that build by opening the .ipa file with iTunes and syncing to install it on a device that has the previous version of your app installed. Be sure you've used the previous version of the app enough that it's saved any data it might save during use. The most common problem updates have is not properly dealing with data created by the previous version of the app.

Managing Data Across Updates

The most common cause of bugs after an update is the new version of the app not handling data created by a previous version of the app.

When an app is updated, the very latest version available in the App Store for the target device is installed. Intermediate updates are not run. Your app needs to handle data created by any previous versions of the app.

When an app is updated, the .app bundle is completely replaced by the latest version of the app. Also, the absolute path to the app's container ("Application_Home") and thus all files inside it, will change. For this reason, you must only save paths to files relative to your application container.

NSSearchPathForDirectoriesInDomains() or -[NSFileManager URLsForDirectory:inDomains:] will always give you a valid path to the current <Application_Home> or a standard subdirectory inside it.

Listing 1  A method that returns a URL to the current Application_Home/Documents directory

- (NSURL *)applicationDocumentsDirectory {
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

Any data inside the app container may be preserved when the app is updated. From a practical standpoints, this means your app needs to gracefully handle (or ignore) old caches and temporary files.

<Application_Home>/Documents/ and <Application_Home>/Library (excluding the <Application_Home>/Library/Caches subdirectory) are the only directories that are guaranteed to be preserved across updates. Although other <Application_Home> subdirectories may be moved over, you should not rely on this as an API contract.

New Hardware

When a user migrates to a new device for the first time, backed up data from their older device is installed on the new device, along with the latest version of any apps that were installed on the old device. This scenario is the same as a regular update, except for two considerations. Temporary data will absolutely not be installed, because it was never backed up. Also, any files that were marked as "do not backup" will not be installed.

Debugging Ad Hoc Builds

If a problem only reproduces in an Ad Hoc build, you'll need to analyze Crash Logs and Console output from the device to debug it. Debugging Deployed iOS Apps explains how to gather this information. See Understanding and Analyzing iOS Application Crash Reports and the Understanding Crash Reports on iOS WWDC Session for tips.

Next Steps

After testing an archived build to your satisfaction, you can submit it to the App Store, by following these steps. It is important to submit the exact same build you have tested.

For information on making sure your app and update are small enough to be downloaded without a Wi-Fi connection, see "Reducing the Size of my App" and "Reducing Download Size for iOS App Updates".



Document Revision History


DateNotes
2014-10-07

Added more details on the update process and what files are preserved.

2014-05-14

Removed list of overly-specific possible issues.

2013-02-13

Editorial changes.

2011-10-27

New document that discusses some best practices for testing an update to an iOS app that has already been deployed through the App Store.