Accengage Migration

Migration from Accengage SDK to Airship SDK.

This guide will help you migrate from the Accengage platform to the Airship platform by installing the Airship-Accengage module. This module allows you to continue sending messages to your entire audience (upgraded, non-upgraded, net new users) through the Accengage platform while upgrading users to the Airship platform. After all or most of your users have updated to the latest version of your app, you can use the Airship platform exclusively for your messaging and remove the Airship-Accengage module.

For more information about the migration, please visit our documentation about Accengage Upgrade.

Setup Instructions

  1. Remove the Accengage SDK by deleting your AccengageConfig.plist file and the following lines from the Podfile:

        # Accengage specs source repo
        source 'https://github.com/Accengage/ios-pod-specs.git'
        target 'YOUR_APP_TARGET' do
          pod 'Accengage-iOS-SDK', '~> 7.0'
        end
        
  2. Install the Airship SDK. The Airship SDK can be installed using CocoaPods, Carthage, or manually.
    The fastest and easiest way is using CocoaPods:

        use_frameworks!
    
        # Airship SDK
        target "<Your Target Name>" do
          pod 'Airship'
          pod 'Airship/Accengage'
        end
        

    Note: Make sure that the Accengage subspec is included in the podfile.

  3. (Optional) In order to take advantage of notification attachments, create a notification service extension.

  4. Start the Airship SDK.

  5. You can keep the Accengage UpdateDeviceInformation method calls, as they will still work except for the Increment/Decrement methods. Note: Increment and Decrement methods are not supported in the Airship SDK.
    Accengage method calls can also be replaced with Airship method calls, if needed. See the documentation on attributes for more details.

  6. Remove the remaining Accengage features and replace them with the corresponding Airship features. For more details, check the sections below.

Allow URLs

In Airship, all URLs are not verified by default. Applications that use open URL action, landing pages, and custom in-app message image URLs will need to provide a list of URL patterns that match those URLs for SCOPE_OPEN_URL. It is possible to allow all URLs by adding the wildcard symbol * to the array under the URLAllowListScopeOpenURL key in your AirshipConfig.plist. See the URL Allow List documentation for more information.

Push Notifications

Enabling Push Notifications

For reference, in the Accengage SDK, you had to register for notifications with the following call:

Enable notifications in Accengage
Accengage.push()?.registerForUserNotifications(options: [.notificationOptionSound, .notificationOptionAlert, .notificationOptionBadge, .notificationOptionCarPlay])
[[Accengage push] registerForUserNotificationsWithOptions:options];

During the migration, the Opt-in status of your users are automatically transferred to Airship. But if needed, you can still ask for Push notification consent, and then call the following method to enable or disable notifications:

Enable notifications in Airship
UAirship.push().userPushNotificationsEnabled = true
UAirship.push().defaultPresentationOptions = [.alert, .badge, .sound]
[UAirship push].userPushNotificationsEnabled = YES;
[UAirship push].defaultPresentationOptions = (UNNotificationPresentationOptionAlert |
                                              UNNotificationPresentationOptionBadge |
                                              UNNotificationPresentationOptionSound);

Custom interactive notifications (Categories)

If you want to define a custom Interactive Notification type, you must register a new category.

 Note

Airship reserves category IDs prefixed with “ua_”. Any custom categories with that prefix will be dropped.

Categories can be set after takeOff. Any modifications to the user notification categories will require an update to the registration settings by calling UAPush updateRegistration .

For reference, here are the calls in Accengage SDK to register custom categories:

Setting Custom Categories in Accengage
var customCategories: Set<UNNotificationCategory> = []

let acceptAction = UNNotificationAction(identifier: "ACCEPT_ACTION", title: "Accept", options: UNNotificationActionOptions(rawValue: 0))

let declineAction = UNNotificationAction(identifier: "DECLINE_ACTION", title: "Decline", options: UNNotificationActionOptions(rawValue: 0))

let meetingInviteCategory = UNNotificationCategory(identifier: "MEETING_INVITATION", actions: [acceptAction, declineAction], intentIdentifiers: [], options: .customDismissAction)

customCategories.insert(meetingInviteCategory)

Accengage.push()?.customCategories = customCategories
NSMutableSet *customCategories = [NSMutableSet set];

