Push Notifications

The Zendesk SDK for iOS uses Apple Push Notification service (APNs) for push notifications. The following steps will guide you, or your development team, through the process of setting up push notifications for the Zendesk SDK in your app.

Step 1 - Creating your .p12 certificate on the Apple Developer site

For the steps below, you must be logged in to your Apple Developer account. If you don’t have a developer account yet, you can enroll here.

  1. Log in to Apple Developer Member Center, and navigate to the certificates list.
  2. Click the + button at the top of the page to create a new certificate, and select Apple Push Notification service SSL (Sandbox & Production).
  3. Select your app ID from the dropdown and click continue.
  4. Follow the instructions to generate a Certificate Signing Request (CSR) using Keychain Access, and upload it to generate your certificate.
  5. Once the certificate is ready, download it to your computer and double-click it to open it in Keychain Access.
  6. Right click on the certificate you created, and select Export "Apple Push Services: {your-app-id}".
  7. Choose a password, if desired, and save the .p12 file to your computer.

Step 2 - Adding your .p12 certificate in the Zendesk Admin Center

Now that you have created your .p12 certificate, it will need to uploaded to the Zendesk Admin Center by an admin on your Zendesk account. If you are not an admin, please contact the admin on your account to assist you with this step.

Step 3 - Add the push notifications capability to your project

  1. Select your project target.
  2. Go to the Signing & Capabilities tab.
  3. Add the Push Notifications capability with the + Capability button.

Step 4 - Set the APS Environment entitlement

This is added automatically when you add the Push Notifications capability. Check the app's .entitlements file to make sure an APS Environment key exists.

Step 5 - Request authorization for push notifications from your user

Register for push notifications using UNUserNotificationCenter in your AppDelegate in application(didFinishLaunchingWithOptions).

Swift

import UserNotifications

func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    registerForPushNotifications()
    return true
}

private func registerForPushNotifications() {
    let notificationCenter = UNUserNotificationCenter.current()
    notificationCenter.delegate = self
    notificationCenter.requestAuthorization(options: [.alert, .sound, .badge]) { allowed, _ in
        guard allowed else { return }

        DispatchQueue.main.async {
            UIApplication.shared.registerForRemoteNotifications()
        }
    }
}

Objective-C

#import <UserNotifications/UserNotifications.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [self registerForPushNotifications];
    return YES;
}

- (void)registerForPushNotifications {
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
      center.delegate = self;
      [center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge)
         completionHandler:^(BOOL allowed, NSError * _Nullable error) {
        if (allowed) {
          dispatch_async(dispatch_get_main_queue(), ^{
              [[UIApplication sharedApplication] registerForRemoteNotifications];
          });
        }
    }];
}

Step 6 - Add the Zendesk SDK to your app

Add the Zendesk SDK and update the PushNotifications class with the received device token.

Override application(didRegisterForRemoteNotificationsWithDeviceToken) in your AppDelegate.

Swift

import ZendeskSDKMessaging

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    PushNotifications.updatePushNotificationToken(deviceToken)
}

Objective-C

#import <ZendeskSDKMessaging/ZendeskSDKMessaging.h>

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

Step 7 - Show push notifications in your app

Conform to the UNUserNotificationCenterDelegate.

Swift

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate

Objective-C

@interface AppDelegate : UIResponder <UIApplicationDelegate, UNUserNotificationCenterDelegate>

Implement userNotificationCenter(willPresent) to display a notification while the app is in the foreground.

Swift

