OCX Responsys iOS SDK

In this topic:

Requirements

Ensure that you are using the following SDK versions:

  • OCX Mobile SDK (Core) >= 1.1.6
  • OCX Responsys SDK >= 6.52.1

Upgrade Guide:
If your app is already using the OCX Responsys Mobile SDK, then download the latest SDK for Responsys and Oracle.json and integrate with the app. For more information. refer to OCX Mobile SDK iOS.

Step 1: Initial Setup

[1.1] For your initial Oracle Push Cloud Service integration, you will want to set up an iOS Development Platform. This will allow you to use a development provisioning profile so you can easily deploy and debug on your device. This is important because push notifications are not available to be tested on the simulator.

From the Mobile App Developer Console, locate your app and click Edit App.

From your app's page, click Platform.

On the Platform page, click the Add Platform button.

On the Add platform dialog, select iOS Development, and then click Ok.

PushIO Web Dashboard - Add Platforms screenshot

The iOS Development dialog is displayed. It assumes that you have a .PEM file ready to upload. If you do not, proceed to step [1.2]. If you do, skip to step [1.3]

[1.2] The next step involves creating an Authentication file. Responsys supports Authentication Key Files and Push SSL Certificates (known as a .PEM file) via Apple’s iOS Provisioning Portal. These Authentication files give us permission to speak to Apple’s servers, which ultimately communicate with your application. If you are using .PEM files, at this stage, you will only need to create a Development Push SSL Certificate because you aren’t ready to ship or distribute your app yet.

This process can be a bit tricky, so we’ve created guides dedicated solely to generating the necessary files:

 

[1.3] Once you have generated the Authentication file, head back to the Mobile App Development Console to upload the file.

[1.3.1] On the iOS Development dialog, enter the app title (unique for your app and platform), and then click the Upload button.

[1.3.2] Browse to the location on your computer where the .PEM file is located, select it, and finish the upload.

[1.3.3] Click the Add button to complete the setup.

When completed, it should look like this:

iOS Development setup screenshot

[1.4] Next, download our iOS OracleCXResponsys and a configuration file called pushio_config_debug.json. Click the Downloads menu of the iOS Development row to download these files.

Downloading the PushIO SDK files

Note: You can check your pushio_config_debug.json file by opening the file in TextEdit. You should see a populated bundleId value that matches your application, as well as an apiKey value that matches what you see listed on your iOS Development Platform page.

Step 2: Download and Add Oracle CX Responsys Frameworks

[2.1] Download the OracleCXResponsys framework and OracleCXMobileSDK framework.

[2.2] Extract the downloaded zip.

[2.3] Drag and drop the OracleCXResponsys and OracleCXMobileSDK frameworks into your project.

[2.4] Select Copy items if needed and specify the options to add the files into your project. Click Finish.

The confirmation dialog when adding files to your project

Step 3: Adding additional required Frameworks

[3.1] Navigate to your project in the Project Navigator, and then navigate to your application target.

[3.2] On the General tab, under Linked Frameworks and Libraries, click the add button ("+" sign) below the list of existing frameworks. From the list of available frameworks and libraries, add the frameworks your app will require. Some examples include WebKit.framework, UserNotifications.framework, libsqlite3.0.tbd. Ensure that the embed type for OracleCXMobileSDK.xcframework and OracleCXResponsys.xcframework is set to "Embed & Sign".

Set embed type to 'Embed & Sign'

Step 4: Enable Push Notifications

On the application settings Capabilities tab, ensure that Push Notifications is enabled.

Ensure that when you enable Push Notifications:

  • Add the Push Notifications feature to your app id.

  • Add the Push Notifications entitlement to your entitlements file

Enable Push Notifications on Capabilities tab screenshot

Note: Add Oracle.json to your project before proceeding to the next step.

Step 5: Implement Code

[5.1] Import the frameworks.