UNNotificationAction *acceptAction = [UNNotificationAction actionWithIdentifier: @"ACCEPT_ACTION" title: @"Accept" options: UNNotificationActionOptionNone];

UNNotificationAction *declineAction = [UNNotificationAction actionWithIdentifier: @"DECLINE_ACTION" title: @"Decline" options: UNNotificationActionOptionNone];

UNNotificationCategory *meetingInviteCategory = [UNNotificationCategory categoryWithIdentifier:@"MEETING_INVITATION" actions:@[acceptAction, declineAction] intentIdentifiers: @[] options:UNNotificationCategoryOptionCustomDismissAction];

[customCategories addObject:meetingInviteCategory];

[[Accengage push] setCustomCategories:customCategories];

You can then replace them with these calls:

Setting Custom Categories in Airship
// Define an action for the category
let categoryAction = UANotificationAction(identifier: "category_action",
                                               title: "Action!",
                                             options: [.authenticationRequired, .foreground, .destructive])

// Define the category
let category = UANotificationCategory(identifier: "custom_category",
                                         actions: [categoryAction],
                               intentIdentifiers: [],
                   hiddenPreviewsBodyPlaceholder: "Sensitive Content Hidden",
                                         options: [])

// Set the custom categories
UAirship.push().customCategories = [category]

// Update registration
UAirship.push().updateRegistration()
// Define an action for the category
UANotificationAction *categoryAction = [UANotificationAction actionWithIdentifier: @"category_action"
                                                                            title:@"Action!"
                                                                          options:(UNNotificationActionOptionForeground |
                                                                                  UNNotificationActionOptionDestructive |
                                                                                  UNNotificationActionOptionAuthenticationRequired)];

// Define the category
UANotificationCategory *category = [UANotificationCategory categoryWithIdentifier:@"custom_category"
                                                                          actions:@[categoryAction]
                                                                intentIdentifiers:@[]
                                                                          options:UNNotificationCategoryOptionNone];

// Set the custom categories
[UAirship push].customCategories = [NSSet setWithArray:@[category]];

// Update registration
[[UAirship push] updateRegistration];

Silent Push Notifications

To enable silent push notifications in Airship, you’ll need to use Xcode to enable push notifications in the target’s Capabilities pane:

Enable background notifications by including the UIBackgroundModes key with the remote-notification value in your app’s Info.plist file. When viewing the plist in Xcode, UIBackgroundModes is displayed as Required background modes and remote-notification is displayed as App downloads content in response to push notifications.

Make sure you enable Background Modes and Remote notifications under the target’s Capabilities section:

Deep Linking

The Accengage deep link delegate should look like this:

func receivedDeepLink(_ url: URL, completionHandler: @escaping (_ success: Bool) -> Void) {
    let pathComponents = url.pathComponents

    if pathComponents.contains(ViewStoryboardID) {
        // Navigate to desired view
        completionHandler(true)
        return
    }
    completionHandler(false)
}
- (void)receivedDeepLink:(nonnull NSURL *)url completionHandler:(void (^ _Nonnull)(BOOL success))completionHandler {
    NSArray *pathComponents = url.pathComponents;

    if ([pathComponents containsObject:ViewStoryboardID]) {
        // Navigate to desired view
        completionHandler(true);
        return;
    }
   completionHandler(false); 
}

And you can replace it with this delegate:

- (void)receivedDeepLink:(NSURL *_Nonnull)url completionHandler:(void (^_Nonnull)(void))completionHandler {
    NSArray *pathComponents = url.pathComponents;

    if ([pathComponents containsObject:ViewStoryboardID]) {
        // Navigate to desired view
    }

    // Call completion handler
    completionHandler();
}
func receivedDeepLink(_ url: URL, completionHandler: @escaping () -> ()) {
    let pathComponents = url.pathComponents

    if pathComponents.contains(ViewStoryboardID) {
      // Navigate to desired view
    }

    // Call completion handler
    completionHandler()
}

Data Collection (GDPR compliancy)

Data collection can be disabled at the SDK level to prevent the collection of any non-essential, personally identifiable data.

When you start the Accengage SDK, you pass the “ACCOptInEnabled” value which specifies whether data collection is enabled. There is a similar setting in Airship, but should be defined on the UAConfig instance at runtime, before takeoff, by setting UAConfig#dataCollectionOptInEnabled or by adding the dataCollectionOptInEnabled to your AirshipConfig.plist file and setting it to YES:

