Upsight logo Back to top

Push

Prerequisites


Setting Up for Push Notifications

If you have a push-enabled App ID and a production push certification, then you can skip the Prerequisites and precede to integrating Push.

Setting Up App ID and Certificates

  1. Login to your Apple Developer's Account.

  2. Click the Identifiers Portal under iOS Apps.

  3. Find the App ID and select edit or select the "+" button the top right corner to add a new App ID.

    Edit App

  4. Click the checkmark box next to Push Notifications and click Create Certificate for the environment you are implementing push on.

    Create Certificate

Production and Development Environments

To develop and deploy an application that supports push notifications, you must get SSL certificates from the appropriate Dev Center. Each certificate is limited to a single application, identified by its bundle ID. Each certificate is also limited to 1-2 development environments:

  • Development: Use the development environment for initial development and testing of the provider application.
  • Production: Use the production environment when building the production version of the provider application.

You must get separate certificates for the development environment and the production environment. The certificates are associated with an identifier of the application that is the recipient of push notifications; this identifier includes the application’s bundle ID.

Enabling Push Notification Service

  1. Follow the instructions to create a Certificate Signing Request (CSR) file and hit continue.

    Create Certificate

  2. Upload the .certSigningRequest file you just create and generate your iOS Push Certificate and hit continue.

  3. Download the file and double click to install the certificate to your Keychain Access Utility.

  4. When you finish those steps, the push notification service will be enabled in your iOS App ID settings as illustrated in the screenshot below.

    iOS App ID settings

SSL Certificate and Key

You should upload the SSL distribution certificate (or development certificate if you are using the development environment) and private cryptographic key to the Push Dashboard so that Upsight servers can connect with Apple's Push Notification service. To obtain your SSL APNS Certificate, follow these steps:

  1. Open the Keychain Access utility and click the My Certificates category in the left pane. Keychain Access Utility

  2. Find the certificate you just downloaded and installed to your Keychain Access. The certificate you are interested in should resemble the certificate shown in the above screenshot.

  3. Select the certificate and click File, Export Items. Export the certificate as a Personal Information Exchange (.p12) file.

To upload your certificate to the Push Dashboard, see the Push Interface section.

Setting Up and Installing the Provisioning Profile

The provisioning profile is a collection of assets that associates developers of an application and their devices with an authorized development team and enables those devices to be used for testing. The profile contains certificates, device identifiers, the application’s bundle ID, and all entitlements, including <aps-environment>. All team members must install the provisioning profile on the devices on which they will run and test application code.

To setup and install the provisioning profile, team members should complete the following steps shown in the table below.

  1. Login to your Apple Developer's Account.

  2. Go to the Provisioning Portal under iOS Apps.

  3. Download the provisioning profile associated with the application that is going to be tested or select the "+" button the top right corner to add a new Provisioning Profile.

    Provisioning Profile

  4. Double click the downloaded .mobileprovision profile file or drag it on to the Xcode or iTunes application icons to install. Alternatively, you can move the profile file to ~/Library/MobileDevice/Provisioning Profiles. Create the directory if it does not already exist.

  5. In the Xcode Organizer window, go to the Provisioning Profiles section and install the profile on your device. If using Xcode 6 navigate to the Xcode Devices window instead. Additionally remember to set your Provisioning Profile under Code Signing within your Build Settings.

Integration Push


