iOS Accengage Migration

Migration from Accengage SDK to Airship SDK.

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:

    # 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, deeplinks 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 Allowlist 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
Airship.push.userPushNotificationsEnabled = true
Airship.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
Airship.push.customCategories = [category]

// Update registration
Airship.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(_ deepLink: 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 Config instance at runtime, before takeoff, by setting Config#enabledFeatures to none.

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>enabledFeatures</key>
   <array/>
    <string>none</string>
  </array>
  ...
</dict>
</plist>

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

Accengage.setDataOptInEnabled(true)
[Accengage setDataOptInEnabled:YES];
Airship.shared.privacyManager.enableFeatures(.all)
[UAirship.shared.privacyManager enableFeatures:UAFeaturesAll];

For more information, see the Data Collection guide.

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
Airship.channel.editAttributes { editor in
    editor.set(string: "myString", attribute: "string")
    editor.set(number: 100, attribute: "number")
    editor.set(date: Date(), attribute: "date")
}
[UAirship.channel editAttributes:^(UAAttributesEditor * editor) {
    [editor setString:@"myString" attribute:@"string"];
    [editor setNumber:@"100" attribute:@"number"];
    [editor setDate:[NSDate date] attribute:@"date"];
}];

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
Airship.analytics.trackScreen("controller_id")
// Record the event
[UAirship.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 = CustomEvent(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.

Remove Airship-Accengage module

After your users have migrated to Airship, you are now ready to remove the Airship-Accengage module. Depending on how you previously added it, you will have to remove it from your Podfile or your project.

After removing the module, verify if you are using the Accengage updateDeviceInformation() method anywhere in your code and replace any instances with the Airship editAttributes() methods by following the Update Device Information section of this documentation.

 Note

Upgrading to Airship SDK 17+ requires removing the Airship-Accengage module.