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.

SDK Support Policy

The Oracle SDK Support Policy for the Oracle Responsys Mobile App Platform Cloud Service SDK / Responsys Push SDK covers only the four most recent Major SDK Releases. For example, if the most current SDK is 6.48.0, the SDK Support Policy covers SDK Versions 6.48.x, 6.47.x, 6.46.x, and 6.45.0.

Supported Platforms and Languages

  • Supported iOS versions: Oracle Responsys SDK 6.45.0 and later will support iOS 11.0 and later.

  • Supported XCode versions: Oracle Responsys SDK 6.45.0 and later is supported by XCode 10.0.x and later.

  • Supported languages: Objective-C and Swift.

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 iOS framework.

[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 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, and CoreLocation.framework.

[3.3] Ensure that the embed type for PushIOManager.xcframework is set to "Embed & Sign". Incase the SDK is of .framework extension i.e. PushIOManager.framework the embed type is "Do Not Embed".

All Frameworks added to project

Step 4: Adding Linker Flags

NOTE: Addition of linker flags is applicable only for .framework extension. Can skip this step when using XCFramework.

[4.1] Click Build Settings.

[4.2] Double-click Other Linker Flags.

Double-click Other Linker Flags to add switches

 

[4.4] Enter -ObjC.

 Enter `-ObjC` linker switch entered

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

`-ObjC` 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:

  • 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

Step 6: Implement Code

[6.1] Import the frameworks.

//1. Import Frameworks
#import <PushIOManager/PushIOManager.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 PushIOManager
//For UserNotifications support
import UserNotifications

//Implement UserNotifications delegate to receive the notification callbacks in iOS 10.
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

}

[6.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

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

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

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

//4. 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;
    } 
}];					
//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
    }
})

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

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

        //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.
        [[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);
        }
    }
}];					
//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)")
        }
    }
})

[6.6] Integrate PushIOManager 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 <PushIOManager/PushIOManager.h>
//For UserNotifications support
#import <UserNotifications/UserNotifications.h>

@interface AppDelegate()<UNUserNotificationCenterDelegate>
@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] 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 PushIOManager
//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().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
}

[6.7] Implement the Apple Push Notification Service Callbacks in AppDelegate class:

- (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];
}

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options { 
    [[PushIOManager sharedInstance] openURL:url options:options];
    return YES;
}

//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];
}																
func application(
_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) 
{
    PushIOManager.sharedInstance().didRegisterForRemoteNotifications(withDeviceToken: deviceToken)
}

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

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

func application(_ application: UIApplication,didReceiveRemoteNotification userInfo: [AnyHashable : Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) 
{
    PushIOManager.sharedInstance().didReceiveRemoteNotification(userInfo, fetchCompletionResult: UIBackgroundFetchResult.newData, fetchCompletionHandler: completionHandler)
}

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    PushIOManager.sharedInstance().open(url, options:options)
}

//iOS 10 or later

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

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

[6.7.1] For Scene-based apps, implement the following methods in your SceneDelegate class. Note this API is available for the Oracle Responsys SDK 6.50.0 and above.

 - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions  API_AVAILABLE(ios(13.0))
    {
    
         [[PushIOManager sharedInstance] willConnectToSession:session options:connectionOptions];
     }		
     - (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts  API_AVAILABLE(ios(13.0))
    {
    
        [[PushIOManager sharedInstance] openURLContexts:URLContexts];
    }
    - (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity  API_AVAILABLE(ios(13.0))
    {
        [[PushIOManager sharedInstance] continueUserActivity:userActivity restorationHandler:nil];
    }
                        
        													
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)
    {
        PushIOManager.sharedInstance().willConnect(to: session, options: connectionOptions)               
    }
    
    func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>)
    {
        PushIOManager.sharedInstance().openURLContexts(URLContexts)
    }	

    func scene(_ scene: UIScene,continue userActivity: NSUserActivity)
    {
        PushIOManager.sharedInstance().continue(userActivity, restorationHandler: nil)
    }

    

[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.1] 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 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")		

 

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

 

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.