Push is supported through the USPush interface. Pushed content is displayed through a Push-specific billboard which is managed by the USPush interface. To integrate push, you must:

  1. Check 'Remote notifications' from the list of Background Modes in the Capabilities section of your target's settings.

  2. Add the USBillboardDelegate and UNUserNotificationCenterDelegate protocols to your App Delegate as well as import UserNotifications.h.

    #import <UserNotifications/UserNotifications.h>
    @interface AppDelegate () <USBillboardDelegate, UNUserNotificationCenterDelegate>`
    
  3. Implement the presentingViewControllerForBillboard: method in your App Delegate.

    - (UIViewController *)presentingViewControllerForBillboard:(id<USBillboard>)aBillboard {
    
    UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
    
        while (topController.presentedViewController) {
            topController = topController.presentedViewController;
        }
    return topController;
    }
    
  4. Register for push by calling [USPush registerForPushNotifications] in your App Delegate's didFinishLaunchingWithOptions: method, on iOS 10+, also set the Notification Center delegate.

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
        if ([[[UIDevice currentDevice] systemVersion] compare:@"10.0" options:NSNumericSearch] != 
        NSOrderedAscending)
        {
            [[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];
        }   
        [USPush registerForPushNotifications];
    return YES;
    }
    
  5. Call the USPush API method didRegisterUserNotificationSettings: in your App Delegate's application:didRegisterUserNotificationSettings: method.

     - (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
    
    [USPush didRegisterUserNotificationSettings:notificationSettings];
    
    }
    
  6. Call the USPush API method registerPushToken: from didRegisterForRemoteNotificationsWithDeviceToken:

    - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    
    [USPush registerPushToken:deviceToken];
    
    }
    
  7. When a remote notification is received, set the USPush billboard's delegate to be your App Delegate class and call the USPush interface's handleRemoteNotificationWithUserInfo: method.

    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    
    [USPush pushBillboard].delegate = self;
    [USPush handleRemoteNotificationWithUserInfo:userInfo];
    
        if (NULL != completionHandler) {
            completionHandler(UIBackgroundFetchResultNoData);
          }
    }
    
    - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:
    (UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler
    {
        [USPush pushBillboard].delegate = self;
        [USPush handleRemoteNotificationWithUserInfo:response.notification.request.content.userInfo];
    
        if (NULL != completionHandler) {
            completionHandler();
        }
    }
    

Note Once you have called USPush registerPushToken: the SDK will send an upsight.com.register message to the server containing your token. You can see this message through the Real Time dashboard.

Sample AppDelegate


Here is a sample AppDelegate implementation that properly integrates Push

@interface AppDelegate () <USBillboardDelegate, UNUserNotificationCenterDelegate>
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        if ([[[UIDevice currentDevice] systemVersion] compare:@"10.0" options:NSNumericSearch] != 
        NSOrderedAscending)
    {
        [[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];
    }

        [USPush registerForPushNotifications];


    return YES;
}

- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
    [USPush didRegisterUserNotificationSettings:notificationSettings];
}

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

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    [USPush pushBillboard].delegate = self;
    [USPush handleRemoteNotificationWithUserInfo:userInfo];

        if (NULL != completionHandler) {
            completionHandler(UIBackgroundFetchResultNoData);
        }
}

- (void)applicationWillResignActive:(UIApplication *)application {
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
}

- (void)applicationWillTerminate:(UIApplication *)application {
}

#pragma mark - Billboard delegate

- (UIViewController *)presentingViewControllerForBillboard:(id<USBillboard>)aBillboard
{
    UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;

    while (topController.presentedViewController) {
        topController = topController.presentedViewController;
    }

    return topController;
}

    #pragma mark - Notification Center Delegate
    - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:
       (UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler
    {
     [USPush pushBillboard].delegate = self;
     [USPush handleRemoteNotificationWithUserInfo:response.notification.request.content.userInfo];

      if (NULL != completionHandler) {
         completionHandler();
       } 
    }

@end

Image Push


Overview

On iOS 10 and above, developers can use Upsight to send push notifications containing rich media such as images and gifs. In order to take advantage this, a few simple integration steps are required. Upsight currently supports image push for the following image formats: JPG,JPEG, PNG, GIF and SDK versions 4.3.2 and above.

To get started:

Add a new Target to your Xcode Project by navigating to the Target Template Selection screen by clicking File -> New -> Target. Once on the screen select the Notification Service Extension icon shown below and press Next. When choosing options for your Target, make sure ‘Language’ is set to Objective-C and ‘Embed In Application’ is set to the correct application.

Extension Selection

Notification Service Extensions have a separate Bundle ID from your application. In order to account for the new Bundle ID, you must generate a separate App ID and Provisioning Profile for the Notification Service Extension on the Apple Developer Portal.

Once your Notification Service Extension is created, Xcode will add a folder named with the product name designated when creating the Target. Inside this folder you will need to locate the NotificationService.m file and add the following code:

#import "NotificationService.h"
#import "Upsight.h"

@interface NotificationService ()

@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;

@end

@implementation NotificationService

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];

    // Get a reference to the Upsight data in the push payload
    NSDictionary * inPushPayload =  request.content.userInfo[@"upsight_push_data"];

    if(nil != inPushPayload && [inPushPayload isKindOfClass:[NSDictionary class]] ) {
        NSMutableDictionary * outPushPayload = [[NSMutableDictionary alloc] initWithDictionary:inPushPayload];
        // Create a string with the Image URL passed down in the
        // Upsight payload using the key "media_url"
        NSString * imgString = inPushPayload[@"media_url"];

        // If an image is contained in the payload, the code below will
        // Manage the downloading and displaying of the image in the push.
        if(nil != imgString && [imgString isKindOfClass:[NSString class]]) {
            NSURL * imgURL = [NSURL URLWithString:imgString];

            [[[NSURLSession sharedSession] downloadTaskWithURL:imgURL completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
                // If the download is successful a copy of the data will be stored in a
                // temporary directory where the data can be used to display the push
                if(nil != location) {
                    NSString * aTmpDir = NSTemporaryDirectory();
                    NSString * aTmpFileString = [imgURL lastPathComponent];

                    NSURL * theTmpUrl = [NSURL URLWithString:[[@"file://" stringByAppendingString:aTmpDir] stringByAppendingString:aTmpFileString]];

                    bool didMove = [[NSFileManager defaultManager] moveItemAtURL:location toURL:theTmpUrl error:nil];
                    if(didMove) {
                        // The image is added to the push as an attachment.
                        UNNotificationAttachment * theAttachment = [UNNotificationAttachment attachmentWithIdentifier:@"USPushAttachment" URL:theTmpUrl options:nil error:nil];
                        self.bestAttemptContent.attachments = @[theAttachment];
                    }
                }
                else if(error) {
                    //  Uncomment this log if you are having issues with rich pushes.
                    //  NSLog("Error downloading file with Error:%@",error);
                    outPushPayload[@"error"] = error;
                    self.bestAttemptContent.userInfo = outPushPayload;
                }
                // Pass back the content handler that will display the push notification
                self.contentHandler(self.bestAttemptContent);
            }] resume];
        }
        else {
            // Append error details to the push payload
            outPushPayload[@"error"] = [NSError errorWithDomain:@"USPushDomain" code:0 userInfo:@{NSLocalizedDescriptionKey:@"No media URL in push payload"}];
            self.bestAttemptContent.userInfo = outPushPayload;
            self.contentHandler(self.bestAttemptContent);
        }
    }
    else {
        self.contentHandler(self.bestAttemptContent);
    }
}

- (void)serviceExtensionTimeWillExpire {
    // Deliver your "best attempt" content, otherwise the original push payload will be used.
    self.contentHandler(self.bestAttemptContent);
}

@end

Note Don’t forget to build and run your code before attempting to send a test push.

When adding a creative to your push notification, you will have the option to upload an image, which will be stored on Upsight’s CDN and delivered to the targeted devices upon request.