License Migration (Mac)

Ensure a smooth transition across your app releases and OS updates

Catalina Update

Apple’s Catalina (OSX 10.15) update changes the way the archivedDataWithRootObject method on NSData works, which impacts the way Paddle license activations are stored on a user’s system.

To enable users to smoothly update their OS to Catalina:

  • Your app should integrate Paddle’s SDK version 4.0.13 or higher
  • You should call the verifyActivationWithCompletion method the first time the app is launched after the OS update, before the activated state is checked

If the above two steps are not implemented, the first time the app attempts to verify an active license, the activated parameter will return NO and the user may be shown the product access dialog.

Entering their existing license at this point will re-license the product, without using up additional activations - however we would recommend handling the migration programatically to provide a smooth user experience.


Migrating Paddle v3 Licenses to v4

Paddle’s v4 Mac SDK release has refined some concepts and abstraction to make it more clear and flexible than the legacy v3 SDK.

As v3 had a significantly different license format, it is necessary to convert between the two formats, from the older format to the newer format. In the v4 macOS SDK, this conversion can be triggered by calling migrateV3License on the product.

// Populate a local object in case we're unable to retrieve data
// from the Vendor Dashboard
PADProductConfiguration *defaultProductConfig = [[PADProductConfiguration alloc] init];
defaultProductConfig.productName = @"My v4 Product";
defaultProductConfig.vendorName = @"My Company";

PADProduct *product = [[PADProduct alloc] initWithProductID:@"12345"
                                                productType:PADProductTypeSDKProduct 
                                              configuration:defaultProductConfig];

// Ask user if they have a v3 license from your previous app.
// ...

// Migrate v3 license to new format
[product migrateV3License];

After calling migrateV3License, the product will be considered activated and you’ll have access to the usual activation details of the product. If no v3 license was found, no changes are made to the product. The same goes for a product that was already activated before the migration: no changes are made to products activated in your current app.

In the macOS SDK versions 4.0.0-4.0.4, the v3 license migration was entirely automated. Adding a method to manually trigger migration was added in v4.0.5 to give you more control over the process.

App Group Migration

The macOS SDK supports migrating license activations between versions of your app using data shared between apps in your app group. This feature is useful when your bundle identifier changes between major releases, or you are migrating users to a new incarnation of your app.

The migration process requires 2 steps:

  1. Writing the license activation data to the data container of an app group. The write step is performed automatically by the macOS SDK if you provide an app group to the Paddle delegate. At least the last version of your app should provide the app group to start writing the license activation information.

  2. Reading the license activation data from the data container of an app group. Products can read the license activation data from app groups on demand. The app group is provided directly to the read method.

The license activation information can then be activated using the regular routes to verify the license information.

Reading and writing the license activation data are independent of each other, in that you do not need to implement both in your app. You could enable writing of the license activation data in the last 2 versions of your app, for instance, and enable reading in the first version of your new app.

If you do enable both reading and writing in the same app, remember that activated products in your new app will also write to the data container of your app group. After activation you would be able to immediately read the license activation data from the data container. You should skip the read phase if the product is already activated to prevent repeatedly activating the same license.

Note that activations are linked to a single product. When searching for previous activations in the app group, use the product of your previous app’s release. For instance, if you are writing the activation with product X, you won’t be able to read the activation with product Y because the activation is linked to product X.

Implementation

Write Activation Data

In your app using v3 or v4 of the macOS SDK, enable writing of the license activation data by implementing the appGroupForSharedLicense method of the PaddleDelegate.

(NSString *)appGroupForSharedLicense
{
    return @"appgroup.identifier";
}

If your app uses v3 of the macOS SDK, call [paddle productActivated] to ensure that the license activation data, if any, is written to the data container of your app group. If your app uses v4 of the macOS SDK, the license activation data will be written when you initialise the product.

// app using v3 macOS SDK
[paddle productActivated];

// app using v4 macOS SDK
[PADProduct alloc] initWithProductID:@"my-product-id"
                         productType:PADProductTypeSDKProduct
                       configuration:nil];

Read Activation Data

In your app using v4 of the macOS SDK, read in the license activation data written by your app using the v3 or v4 macOS SDK. Use the same product ID and app group as your previous app version.

[PADProduct alloc] initWithProductID:@"my-product-id"
                         productType:PADProductTypeSDKProduct
                       configuration:nil];

PADProductAppGroupLicense *license = [product existingLicenseFromAppGroup:@"appgroup.identifier"];
if (license) {
	// Activate product using license, or suggest activation to the user, etc.
} else {
  // No previous license found.
}