iOS implementation


Set up a mobile app using the PingID SDK sample code

Prerequisites

  1. Make sure that you have the following prerequisite, as described in Initial account configurations:

    • The Application ID (used in the server side integration).
  1. Prepare the iOS push messaging certificates:

    If you intend to use push messaging in your app, verify that you have your push configuration information:

Configure iOS push messaging certificates:

  • iOS Remote Notification:
    • When configuring your PingID SDK application in the PingOne admin web console, you should upload your Apple iOS Push Services Certificate. Find it under “Connect to your application” in the Application Configuration page in the PingOne admin web console.

IDE integration

PingID SDK Demo Application iOS - IDE integration:

  1. In the example app, make sure that you change the following settings in Constants.m, to your customer server URL and the Application ID respectively, which you retrieved from the PingOne admin web console:

    kCustomerServerUrl  
    kAppID
  1. Add the PingID SDK component into your existing project:

    • For versions up to PingID SDK 1.4.x:
      • In your Project Navigator, click on your target, and drag PingID_SDK.framework to Embedded Binaries.
      • Check the Copy items if needed checkbox.
    • For PingID SDK 1.5+:
      • In your Project Navigator, click on your target, and drag PingID_SDK.xcframework to Frameworks, Libraries and Embedded Content.
      • Check the Copy items if needed checkbox.
  2. Enable location:

    PingID SDK uses location, if it is available. Regardless, add the NSLocationWhenInUseUsageDescription to your info.plist with a short description. Implement CLLocationManager, and ask for location permissions.

  3. For versions up to PingID SDK 1.4.x, setup the Run Script phase:

    • Make sure that the Run Script phase is after the Embed Frameworks phase.

    • Select your application’s Xcode project, then your application target, and then select Build Phases, click +, and then New Run Script Build Phase.

    • Paste the following line into the body of the Run Script Build Phase:
      bash "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/PingID_SDK.framework/strip-frameworks.sh"

  4. Project build settings:

    In your target, set Always Embed Swift Standard Libraries to YES.

Implement the PingID SDK in your code