Example AirshipConfig.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  ...
  <key>dataCollectionOptInEnabled</key>
  <boolean>YES</boolean>
  ...
</dict>
</plist>

If this property is enabled, you can then use the Data Collection methods to enable (or disable) data collection when your user agrees to it. For reference, these were the calls used in the Accengage SDK:

  Accengage.setDataOptInEnabled(true)
  [Accengage setDataOptInEnabled:YES];
  UAirship.shared()?.isDataCollectionEnabled = true
  [UAirship shared].dataCollectionEnabled = YES;

Note that in Accengage SDK, disabling DataOptIn fully disable the SDK. In Airship, the SDK is still enabled, but with limited features.

Disabling data collection disables the following Airship features:

  • Push tokens
  • Channels
  • Analytics events
  • Location
  • Attributes
  • Associated Identifiers
  • Tags
  • Named user

Remaining functionality (when data collection is disabled) includes broadcast Message Center messages and broadcast In-App Automation messages.

Data collected in the SDK

 Note

The data collected in the SDK is not used to track users across apps.

Data collection enabled

The following data is sent to Airship when data collection is enabled.

Data collected by SDK
  • Platform
  • Package name
  • Registered Notification Types
  • Time in app
  • SDK Version
  • App Version
  • Device model
  • Device manufacturer
  • Push provider
  • OS version
  • Carrier
  • Locale
  • Timezone
  • Airship Channel ID
  • Connection type
  • Device Token/Push Registration Token
  • Airship Framework usage (Cordova, Titanium, ReactNative, Xamarin, Flutter, Unity plugins)
  • Message Center User ID (generated when including the Message Center module)
  • Notification open events
  • Send events
  • In-App Message events
  • Message Center Reads
  • Message Center Deletes
  • Location updates
Data set by App
  • Screen tracking
  • Associated Identifiers
  • Attributes
  • Tags
  • Named User ID
  • Custom events
  • Quiet Time
  • Push opt-in and notification opt-in status

Data collection disabled

The following data is sent to Airship when data collection is disabled.

Data collected by SDK
  • Platform
  • Package name
  • Device model
  • Device manufacturer
  • Push provider
  • SDK version
  • Locale
  • Timezone
  • Airship Channel ID
  • Message Center User ID (generated when including the Message Center module)
  • Device Token/Push Registration Token (only when explicitly enabled by app)
  • Send events
  • Message Center Reads
  • Message Center Deletes
Data set by App
  • Quiet Time
  • Push opt-in and notification opt-in status

For more details about the data collected, check the Data Collection docs

Attributes

Attributes can be set on ChannelsAn instance representing an entity addressable via the Airship service, e.g., an iOS device, email address, SMS number or web browser. The channel instance or channel object contains all relevant information about a channel, including metadata used for targeting, opt-in status, device-specific information, and, importantly, a unique identifier for the channel, the channel ID. and Named UsersA customer-provided identifier used for mapping multiple devices and channels to a specific individual. . See the attributes documentation for more information.

Update Device Information

Formerly called Update Device Information in the Accengage SDK, this feature is called Attributes in the Airship SDK.

If you have this feature implemented in your application, you can keep the Accengage updateDeviceInformation calls. The Airship SDK will transform them into Airship Attributes feature calls.

But if you want to use the Airship Attributes feature directly, you’ll need to replace this code:

Accengage SDK
var deviceInfoSet = ACCDeviceInformationSet.init()
deviceInfoSet.setString("myString", forKey: "string")
deviceInfoSet.setNumber(100, forKey: "number")
deviceInfoSet.setDate(NSDate() as Date, forKey: "date")
Accengage.profile().updateDeviceInformation(deviceInfoSet, withCompletionHandler: { error in
    if error != nil {
        // handle the error
    }
})
ACCDeviceInformationSet *deviceInfoSet = [[ACCDeviceInformationSet alloc] init];
[deviceInfoSet setString:@"myString" forKey:@"string"];
[deviceInfoSet setNumber:@100 forKey:@"number"];
[deviceInfoSet setDate:[NSDate date] forKey:@"date"];
[[Accengage profile] updateDeviceInformation:deviceInfoSet withCompletionHandler:^(NSError * _Nullable error) {
    if (error) {
       // handle the error
    }
 }];