//1. Import Frameworks
#import <OracleCXResponsys/OracleCXResponsys.h>
//For UserNotifications support
#import <UserNotifications/UserNotifications.h>
//Implement UserNotifications delegate to receive the notification callbacks in iOS 10.
@interface AppDelegate()<UNUserNotificationCenterDelegate>
@end						
//1. Import Frameworks
import OracleCXResponsys
//For UserNotifications support
import UserNotifications
//Implement UserNotifications delegate to receive the notification callbacks in iOS 10.
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

}

[5.2] In your AppDelegate.m file, add the following lines mentioned in below steps in the -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method.

//2. Set the UNUserNotificationCenter delegate
[UNUserNotificationCenter currentNotificationCenter].delegate= self;					
//2. Set the UNUserNotificationCenter delegate
UNUserNotificationCenter.current().delegate = self

[5.3] Enable Logging (Optional). In your AppDelegate.m file, enable SDK logging for better debugging:

//3. Enable Logging
#ifdef DEBUG [[PushIOManager sharedInstance] setLoggingEnabled:YES]; [[PushIOManager sharedInstance] setLogLevel:PIOLogLevelInfo]; //PIOLogLevelWarn or PIOLogLevelError #else [[PushIOManager sharedInstance] setLoggingEnabled:NO]; #endif
//3. Enable Logging
#if DEBUG PushIOManager.sharedInstance().setLoggingEnabled(true) PushIOManager.sharedInstance().setLogLevel(PIOLogLevel.info) //PIOLogLevel.warn or PIOLogLevel.error #else PushIOManager.sharedInstance().setLoggingEnabled(false) #endif

[5.4] Set Oracle CX - Infinity account GUID

Log in to the Oracle CX - Infinity and note down the account GUID displayed under the account/profile menu at the top right of the screen. Congure your "GUID" by calling setOracleCXAccountId API.

[[PushIOManager sharedInstance] setOracleCXAccountId:@"YOUR_ACCOUNT_GUID"];
PushIOManager.sharedInstance().setOracleCXAccountId("YOUR_ACCOUNT_GUID")

[5.5] Configure the SDK

This step is required to configure the SDK. There are several configuration APIs available in SDK, but we recommend to call configureWithFileName: API. Provide the filename of config.json file downloaded in step [1.4]. Please make sure your config.json files are in the app bundle.

// Configure the SDK
NSString *configName = @"YOUR_PRODUCTION_CONFIG_FILE_NAME.json";;
#ifdef DEBUG
configName = @"YOUR_DEBUG_CONFIG_FILE_NAME.json";  //(Optional) If you want to configure app for iOS Development/Sandbox Pushs.
#endif
[[PushIOManager sharedInstance] configureWithFileName:configName completionHandler:^(NSError *configError, NSString *response) {
if(configError != nil) {
NSLog(@"Unable to configure SDK, reason: %@", configError.description);
return;
}
}];
// Configure the SDK
var configName = "YOUR_PRODUCTION_CONFIG_FILE_NAME.json"
#if DEBUG
configName = "YOUR_DEBUG_CONFIG_FILE_NAME.json"
#endif
PushIOManager.sharedInstance().configure(withFileName: configName, completionHandler: { (configError, response) in
if let error = configError {
print("Not able to configure the sdk (error.localizedDescription)")
return
}
})

[5.6] Registering your app with APNS and Responsys server:

There are several APIs in SDK to register the App with APNS. We will use registerForAllRemoteNotificationTypes which will ask for alert, badge and sound permissions from user. This API will display system prompt for push notification permission. Call this API on completion of configureWithFileName API.

After registerForAllRemoteNotificationTypes completion we will call registerApp API. This api is responsible for syncing the sdk configurations and push permissions to Responsys servers.

