Oracle Help Center | Oracle Responsys Mobile App Platform Cloud Service title

Step-by-Step Setup Instructions

This topic provides detailed instructions for integrating your iOS mobile app with Oracle Responsys Mobile App Platform Cloud Service. Follow the steps in this section if you are new to Oracle Responsys Mobile App Platform Cloud Service and you are adding the SDK to your mobile app project for the first time.

 

Before You Continue

If you have already integrated the Oracle Responsys Mobile App Platform Cloud Service SDK to your mobile app for a previous release, use the instructions in the Upgrade Guide topic. The Upgrade Guide topic contains information about changes needed to your mobile app for SDK upgrades and for iOS upgrades.

Supported platforms and languages

Supported iOS versions: PushIO SDK 6.38.0 and later will support iOS 9.0 and later.

Supported XCode versions: PushIO SDK 6.38.0 and later is supported by XCode 9.0.x and later.

Supported languages: Objective-C and Swift.

NOTES:

 

Step 1: Initial Setup

[1.1] For your initial Oracle Responsys Mobile App Platform 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.

"Add Platform dialog on the Responsys Mobile App Developer Console"

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.a] On the iOS Development dialog, enter the app title (unique for your app and platform), and then click the Upload button.

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

[1.3.c] 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 PushIOManager 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: Add Project Files

[2.1] Download the framework from GitHub.

[2.2] Extract the downloaded zip.

[2.3] Drag and drop the PushIOManager framework folder into your project.

"Adding files from Finder to your iOS 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: Add Frameworks

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

[3.2] On the Summary 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, and CoreLocation.framework.

"All Frameworks added to project"

Step 4: Adding Linker Flags

[4.1] Click Build Settings.

[4.2] Double-click Other Linker Flags.

"Double-click Other Linker Flags to add switches"

[4.4] Enter -ObjC -all_load.

" Enter `-ObjC -all_load` linker switch entered"

[4.5] The linker switch was added for the Debug and Release versions.

"`-ObjC -all_load` linker switch added"

 

Step 5: Enable Push Notifications

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

Ensure that when you enable Push Notifications:

"Enable Push Notifications on Capabilities tab screenshot"

 

Step 6: Implement Code

[6.1] Import the framework.

//Import PushIOManager
#import <PushIOManager/PushIOManager.h>

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

}
        

[6.2] Configure the SDK.

In your AppDelegate.m file, configure the SDK:

NSString *apiKey = nil;
NSString *accountToken = nil;
#ifdef DEBUG
    apiKey = DEV_APIKEY; //Copy the apiKey value from pushio_config_debug.json
    accountToken = DEV_ACCOUNT_TOKEN; //Copy the accountToken value from pushio_config_debug.json. Assign nil if no value available.
#else
    apiKey = RELEASE_APIKEY; //Copy the apiKey value from pushio_config.json.
    accountToken = RELEASE_ACCOUNT_TOKEN;//Copy the accountToken value from pushio_config.json. Assign nil if no value available.
#endif
NSError *error = nil;
[[PushIOManager sharedInstance] configureWithAPIKey:apiKey accountToken:accountToken error:&error];
if(nil == error)
{
    NSLog(@"SDK Configured Successfully");
}
else
{
    NSLog(@"Unable to configure SDK, reason: %@", error.description);
}
var apiKey : String
var accountToken : String

#if DEBUG
    apiKey = "DEBUG_APIKEY"//Copy the apiKey value from pushio_config_debug.json
    accountToken = "DEBUG_ACCOUNT_TOKEN";//Copy the accountToken value from pushio_config_debug.json. Assign nil if no value available.
#else
    apiKey = "RELEASE_APIKEY"//Copy the apiKey value from pushio_config.json.
    accountToken = "RELEASE_ACCOUNT_TOKEN";//Copy the accountToken value from pushio_config.json. Assign nil if no value available.
#endif

do {
    try PushIOManager.sharedInstance().configure(withAPIKey: apiKey, accountToken: accountToken)
    print("PushIO Configured!!!")
}catch{
    print("Unable to configure PushIO, reason: \(error.localizedDescription)")
}
        

[6.3] Enable Logging.

In your AppDelegate.m file, enable logging (in the debug console):

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

[6.4] In your AppDelegate.m file, add the following to let the SDK know the configuration type. The configuration type tells the SDK which configuration file to read:

#ifdef DEBUG
[PushIOManager sharedInstance].configType = PIOConfigTypeDebug; //load pushio_config_debug.json
#else
[PushIOManager sharedInstance].configType = PIOConfigTypeRelease;//load pushio_config.json
#endif
#if DEBUG
    PushIOManager.sharedInstance().configType = PIOConfigType.debug //load pushio_config_debug.json
#else
    PushIOManager.sharedInstance().configType = PIOConfigType.release //load pushio_config.json
#endif
        