func userNotificationCenter(_ center: UNUserNotificationCenter,
                            willPresent notification: UNNotification,
                            withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    let userInfo = notification.request.content.userInfo

    // This checks whether a received push notification should be displayed by Messaging
    let shouldBeDisplayed = PushNotifications.shouldBeDisplayed(userInfo)

    switch shouldBeDisplayed {
    case .messagingShouldDisplay:
        // This push belongs to Messaging and the SDK is able to display it to the end user
        if #available(iOS 14.0, *) {
            completionHandler([.banner, .sound, .badge])
        } else {
            completionHandler([.alert, .sound, .badge])
        }
    case .messagingShouldNotDisplay:
        // This push belongs to Messaging but it should not be displayed to the end user
        completionHandler([])
    case .notFromMessaging:
        // This push does not belong to Messaging
        // If you have push notifications in your app, place your code here

        // If not, just call the `completionHandler`
        completionHandler([])
    @unknown default: break
    }
}

Objective-C

- (void)userNotificationCenter:(UNUserNotificationCenter *)center
       willPresentNotification:(UNNotification *)notification
         withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {

    id userInfo = notification.request.content.userInfo;

    // This checks whether a received push notification should be displayed by Messaging
    ZDKPushResponsibility shouldBeDisplayed = [ZDKPushNotifications shouldBeDisplayed:userInfo];

    switch (shouldBeDisplayed) {
        case ZDKPushResponsibilityMessagingShouldDisplay:
            // This push belongs to Messaging and the SDK is able to display it to the end user
            if (@available(iOS 14.0, *)) {
                completionHandler(UNNotificationPresentationOptionBanner | UNNotificationPresentationOptionSound | UNNotificationPresentationOptionBadge);
            } else {
                completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionSound | UNNotificationPresentationOptionBadge);
            }
            break;
        case ZDKPushResponsibilityMessagingShouldNotDisplay:
            // This push belongs to Messaging but it should not be displayed to the end user
            completionHandler(UNNotificationPresentationOptionNone);
            break;
        case ZDKPushResponsibilityNotFromMessaging:
            // This push does not belong to Messaging
            // If you have push notifications in your app, place your code here

            // If not, just call the `completionHandler` and `break`
            completionHandler(UNNotificationPresentationOptionNone);
            break;
    }
}

Step 8 - Handle push notifications in your app

Implement userNotificationCenter(didReceive) to handle when the notification is tapped.

Swift

func userNotificationCenter(_ center: UNUserNotificationCenter,
                            didReceive response: UNNotificationResponse,
                            withCompletionHandler completionHandler: @escaping () -> Void) {
    let userInfo = response.notification.request.content.userInfo

    // This checks whether a received push notification should be handled by Messaging
    let shouldBeDisplayed = PushNotifications.shouldBeDisplayed(userInfo)

    switch shouldBeDisplayed {
    case .messagingShouldDisplay:
        // This push belongs to Messaging and the SDK is able to handle when the end user interacts with it
        PushNotifications.handleTap(userInfo) { viewController in
           // Handle displaying the returned viewController in here
        }
    case .messagingShouldNotDisplay:
        // This push belongs to Messaging but the interaction should not be handled by the SDK
        break
    case .notFromMessaging:
        // This push does not belong to Messaging
        // If you have push notifications in your app, place your code here

        // If not, just call `break`
        break
    @unknown default: break
    }

    completionHandler()
}

Objective-C

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

    id userInfo = response.notification.request.content.userInfo;

    // This checks whether a received push notification should be handled by Messaging
    ZDKPushResponsibility shouldBeDisplayed = [ZDKPushNotifications shouldBeDisplayed:userInfo];

    switch (shouldBeDisplayed) {
        case ZDKPushResponsibilityMessagingShouldDisplay:
            // This push belongs to Messaging and the SDK is able to handle when the end user interacts with it
            [ZDKPushNotifications handleTap:userInfo completion:^(UIViewController * _Nullable viewController) {
                // Handle displaying the returned viewController in here
            }];
            break;
        case ZDKPushResponsibilityMessagingShouldNotDisplay:
            // This push belongs to Messaging but the interaction should not be handled by the SDK
            break;
        case ZDKPushResponsibilityNotFromMessaging:
            // This push does not belong to Messaging
            // If you have push notifications in your app, place your code here

            // If not, just call break
            break;
    }

    completionHandler();
}