// Register with APNS and request for push permissions
[[PushIOManager sharedInstance] registerForAllRemoteNotificationTypes:^(NSError error, NSString deviceToken) {
    if (nil == error) {
        NSError regTrackError = nil;

        // Register application with Responsys server. This API is responsible to send registration signal to Responsys server. This API sends all the values configured on SDK to server.
        [[PushIOManager sharedInstance] registerApp:&regTrackError completionHandler:^(NSError regAppError, NSString response) {
            if (nil == regAppError) {
                NSLog(@"Application registered successfully!");
            } else {
                NSLog(@"Unable to register application, reason: %@", regAppError.description);
            }
        }];
        if (nil == regTrackError) {
            NSLog(@"Registration locally stored successfully.");
        } else {
            NSLog(@"Unable to store registration, reason: %@", regTrackError.description);
        }
    }
}];
// Register with APNS and request for push permissions
PushIOManager.sharedInstance().register(forAllRemoteNotificationTypes: { (regTrackError, deviceToken) in
if (regTrackError == nil) {
print("Device token received from APNS: (deviceToken ?? "unknown")")
do {
//6. Register application with Responsys server. This API is responsible to send registration signal to Responsys server. This API sends all the values configured on SDK to server.
try PushIOManager.sharedInstance().registerApp(completionHandler: { (regError, response) in
if let error = regError {
print("Unable to register, reason: (error)")
} else{
print("Registration successful")
}
})
} catch {
print("Unable to track registration locally, reason: (error)")
}
}
})

[5.7] Integrate OracleCXResponsys into your application lifecycle in AppDelegate.m and combine all the steps:

At end call didFinishLaunchingWithOptions API of SDK. After all the above steps AppDelegate.m will look like this.

#import "AppDelegate.h"
//1. Import Frameworks
#import <OracleCXResponsys/OracleCXResponsys.h>
//For UserNotifications support
#import <UserNotifications/UserNotifications.h>
@interface AppDelegate()
@end
@implementation AppDelegate


(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//2. Set the UNUserNotificationCenter delegate
[UNUserNotificationCenter currentNotificationCenter].delegate= self;
//3. Enable Logging
#ifdef DEBUG
[[PushIOManager sharedInstance] setLoggingEnabled:YES];
[[PushIOManager sharedInstance] setLogLevel:PIOLogLevelInfo]; //PIOLogLevelWarn or PIOLogLevelError
#else
[[PushIOManager sharedInstance] setLoggingEnabled:NO];
#endif
//4. Configure the SDK. Please make sure your config.json files are in the app bundle.
NSString *configName = @"pushio_config.json";;
#ifdef DEBUG
configName = @"pushio_config_debug.json";  //(Optional) If you want to configure app for iOS Development/Sandbox.
#endif
[[PushIOManager sharedInstance] setOracleCXAccountId:@"YOUR_ACCOUNT_GUID"];
[[PushIOManager sharedInstance] configureWithFileName:configName completionHandler:^(NSError *configError, NSString *response) {
if(configError != nil) {
NSLog(@"Unable to configure SDK, reason: %@", configError.description);
return;
}
  //5. Register with APNS and request for push permissions
  [[PushIOManager sharedInstance] registerForAllRemoteNotificationTypes:^(NSError *error, NSString *deviceToken) {
      if (nil == error) {

          //Configure other SDK APIs here, if needed eg: [[PushIOManager sharedInstance] registerUserID:@"A1B2C3D4"];
          
          //6. Register application with Responsys server. This API is responsible to send registration signal to Responsys server. This API sends all the values configured on SDK to server.
          NSError *regTrackError = nil;
          [[PushIOManager sharedInstance] registerApp:&regTrackError completionHandler:^(NSError *regAppError, NSString *response) {
              if (nil == regAppError) {
                  NSLog(@"Application registered successfully!");
              } else {
                  NSLog(@"Unable to register application, reason: %@", regAppError.description);
              }
          }];
          if (nil == regTrackError) {
              NSLog(@"Registration locally stored successfully.");
          } else {
              NSLog(@"Unable to store registration, reason: %@", regTrackError.description);
          }
      }
  }];
}];
//7. Call the didFinishLaunching of SDK at end.
[[PushIOManager sharedInstance] didFinishLaunchingWithOptions:launchOptions];
return YES;
}