[6.5] Integrate PushIOManager into your application lifecycle in AppDelegate.m:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // This assumes that steps [6.1, 6.2, 6.3, 6.4] above are implemented before the following is called

    // Requests a device token from Apple
    [[PushIOManager sharedInstance] registerForAllRemoteNotificationTypes:^(NSError *error, NSString *deviceToken)
    {
        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);
            }
        }
    }];

    [[PushIOManager sharedInstance] didFinishLaunchingWithOptions:launchOptions];
    // Override point for customization after application launch.
    return YES;
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {       
  // Requests a device token from Apple
  PushIOManager.sharedInstance().register(forAllRemoteNotificationTypes: { (regTrackError, deviceToken) in
     if (regTrackError == nil){
         print("Device Token: \(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: \(regError)")
                 }
             })
         }catch{
             print("Unable to track registration locally, reason: \(error)")
         }
     }
  })

 PushIOManager.sharedInstance().didFinishLaunching(options: launchOptions)
 // Override point for customization after application launch.
 return true
}
        

[6.6] In your AppDelegate.m file , add the following line in the -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions function to indicate that the AppDelegate will be containing the implementation for the UserNotification Callbacks

[UNUserNotificationCenter currentNotificationCenter].delegate= self;
UNUserNotificationCenter.current().delegate = self
        

[6.7] 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
-(void) userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:
(UNNotificationResponse *)response withCompletionHandler:(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];
}
// didRegisterForRemoteNotificationsWithDeviceToken
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    PushIOManager.sharedInstance().didRegisterForRemoteNotifications(withDeviceToken: deviceToken)
}

// didFailToRegisterForRemoteNotificationsWithError
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
    PushIOManager.sharedInstance().didFailToRegisterForRemoteNotificationsWithError(error)
}

// didReceiveRemoteNotification
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]){
    PushIOManager.sharedInstance().didReceiveRemoteNotification(userInfo)
}

// userNotificationCenter:didReceiveNotificationResponse
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    PushIOManager.sharedInstance().userNotificationCenter(center, didReceive: response, withCompletionHandler: completionHandler)
}

// userNotificationCenter:willPresentNotification
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    PushIOManager.sharedInstance().userNotificationCenter(center, willPresent: notification, withCompletionHandler: completionHandler)
}
        

[6.8] 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!

[6.9] 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.

[6.9.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:

     Username: JohnDoe

     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")
        

[6.8.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)
        

[6.8.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()
        

 

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, now there are additional/separate methods provided to achieve it.

NOTE: The methods described in this section are available only when using the 6.33 PushIO SDK for iOS.

Configure and Register

The following method can be used to both configure the SDK and register with the Server by supplying a valid apiKey and accountToken. The completion handler is called when the registration is finished.

NSString *apiKey = nil;
NSString *accountToken = nil;
#ifdef DEBUG
    apiKey = DEV_APIKEY; //Copy the apiKey value from pushio_config_debug.json
    accountToken = DEV_ACCOUNT_TOKEN; //Copy the accountToken value from pushio_config_debug.json. Assign nil if no value available.
#else
    apiKey = RELEASE_APIKEY; //Copy the apiKey value from pushio_config.json.
    accountToken = RELEASE_ACCOUNT_TOKEN;//Copy the accountToken value from pushio_config.json. Assign nil if no value available.
#endif
[[PushIOManager sharedInstance] configureAndRegisterWithAPIKey:apiKey accountToken:accountToken completionHandler:^(NSError *error, NSString *response){
            if(nil == error){
               NSLog(@"Application registered successfully");
            }else{
                NSLog(@"Unable to configure and register, reason:%@",error.description);
            }
        }];
var apiKey : String
var accountToken : String
//FIXME: correct the apiKey and accountToken values
#if DEBUG
    apiKey = "DEBUG_APIKEY";//Copy the apiKey value from pushio_config_debug.json
    accountToken = "DEBUG_ACCOUNT_TOKEN";//Copy the accountToken value from pushio_config_debug.json. Assign nil if no value available.
#else
    apiKey = "RELEASE_APIKEY";//Copy the apiKey value from pushio_config.json.
    accountToken = "RELEASE_ACCOUNT_TOKEN";//Copy the accountToken value from pushio_config.json. Assign nil if no value available.
#endif

PushIOManager.sharedInstance().configureAndRegister(withAPIKey: apiKey, accountToken: accountToken) { (error, response) in
      if(nil == error){
         print("Application registered successfully!")
      }else{
         print("Unable to configure and register, reason:\(error?.localizedDescription)")
      }
    }

        

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 (nil == error){
                print("Device token received from APNS: \(deviceToken)")
            }else{
                print("Unable to register for remote notifications, reason: \(error?.localizedDescription)")
            }
    })
        

 

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!

 

What's Next?

Now that you have completed the basic configurations, it's time to prepare your app for the additional capabilities available when you use Oracle Responsys to send your push and in-app messaging campaigns. We recommend that you continue to the following topics:

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