with this one:

Airship SDK
// Create the attribute mutations
let mutations = UAAttributeMutations()
mutations.setString("myString", forAttribute: "string")
mutations.setNumber("100", forAttribute: "number")
mutations.setDate(NSDate() as Date, forAttribute: "date")

// Apply the attribute changes to the channel
UAirship.channel().apply(mutations)
// Create the attribute mutations
UAAttributeMutations *mutations = [UAAttributeMutations mutations];
[mutations setString:@"myString" forAttribute:@"string"];
[mutations setNumber:@"100" forAttribute:@"number"];
[mutations setDate:[NSDate date] forAttribute:@"date"];

// Apply the attribute changes to the channel
[[UAirship channel] applyAttributeMutations:mutations];

Events

Views

Formerly called View tracking on Accengage, this feature is called Screen tracking in the Airship SDK.

If you have this feature implemented in your application, you may have added it in your viewDidLoad method:

Accengage SDK
func viewDidLoad() {
    super.viewDidLoad()
    accengageAlias = "controller_id"
}
- (void)viewDidLoad {
    [super viewDidLoad];
    self.accengageAlias = @"controller_id";
}

Or you may be using the manual screen tracking in your viewDidAppear and viewDidDisappear methods:

Accengage SDK
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    Accengage.trackScreenDisplay("controller_id")
}

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    Accengage.trackScreenDismiss("controller_id")
}
- (void)viewDidAppear:(BOOL)animated {

    [super viewDidAppear:animated];
    [Accengage trackScreenDisplay:@"controller_id"];
}

- (void)viewDidDisappear:(BOOL)animated {

    [super viewDidDisappear:animated];
    [Accengage trackScreenDismiss:@"controller_id"];
}

In both cases, you’ll have to replace the former code with the next one in your viewDidAppear method:

Airship SDK
UAirship.shared().analytics.trackScreen("controller_id")
// Record the event
[[UAirship shared].analytics trackScreen:@"controller_id"];

Custom Events

If you have some Accengage Custom Events implemented in your application, you’ll need to use Airship’s Custom Events instead. For that, you just have to replace this code:

Accengage SDK
var customEventParams = ACCCustomEventParams()
customEventParams.set("myString", forKey: "myKey")
customEventParams.setNumber(4, forKey: "mySecondKey")
customEventParams.setBoolean(true, forKey: "myThirdKey")
customEventParams.setDate(Date(), forKey: "myFourthKey")

Accengage.trackEvent(1001, withCustomParameters: customEventParams)
ACCCustomEventParams *customEventParams = [[ACCCustomEventParams alloc] init];
[customEventParams setString:@"myString" forKey:@"myKey"];
[customEventParams setNumber:[NSNumber numberWithInteger:4] forKey:@"mySecondKey"];
[customEventParams setBoolean:YES forKey:@"myThirdKey"];
[customEventParams setDate:[NSDate date] forKey:@"myFourthKey"];

[Accengage trackEvent:1001 withCustomParameters:customEventParams];

with this code:

Airship SDK
let event = UACustomEvent(name: "your_event_name")

// Set custom event properties
var propertyDictionary = Dictionary <String, Any>()
propertyDictionary["myKey"] = "myString"
propertyDictionary["mySecondKey"] = 4
propertyDictionary["myThirdKey"] = true
propertyDictionary["myFourthKey"] = Date()
event.properties = propertyDictionary

// Record the event in analytics
event.track()
UACustomEvent *event = [UACustomEvent eventWithName:@"your_event_name"];

// Set custom event properties
NSMutableDictionary<NSString *, id> *propertyDictionary = [NSMutableDictionary dictionary];
[propertyDictionary setValue:@"myString" forKey:@"myKey"];
[propertyDictionary setValue:@4 forKey:@"mySecondKey"];
[propertyDictionary setValue:@YES forKey:@"myThirdKey"];
[propertyDictionary setValue:[NSDate date] forKey:@"myFourthKey"];
event.properties = propertyDictionary;

// Record the event in analytics
[event track]

Note that we don’t set an event ID in the Airship SDK. You’ll have to use an event name instead.

Accengage Predefined Events

If you are using Lead, Cart or Purchase Events, you’ll have to use Airship’s Custom Events to track the data you need to.