// Implement the delegate methods.
@end
		
import UIKit
//1. Import the frameworks
import OracleCXResponsys
//For UserNotifications support
import UserNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    
    //2. Set the `UNUserNotificationCenter` delegate
    UNUserNotificationCenter.current().delegate = self
    
    //3. Enable Logging
    #if DEBUG
        PushIOManager.sharedInstance().setLoggingEnabled(true)
        PushIOManager.sharedInstance().setLogLevel(PIOLogLevel.info) //PIOLogLevel.warn or PIOLogLevel.error
    #else
        PushIOManager.sharedInstance().setLoggingEnabled(false)
    #endif
    
    //4. Configure the SDK
    var configName = "YOUR_PRODUCTION_CONFIG_FILE_NAME.json"
    #if DEBUG
    configName = "YOUR_DEBUG_CONFIG_FILE_NAME.json"
    #endif

    PushIOManager.sharedInstance().setOracleCXAccountId("YOUR_ACCOUNT_GUID")
    
    PushIOManager.sharedInstance().configure(withFileName: configName, completionHandler: { (configError, response) in
        if let error = configError {
            print("Not able to configure the sdk \(error.localizedDescription)")
            return
        }
        
        //Configure other SDK parameters here, if needed eg: PushIOManager.sharedInstance().registerUserID("A1B2C3D4")
        
        //5. Register with APNS and request for push permissions
        PushIOManager.sharedInstance().register(forAllRemoteNotificationTypes: { (regTrackError, deviceToken) in
            if (regTrackError == nil) {
                print("Device token received from APNS: \(deviceToken ?? "unknown")")
                do {
                    //6. Register application with Responsys server. This API is responsible to send registration signal to Responsys server. This API sends all the values configured on SDK to server.
                    try PushIOManager.sharedInstance().registerApp(completionHandler: { (regError, response) in
                        if let error = regError {
                            print("Unable to register, reason: \(error)")
                        } else{
                            print("Registration successful")
                        }
                    })
                } catch {
                    print("Unable to track registration locally, reason: \(error)")
                }
            }
        })
    })

    //7. Call the didFinishLaunching of SDK at end.
    PushIOManager.sharedInstance().didFinishLaunching(options: launchOptions)
    return true
}

// Implement the delegate methods
}
		

