Overview

Skill Level: Intermediate

This tutorial explains how to configure mobile app messages in iOS apps that are developed with Objective C.

WARNING: When IBM Mobile App Messaging stores data that you send, the data is not encrypted. IBM Mobile App Messaging recommends that you do not transmit sensitive information in inbox, inapp, and mobile app messages. We do not encrypt the data in our databases or log files, or when stored on the device. If you must transmit sensitive information, encrypt the data before sending it and decrypt the data in memory on the device.

Prerequisites

 

To get started, you need:

  • Membership in the iOS Developer Program. ¬†

TIP: If you are not an iOS developer, find out who manages the Apple Developer Program for your organization.

  • An account with Watson Campaign Automation. ¬†

TIP: If you do not already have an Watson Campaign Automation account, contact your Client Services representative or sales.

  • To add your iOS app to Watson Campaign Automation. For instructions, see Adding an app in Watson Campaign Automation.

    RESTRICTION: Watson Campaign Automation documentation contains information for marketers, app developers, and organization administrators and requires a user name and password. If you need a user name and password, contact your Client Services representative.

  • The latest stable version of the IBM Mobile App Messaging SDK for iOS: See https://github.com/ibm-mobile-push/ios.
  • An app that is compliant with Automatic Reference Counting (ARC): To enable ARC in your Xcode project, go to Edit > Convert > To Objective-C ARC and select the project you want to convert.
  • It is possible to use a non-ARC project, as long as the SDK, its plugins and templates are built with ARC turned on. To do so, go to Target > Build Phases > Compile Source, select the MCE files, and add -fobjc-arc to all of them.
  • Information about supported platforms, sample app compatibility and what’s new in the latest version of the¬†IBM Mobile App Messaging SDK for iOS: See Supported platforms and sample app compatibility and What’s new in mobile app messaging.
  • Information about where to find Mobile App Messaging documentation: See¬†Where to find¬†IBM Mobile App Messaging documentation.

 

Remember: Before you begin your development with the IBM Mobile App Messaging SDK for iOS, you must install the iOS development tools and have an iOS provisioning file to develop iOS applications. The following tutorial assumes you are familiar with the iOS development process.

Are you working with Swift?

If you are working with Swift, follow the instructions in Getting started with mobile app messages in iOS apps developed with Swift.