This section details the implementation steps of the PingID SDK flows and logic, which are described in Multifactor authentication (MFA) methods and User device pairing.

  1. Configure remote notification: If you intend to use push messaging in your app, you should have your Apple iOS Push Services Certificate ready. Upload the certificate in the PingOne admin console: Go to Setup > Certificates.
  1. Integrate the PingID SDK component into your code:
    • Initialize the PingID SDK singleton. Import the framework into your application initialization code :

      #import <PingID_SDK/PingID.h>

    • Call the initWithAppID method, passing the Application ID requested from the admin (from the PingOne admin console) when the application was created.

      Language Example
      Objective-C [PingID initWithAppID:##YOUR_APP_ID_HERE##];
      Swift PingID.initWithAppID(##YOUR_APP_ID_HERE##)
      • Call the initWithAppID:supportedMfa: method with the required registration mode for pairing (MFA type):

        • Objective-C:

          [PingID initWithAppID:##YOUR_APP_ID_HERE## supportedMfa:##PIDSupportedMfaType##];
        • Swift:

          open class func initWithAppID(##YOUR_APP_ID_HERE##, supportedMfa:##PIDSupportedMfaType##)
        Registration mode value Description
        PIDSupportedMfaTypeAutomatic MFA supports remote notifications with automatic fallback to one time passcode.
        PIDSupportedMfaTypeRemoteNotification MFA supports remote notifications only.
        PIDSupportedMfaTypeOneTimePasscode MFA supports one time passcode only, and will not support remote notifications.

        Make sure that this method is called at the beginning of your AppDelegate application:didFinishLaunchingWithOptions: method.

        • Objective-C:

          application:didFinishLaunchingWithOptions:
        • Swift:

          func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
    • Integrate the PingID SDK component into the authentication process.

      • Invoke the generatePayload function on every login attempt.

      • In the login request to the customer server, add a string parameter, for passing the payload from the customer mobile application’s PingID SDK component.

      • In the authentication request, you’ll receive information regarding the result of the PingID SDK multifactor authentication.

Working with push messages in iOS

This section details the steps needed in order to work with push messages in iOS.

  1. Enable Push Notifications: Go to your Project Navigator’s capabilities tab. Select Push Notifications > Enable.
  1. Create the APNs certificates for your test and production environments. Refer to: Local and Remote Notifications Overview.

  2. Upload the APNs certificates to the PingOne admin console under your app settings. Go to Applications > PingID SDK Applications.

    • Verify that push notifications are working with the above certificates before uploading them to the admin console.
  3. Enable PingID SDK to send silent notifications when needed:

    • Go to your Project Navigator’s capabilities tab.
    • Select Background Mode > Enable.
    • Check Remote notifications.
  4. Register Push: In order to receive push notifications from PingID SDK, use the following code in your didRegisterForRemoteNotificationsWithDeviceToken call:

    Language Implementation
    Objective-C + (void)setRemoteNotificationsDeviceToken:(nullable NSData *)deviceToken;
    Swift open class func setRemoteNotificationsDeviceToken(_ deviceToken: NSData?)

    using the actual deviceToken string, without spaces and brackets.

  5. Handling Push Notifications: PingID SDK will only handle push notifications which were issued by the PingID SDK server.

    • Objective-C:

      Inside the following method:

      - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler;

      Call:

      + (BOOL)isRemoteNotificationFromPingID:(nonnull NSDictionary *)userInfo;

      with the userInfo NSDictionary. If the notification is not from PingID SDK, it will not be handled.

      If the push was received from PingID SDK, pass the userInfo to:

      + (void)handleRemoteNotification:(nonnull NSDictionary *)userInfo  
                                   completion:(nullable void(^)(PIDRemoteNotificationType  
           remoteNotificationType, NSArray * _Nullable availableTrustLevels, NSDictionary * _Nullable  
           sessionInfo, NSError * _Nullable error))completionBlock

      and handle the response accordingly.

      Note that the handleRemoteNotification method doesn’t handle didReceiveRemoteNotification:fetchCompletionHandler:, and it should be added to your code.

    • Swift:

      Inside the following method:

      func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)

      Call:

      open class func isRemoteNotification(fromPingID userInfo: [AnyHashable : Any]) -> Bool

      with the userInfo. If the notification is not from PingID SDK, it will not be handled.

      If the push was received from PingID SDK, pass the userInfo to:

      open class func handleRemoteNotification(_ userInfo: [AnyHashable : Any], completion completionBlock: ((PIDRemoteNotificationType, [NSNumber]?, [AnyHashable : Any]?, Error?) -> Swift.Void)? = nil)

      and handle the response accordingly.

      Note that the handleRemoteNotification method doesn’t handle didReceiveRemoteNotification, and it should be added to your code.

  1. Push Notifications Categories: PingID SDK uses categories for different notifications. If your app already uses categories, you will need to retrieve the PingID SDK categories NSMutableSet, by calling:

    Language Implementation
    Objective-C + (nonnull NSMutableSet *)getPingIDRemoteNotificationsCategories;
    Swift open class func getRemoteNotificationsCategories() -> NSMutableSet

    and add that to your current categories.

    • iOS 9:

      Objective-c example:

      // Registering UIUserNotificationSettings more than once results in previous settings being overwritten. PingID provides the needed categories. The developer may add categories.
      
      NSMutableSet *categories = [PingID getPingIDDeprecatedRemoteNotificationsCategories];
       
      UIUserNotificationSettings *settings = [UIUserNotificationSettings
              settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge |
              UIUserNotificationTypeSound categories:categories];
      
      [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
      [[UIApplication sharedApplication] registerForRemoteNotifications];

      Swift example:

      let categories = PingID.getDeprecatedRemoteNotificationsCategories()
      let settings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: categories as? Set<UIUserNotificationCategory>)
      
      UIApplication.shared.registerUserNotificationSettings(settings)
      UIApplication.shared.registerForRemoteNotifications()
    • iOS 10 and up: (UNUserNotification support):

      Objective-c example:

      // Retrieve the PingID SDK categories Set.
         NSMutableSet *categories = [PingID getPingIDRemoteNotificationsCategories];
      // Create the actions for custom category.
         UNNotificationAction* acceptAction = [UNNotificationAction actionWithIdentifier:@"ACCEPT"
                                                  title:@"Approve"
                                                  options:UNNotificationActionOptionForeground];
         UNNotificationAction* cancelAction = [UNNotificationAction actionWithIdentifier:@"CANCEL"
                                                  title:@"Deny"
                                                  options: UNNotificationActionOptionDestructive];
      // Create the category with the custom actions.
         UNNotificationCategory* customCategory = [UNNotificationCategory categoryWithIdentifier:@"CUSTOM_CATEGORY"
                                                  actions:@[acceptAction, cancelAction]
                                                  intentIdentifiers:@[]
                                                  options:UNNotificationCategoryOptionNone];
      //Option 1: Add your custom category to PingID SDK categories Set.
         [categories addObject: customCategory];
         [[UNUserNotificationCenter currentNotificationCenter]setNotificationCategories: categories];
      //Option 2: Merge your current categories Set with PingID SDK categories Set.
         NSMutableSet * customCategories = [NSMutableSet set];
         [customCategories addObject: customCategory];
         [customCategories unionSet: categories];
         [[UNUserNotificationCenter currentNotificationCenter]setNotificationCategories: customCategories];
         [[UIApplication sharedApplication] registerForRemoteNotifications];

      Swift example:

      // Retrieve the PingID SDK categories Set.
         var categories = PingID.getRemoteNotificationsCategories() as! Set<UNNotificationCategory> 
      // Create the actions for custom category.
         let acceptAction = UNNotificationAction(identifier: "ACCEPT",
                                  title: "Approve",
                                  options: .foreground)
         let cancelAction = UNNotificationAction(identifier: "CANCEL",
                                  title: "Deny",
                                  options: .destructive)
      // Create custom category.
         let customCategory = UNNotificationCategory(identifier: "CUSTOM_CATEGORY”,
                                  actions: [acceptAction, cancelAction],
                                  intentIdentifiers: [],
                                  options: UNNotificationCategoryOptions ( rawValue: 0 ))
      //Option 1: Add your custom category to PingID SDK categories Set.
         categories.insert(customCategory)
         UNUserNotificationCenter.current().setNotificationCategories(categories)
      //Option 2: Merge your current categories Set with PingID SDK categories Set.
         let customCategories: Set<UNNotificationCategory> = [customCategory]
         let mergedCategoriesSet = customCategories.union(categories)
         UNUserNotificationCenter.current().setNotificationCategories(mergedCategoriesSet)
         UIApplication.shared.registerForRemoteNotifications()
  2. Cancel Authentication:

    The handleRemoteNotification:completion method provides a mechanism for your application to take action on authentication cancelation events, by returning PIDRemoteNotificationTypeCancel.

  3. Localization: The following keys are returned by the PingID SDK Remote Notification, with suggested localization:

    "notification_confirm" = "Approve";
    "notification_deny" = "Deny";
    "notification.message" = "You have a new authentication request.";
    "notification.title" = "New Authentication";

Keychain Sharing

Make sure that the first item on your Keychain Groups is YOUR_BUNDLE_ID (your private keychain group). This requirement will ensure that the SDK keychain values are private, and are not shared between apps​: