Bringing Existing Users Along for the Ride

Its become common for iOS developers to release a completely new app when releasing a major new version of a product. One reason for this is the lack of paid upgrades in the App Store. Another is to support older OS versions while allowing the latest version to advance beyond them.

Whatever the reasons may be, its a good idea to make it as easy as possible for them to use the new app. Many existing users will be active users of the product, and will want to move to the new version. You want to treat them with as much respect as possible and make it easy for them to move to the new version of your app should they choose to upgrade.

When I was finishing up Runtime I was trying to decide how to migrate existing users off of my older app, Workout Logbook. The apps share the same database system, so their data is compatible. I knew there would be other people like me who had several years worth of runs stored on the app, so I wanted to create a way to bring those users along for the ride with Runtime.

It turns out that iOS actually has a great way to do just that. My good friend Kevin Harwood suggested using custom URL schemes. That gave me the ability to detect if a user had Workout Logbook installed, and if so, allow them to visit that app and export their data back to Runtime. Here's the screen a new Runtime user will see if they already have Workout Logbook installed.

Import Workout Logbook.png

Tapping Import sends the user out to Workout Logbook. There I can use the following code to detect that the user opened it via a specific URL scheme, and take action to allow them to export their data.

if ([[url absoluteString] isEqualToString:@"runDataExport://"]) {
    [self promptExport];
}

After prompting the user to verify that they want to export their data, its a relatively simple matter to package up their data into a plist file that can be read by Runtime. Sharing that file with Runtime is also pretty straightforward. We make use of the UIDocumentInteractionController to open the plist file in Runtime.

- (void)handleRunDataExport {
    NSString *plistName = [self.runListDataController writeRunsToPlist];
    NSString *rootPath =
        [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                             NSUserDomainMask,
                                             YES) objectAtIndex:0];
    NSString *runPlistPath = [rootPath stringByAppendingPathComponent:plistName];
    NSURL *fileURL = [NSURL fileURLWithPath:runPlistPath];

    UIDocumentInteractionController *controller =
        [UIDocumentInteractionController interactionControllerWithURL:fileURL];
    controller.delegate = self;
    [controller presentOpenInMenuFromRect:self.window.bounds
                                                              inView:self.window.rootViewController.view
                                                              animated:YES];
    self.documentInteractionController = controller;
}

Of course, there has to be a contract between the two apps so that the data is in a format they understand. In this case we are transferring real user data, but this method could also be used to transfer app settings and configurations, preferences, and other meta data to give the user a better experience when making the transition to a new version of a product.

Workout Logbook has been updated to support this functionality, and I hope that existing users will be able to use it to make the transition over to Runtime. I really appreciate the people who purchased Workout Logbook over the last few years, and I want to make it easy for them to move over to Runtime. Workout Logbook will cease to be supported soon, and I'll be removing it from sale  once the majority of users have updated to the latest version that supports this feature. I'm happy that I'm able to do what I can to support them with a new product. I hope that other iOS developers will consider this when releasing new versions of their products. Make it easy for existing users to use your new app.