Step-by-step

  1. Build the sample application that is provided in the SDK.

    The IBM Mobile App Messaging SDK for iOS includes a sample application that helps demonstrate end-to-end functions in mobile app messages. You use the sample app included in the SDK to learn how to build a mobile app message and to discover capabilities that are available. For instructions about building the sample application, see Setting up the sample app that is included in the Mobile App Messaging SDK for iOS.

  2. Integrate the IBM Mobile App Messaging SDK with your iOS app.

    RESTRICTION: Before you can implement the IBM Mobile App Messaging SDK for iOS, you must download and extract the latest version of the iOS SDK as described in the Prerequisties.

    To implement the IBM Mobile App Messaging SDK for iOS:

    1. Install the IBM Mobile App Messaging SDK for iOS into your app. You can manually add the IBM Mobile App Messaging framework to your application, or you can add the framework by using the CocoaPods dependency manager.

       

      Manually linking frameworks and libraries
      To manually link frameworks and libraries with your project’s object files and produce a binary file, follow these steps:

      1. Copy IBMMobilePush.framework to your project’s frameworks.
      2. Copy MceConfig.json to your project.
      3. Select the target in the project editor, and copy the following frameworks (including dependencies) to your project in the Linked Frameworks and Libraries section.
        • libz.tbd
        • CoreLocation.framework
        • libsqlite3.0.tbd
        • CoreData.framework
        • CoreTelephony.framework

          (If you see these frameworks in the section, you can skip adding them.)

      4. Add -ObjC to the Other Linker Flags build options.
      5. Set your team in the General tab and the provisioning profile in the Build Settings tab.
        You must set your team and provisioning profile before the app has permission to get the APNs deviceToken.

       

      Using CocoaPods to add the framework
      To add the IBM Mobile App Messaging framework by using the CococaPods dependency manager, follow these steps:

      1. Install CocoaPods and add the pod for the SDK to your podfile.  You can use CocoaPods to integrate the iOS SDK, the NotificationService, and the Watch SDK:
        target 'Application Target Name' do
          pod 'IBMMobilePush', :git => 'https://github.com/ibm-mobile-push/ios.git', :tag => '3.7.1.2.2'
        end
        
        target 'Notification Target Name' do
          pod 'IBMMobilePushNotificationService', :git => 'https://github.com/ibm-mobile-push/ios.git', :tag => '3.7.1.2.2'
        end
        
        target 'watch Extension Target Name' do
          pod 'IBMMobilePushWatch', :git => 'https://github.com/ibm-mobile-push/ios.git', :tag => '3.7.1.2.2'
        end

      2. Set your team in the General tab and the provisioning profile in the Build Settings tab. You must set your team and provisioning profile before the app has permission to get the APNs deviceToken.
      3. For the pod target and the app target, go to the Build Settings tab and set Set Build Active Architectures Only to No for both Debug and Release.
      4. Set Push Notification capability in Target Capabilities.
    2. Configure the MceConfig.json file.

       

      Note: If you want to implement the iOS SDK without using the MceConfig.json file, you can use a NSDictionary object. To use a NSDictionary object, skip the MceConfig.json file configuration that is described in this step, perform the manual integration that is described in step 3, and then modify the application:didFinishLaunchingWithOptions: method in your application delegate. For more information, see Initialize the iOS SDK with a NSDictionary object.

      To configure MceConfig.json, open the file and modify the following fields:

      • baseURL – provide the base URL for your Pod. For more information, see¬†Setting the baseURL.¬†
      • appKey – in the dev and prod fields, provide the development app keys and production app keys that were generated in IBM Watson Campaign Automation. Depending on how the app is compiled, the SDK can choose the correct app key to use. Do not change your app key after you publish your app.
      • appDelegateClass – replace AppDelegate with your AppDelegate class name.
      • loglevel – provide a log level for debugging mode and production mode. For debugging mode, set to verbose and for production mode, set to error. For information, see Setting log level messages types.
      • additional settings for Logging:
        ‚Äď ‚ÄúmaximumSize‚ÄĚ ‚Äď maximum number of bytes for log files before they‚Äôre rotated, default value is 10MB
        ‚Äď ‚ÄúmaximumNumberOfLogFiles‚ÄĚ ‚Äď maximum number of rotated log files, default value is 7¬†

        Note: For information about other properties in the MceConfig.json file, see these topics:

         

        New config flags for iOS MceConfig.json file:

        • databaseEncryption – This flag can be used to disable internal database encryption, this is typically only done for testing so the databases can be read in development. Default value is true.

        Note: If both the internal encrypted sqlite and the OS provided sqlite are linked on the same application, the internal database encryption will fail.

        • databaseKeyRotationDays – This setting can be used to change the frequency of key rotation for database encryption. The default value is 30.

          • allowJailbrokenDevices – This flag can be used to disallow jailbroken devices from being able to register. The default value is true.

        Example of the MceConfig.json

        {
        "baseUrl": "https://sdk.ibm.xtify.com/3.0/",
        "appKey": {
        "dev":"INSERT DEV APPKEY HERE",
        "prod":"INSERT PROD APPKEY HERE"
        },
        "appDelegateClass": "AppDelegate",
        "autoInitialize": true,
        "sessionTimeout": 20,
        "loglevel": "error",
        "logfile": false
        }

    3. Perfom one of the following types of integrations:


      Easy integration
      –¬† The easy integration simplifies communication between the OS and required integration points by replacing the application delegate object with one that processes incoming push message data and forwards all calls back to your application delegate. In most cases, IBM recommends that you perform the easy integration.

      Manual integration РThe manual integration allows for additional control by calling into the MCE SDK at various integration points in your application delegate. Perform a manual integration only in special cases. For example, perform a manual integration if you have another app that needs to be app delegate or if you are using a NSDictionary object to initialize the SDK.  For instructions about performing a manual integration, see Manually integrating the iOS SDK using Objective C.

      To perfom the easy integration, follow these steps:

      1. Replace the AppDelegate class name specification in the main.m file with MCEAppDelegate. If you do additional initialization in the main method, make sure to return the result of UIApplicationMain with MCEAppDelegate when returning from main. MCEAppDelegate is a proxy delegate that forwards the calls to your delegate defined in the configuration. The following code shows before and after samples:
        #Example of code before replacing AppDelegate 

        int main(int argc, char * argv[]) {
        @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
        }
        }

        #Example of code after replacing with MCEAppDelegate

        #import <IBMMobilePush/IBMMobilePush.h>

        int main(int argc, char * argv[]) {int result = 0;
        @autoreleasepool {
        result = UIApplicationMain(argc, argv, nil, NSStringFromClass([MCEAppDelegate class]));
        }
        return result;
        }
      2. Add the following import directive to the top of the AppDelegate:
        @import UserNotifications;
      3. Add the following code to the application: didFinishLaunchingWithOptions: method in your AppDelegate class. This code sets the notification type to badge, sound, and alert. If you do not require all of these notification types, remove it from each declaration for each OS support level.
        - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

        if([UNUserNotificationCenter class]) { [application registerForRemoteNotifications]; // iOS 10+ Example static action category: UNNotificationAction * acceptAction = [UNNotificationAction actionWithIdentifier:@"Accept" title:@"Accept" options:UNNotificationActionOptionForeground]; UNNotificationAction * fooAction = [UNNotificationAction actionWithIdentifier:@"Foo" title:@"Foo" options:UNNotificationActionOptionForeground]; UNNotificationAction * rejectAction = [UNNotificationAction actionWithIdentifier:@"Reject" title:@"Reject" options:UNNotificationActionOptionDestructive]; UNNotificationCategory * category = [UNNotificationCategory categoryWithIdentifier:@"example" actions:@[acceptAction, fooAction, rejectAction] intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction]; NSSet * applicationCategories = [NSSet setWithObject: category]; // iOS 10+ Push Message Registration UNUserNotificationCenter * center = [UNUserNotificationCenter currentNotificationCenter]; NSUInteger options = UNAuthorizationOptionAlert|UNAuthorizationOptionSound|UNAuthorizationOptionBadge|UNAuthorizationOptionCarPlay; [center requestAuthorizationWithOptions: options completionHandler:^(BOOL granted, NSError * _Nullable error) { [center setNotificationCategories: applicationCategories]; }]; } else if ([UIApplication.sharedApplication respondsToSelector:@selector(registerUserNotificationSettings:)]) { // iOS 8+ Example static action category: UIMutableUserNotificationAction * acceptAction = [[UIMutableUserNotificationAction alloc] init]; [acceptAction setIdentifier: @"Accept"]; [acceptAction setTitle: @"Accept"]; [acceptAction setActivationMode: UIUserNotificationActivationModeForeground]; [acceptAction setDestructive: false]; [acceptAction setAuthenticationRequired: false]; UIMutableUserNotificationAction * rejectAction = [[UIMutableUserNotificationAction alloc] init]; [rejectAction setIdentifier: @"Reject"]; [rejectAction setTitle: @"Reject"]; [rejectAction setActivationMode: UIUserNotificationActivationModeBackground]; [rejectAction setDestructive: true]; [rejectAction setAuthenticationRequired: false]; UIMutableUserNotificationCategory * category = [[UIMutableUserNotificationCategory alloc] init]; [category setIdentifier: @"example"]; [category setActions: @[acceptAction, rejectAction] forContext: UIUserNotificationActionContextDefault]; [category setActions: @[acceptAction, rejectAction] forContext: UIUserNotificationActionContextMinimal]; NSSet * applicationCategories = [NSSet setWithObject: category]; // iOS 8+ Push Message Registration UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert categories: applicationCategories]; [UIApplication.sharedApplication registerUserNotificationSettings:settings]; [UIApplication.sharedApplication registerForRemoteNotifications]; } else { // iOS < 8 Push Message Registration #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound; [UIApplication.sharedApplication registerForRemoteNotificationTypes:myTypes]; #pragma GCC diagnostic pop } return TRUE; }

     

  3. Customize mobile app messages by implementing advanced features.

    After you integrate the IBM Mobile App Messaging SDK with your iOS app and have basic mobile app messaging operational, you can customize your build with advanced options. The following tutorials provide end-to-end instructions about implementing mobile app messaging features in your iOS apps:

  4. What to do next…

    After you integrate the IBM Mobile App Messaging SDK with your iOS app, you prepare your iOS app for App Store distribution. For instructions, see Preparing your iOS app for App Store distribution.

    Finally, after developers complete the steps described in this tutorial, marketers use Watson Campaign Automation to create, schedule and send mobile app messages. For more information, see Create, schedule, and send mobile app messages in Watson Campaign Automation.

Expected outcome

This tutorial takes developers through the basic steps for implementing mobile app messaging in iOS apps. For more information about mobile app messaging, see the Documentation.

Go Back to Mobile Application Messaging home page.

 

3 comments on"Getting Started with mobile app messages in iOS apps developed with Objective C"

  1. What is the best way to manage the MceConfig.json file? I have installed the IBMMobilePush CocoaPod, which comes with a config file located in the Resources directory of the pod. Can a copy of the file be stored in our project? We do not store installed pods in our bitbucket repo (only Podfile), plus any time we run pod install for the project, the changes we would make to the MceConfig.json file would be overridden.

    • JoanGriffin April 26, 2018

      Hi Gary,
      You could put the config file in your project, but we’re not sure if it’ll override the one in the CocoaPod or not…so, that’s a good question! Try scripting the replacement of the file in your integration script for the CocoaPod… that would be the most straight forward approach.

Join The Discussion

Your email address will not be published. Required fields are marked *