[5.8] Implement the Apple Push Notification Service Callbacks in AppDelegate.m:

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:
    (NSData *)deviceToken
{
    [[PushIOManager sharedInstance]  didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
    [[PushIOManager sharedInstance]  didFailToRegisterForRemoteNotificationsWithError:error];
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    [[PushIOManager sharedInstance] didReceiveRemoteNotification:userInfo];
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:
(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    [[PushIOManager sharedInstance] didReceiveRemoteNotification:userInfo fetchCompletionResult:UIBackgroundFetchResultNewData fetchCompletionHandler:completionHandler];
}

//iOS 10 or later

- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler {
    [[PushIOManager sharedInstance] userNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:completionHandler];
}

-(void) userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:
(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
    [[PushIOManager sharedInstance] userNotificationCenter:center willPresentNotification:notification withCompletionHandler:completionHandler];
}																
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:
    (NSData *)deviceToken
{
    [[PushIOManager sharedInstance]  didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
    [[PushIOManager sharedInstance]  didFailToRegisterForRemoteNotificationsWithError:error];
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    [[PushIOManager sharedInstance] didReceiveRemoteNotification:userInfo];
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:
(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    [[PushIOManager sharedInstance] didReceiveRemoteNotification:userInfo fetchCompletionResult:UIBackgroundFetchResultNewData fetchCompletionHandler:completionHandler];
}

//iOS 10 or later

- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler {

    [[PushIOManager sharedInstance] userNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:completionHandler];

}

-(void) userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:
(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
    [[PushIOManager sharedInstance] userNotificationCenter:center willPresentNotification:notification withCompletionHandler:completionHandler];
}								

[5.9] Ready, set, test!

It's time to test sending a push notification.

  1. Log into the Web Dashboard.
  2. Navigate to the Push tab
  3. Choose All Active Devices from the Audience dropdown menu.
  4. Type in a message and click Send Now.
  5. If all went well, you should see your first true iOS push notification!

[5.10] Add the User Identifier methods

Responsys uses the USER_IDENTIFIER parameter to uniquely identify "known users" of your app. You must add the appropriate user identifier methods to register a user when the user logs in to the mobile app, to unregister a user when the user logs out, and you can also retrieve the known user's ID.

[5.10.1] Add code for "known user" identification.

Responsys uses the USER_IDENTIFIER parameter to uniquely identify "known users" of your app. To do this, when the user signs in or signs up in the app, you need to call the register user ID function of the SDK (where <match_key_value> is the value of the match key field):

[[PushIOManager sharedInstance] registerUserID:@" <match_key_value> "];
PushIOManager.sharedInstance().registerUserID(" <match_key_value> ")

Coordinate with the Responsys Account Admin regarding which match key field to use; the match key field must be chosen when the Account Admin creates the app channel list and it cannot be changed later. For more information about the match key, and recommendations for choosing which Profile List field to use as the match key, see the "Setting up the App Channel List" topic in the Mobile App Channel Configuration Guide.

Example of how "known user" identification works

In the following example, the match key field is CUSTOMER_ID, and let's assume that the CUSTOMER_ID values are normalized on all systems involved (that is, leading and trailing spaces are removed).

  1. A customer named John Doe with a customer ID of A1B2C3D4 logs in to your app with the username JohnDoe and password: ABC123

  2. Next, the backend server authenticates the user, and sends the mobile app the user's customer ID in the form of a string:     Successful Login to backend server > the customer ID A1B2C3D4 is obtained

  3. Finally, the app registers the user with Push SDK registerUserID method:

    [[PushIOManager sharedInstance] registerUserID:@"A1B2C3D4"];					
    PushIOManager.sharedInstance().registerUserID("A1B2C3D4")		

[5.10.2] Add code to unregister a "known user"

When the user finishes the session and logs out, the app unregisters the user by calling registerUserID and passing nil as the argument. (This action has the effect of clearing the USER_IDENTIFIER_ field in the App Channel List.)

[[PushIOManager sharedInstance] registerUserID:nil];					
PushIOManager.sharedInstance().registerUserID(nil)					

[5.10.3] Add code to retrieve a "known user"

Call the getUserID method to retrieve the registered userID:

NSString *userID = [[PushIOManager sharedInstance] getUserID];
					
let userID = PushIOManager.sharedInstance().getUserID()
					

Provisional Authorization

iOS 12 apps can implement provisional authorization along with other notification options.

Apps requesting provisional authorization do not need to prompt the user for push permission. Notifications can be "delivered quietly" which does not require user permission initially. When a notification is delivered quietly, it can only be seen in the iOS Notification Center. The notification will not display as a banner, make a sound, and so on. Later on, the user will need to explicitly select whether they want to keep receiving messages "prominently" or "quietly". They also can turn off these notification from the iOS Notification Center, so that only relevant messages are delivered.

To implement this you need to pass UNAuthorizationOptionProvisional while registering.

UNAuthorizationOptions options = UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound;

if (@available(iOS 12.0, *)) {
    options = (options | UNAuthorizationOptionProvisional);
} else {
    NSLog(@"Provisional Authorization is not supported below iOS 12.");
}

[[PushIOManager sharedInstance] registerForNotificationAuthorizations:options categories:nil completionHandler:^(NSError *error, NSString *response) {
    if (nil == error) {
        NSError *regTrackError = nil;
        [[PushIOManager sharedInstance] registerApp:&regTrackError completionHandler:^(NSError *regAppError, NSString *response) {
            if (nil == regAppError) {
               NSLog(@"Application registered successfully!");
            } else {
               NSLog(@"Unable to register application, reason: %@", regAppError.description);
            }
        }];
        if (nil == regTrackError) {
            NSLog(@"Registration locally stored successfully.");
        } else {
            NSLog(@"Unable to store registration, reason: %@", regTrackError.description);
        }
    }
}];
var options: UNAuthorizationOptions = [.alert, .badge, .sound]
if #available(iOS 12, *) {
    options.insert(.provisional)
} else {
    print("Provisional Authorization is not supported below iOS 12.")
}

PushIOManager.sharedInstance().register(forNotificationAuthorizations: options, categories: nil, completionHandler: { (regTrackError, deviceToken) in
    if (regTrackError == nil) {
        print("Device Token: \(String(describing: deviceToken))")
        do {
            // Register application with SDK.
            try PushIOManager.sharedInstance().registerApp(completionHandler: { (regError, response) in
                if (regError == nil) {
                    print("Registration successful")
                }
                else {
                    print("Unable to register, reason: \(String(describing: regError))")
                }
            })
        } catch {
            print("Unable to track registration locally, reason: \(error)")
        }
    }

})

Separate Opt-in for Push (Pre-permission Messaging)

If you want to delay the system prompt for push notification permission but want to register the application with SDK separately, don't call registerForAllRemoteNotificationTypes which is responsible for showing for system prompt for push notification permission. You can delay this API call, and call whenever you want.

 

Configure and Register

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //2. Set the `UNUserNotificationCenter` delegate
    [UNUserNotificationCenter currentNotificationCenter].delegate= self;
    
    //3. Enable Logging
#ifdef DEBUG
    [[PushIOManager sharedInstance] setLoggingEnabled:YES];
    [[PushIOManager sharedInstance] setLogLevel:PIOLogLevelInfo]; //PIOLogLevelWarn or PIOLogLevelError
#else
    [[PushIOManager sharedInstance] setLoggingEnabled:NO];
#endif
    
    //4. Configure the SDK. Please make sure your `config.json` files are in the app bundle.
    NSString *configName = @"pushio_config.json";;
#ifdef DEBUG
    configName = @"pushio_config_debug.json";  //(Optional) If you want to configure app for iOS Development/Sandbox.
#endif
    
    [[PushIOManager sharedInstance] configureWithFileName:configName completionHandler:^(NSError *configError, NSString *response) {
        if(configError != nil) {
            NSLog(@"Unable to configure SDK, reason: %@", configError.description);
            return;
        }
        
        //Configure other SDK APIs here, if needed eg: [[PushIOManager sharedInstance] registerUserID:@"A1B2C3D4"];.

        //5. Register application with Responsys server. This API is responsible to send registration signal to Responsys server. This API sends all the values configured on SDK to server.
        NSError *regTrackError = nil;
        [[PushIOManager sharedInstance] registerApp:&regTrackError completionHandler:^(NSError *regAppError, NSString *response) {
            if (nil == regAppError) {
                NSLog(@"Application registered successfully!");
            } else {
                NSLog(@"Unable to register application, reason: %@", regAppError.description);
            }
        }];
        if (nil == regTrackError) {
            NSLog(@"Registration locally stored successfully.");
        } else {
            NSLog(@"Unable to store registration, reason: %@", regTrackError.description);
        }
    }];
    
    //6. Call the didFinishLaunching of SDK at end.
    [[PushIOManager sharedInstance] didFinishLaunchingWithOptions:launchOptions];
    return YES;
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    
    //2. Set the `UNUserNotificationCenter` delegate
    UNUserNotificationCenter.current().delegate = self
    
    //3. Enable Logging
    #if DEBUG
        PushIOManager.sharedInstance().setLoggingEnabled(true)
        PushIOManager.sharedInstance().setLogLevel(PIOLogLevel.info) //PIOLogLevel.warn or PIOLogLevel.error
    #else
        PushIOManager.sharedInstance().setLoggingEnabled(false)
    #endif
    
    //4. Configure the SDK
    var configName = "YOUR_PRODUCTION_CONFIG_FILE_NAME.json"
    #if DEBUG
    configName = "YOUR_DEBUG_CONFIG_FILE_NAME.json"
    #endif

    PushIOManager.sharedInstance().configure(withFileName: configName, completionHandler: { (configError, response) in
        if let error = configError {
            print("Not able to configure the sdk \(error.localizedDescription)")
            return
        }
        
        //Configure other SDK parameters here, if needed eg: PushIOManager.sharedInstance().registerUserID("A1B2C3D4")
        
        
        //5. Register application with Responsys server. This API is responsible to send registration signal to Responsys server. This API sends all the values configured on SDK to server.
        do {
            try PushIOManager.sharedInstance().registerApp(completionHandler: { (regError, response) in
                if let error = regError {
                    print("Unable to register, reason: \(error)")
                } else{
                    print("Registration successful")
                }
            })
        } catch {
            print("Unable to track registration locally, reason: \(error)")
        }
    })
    
    //6. Call the didFinishLaunching of SDK at end.
    PushIOManager.sharedInstance().didFinishLaunching(options: launchOptions)
    return true
}

Opt-in

The user can be prompted for opting into Push notifications by calling the following method:

[[PushIOManager sharedInstance] registerForAllRemoteNotificationTypes:^(NSError *error, NSString *deviceToken) {
    if (nil == error) {
        NSLog(@"Device token received from APNS:%@",deviceToken);
    } else {
        NSLog(@"Unable to register for remote notifications,  reason:%@",error.description);
    }  
 }];
PushIOManager.sharedInstance().register(forAllRemoteNotificationTypes: { (error, deviceToken) in
    if let error =  error {
        print("Unable to register for remote notifications, reason: \(error.localizedDescription)")
    } else {
        print("Device token received from APNS: \(deviceToken ?? "unknown")")
    }
})

Ready for an Ad-Hoc and/or App Store Build?

Creating a push-enabled Ad-Hoc or App Store build is nearly identical to creating developer builds!

  • First, add a Distribution iOS Platform (not Development iOS) to your application setup.
  • Next, generate a Distribution .PEM in the Apple Provisioning Portal and upload the .PEM file to the iOS Distribution Platform.
  • Download and add your iOS Distribution pushio_config.json file to your project. This is the Distribution config file and will co-exist in your project alongside the pushio_config_debug.json file you previously added for development.
  • Lastly, make sure you have created a push-enabled distribution provisioning profile for your application and that your Xcode project is properly Code Signed for Distribution

Stripping symbols

This section is applicable only for .framework and can be skipped in case of XCFrameworks.

Both OracleCXResponsys and OracleCXMobileSDK frameworks are dynamic frameworks. So you will need to strip the extra architectures before archiving and uploading to iTunes. Simple commands can be run on these frameworks to strip the symbols.

Open the terminal and navigate to the directory where these frameworks are available. Copy the below command and run it.

lipo -remove i386 OracleCXResponsys -o OracleCXResponsys && lipo -remove x86_64 OracleCXResponsys -o OracleCXResponsys;			

It'll remove the i386 and x86_64 architectures from frameworks. Now you can archive the apps.

Note: Make sure you replace the frameworks back to the original ones. You'll not be able to run your app on simulators as we have stripped the architectures .

What's Next?

Now that you have completed the basic configuration and have tested push notifications, we recommend that you continue to the following topics:

Also, see our iOS FAQ for troubleshooting information and answers to general questions about the OCX Responsys iOS SDK.