Integration

Kumulos provides an SDK in the form of framework to ease integration Kumulos Build, Push Notification and Analytics features into your iOS app. This guide provides an overview of setting up the SDK for your project and sample usage.

Integrate SDK components

The Kumulos SDK is an open source project hosted on Github, for ease of use it is linked to from the agency console and can be found at https://github.com/Kumulos/KumulosSdkSwift.

Both Carthage and CocoaPods integration instructions are available in the GitHub repo.

Initialization

To configure the SDK for use you need to initialize it with your app's API credentials, this should be done early in your application startup so that you can start using API methods and features.

import UIKit
import KumulosSDK

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

  var window: UIWindow?

  func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    let builder = KSConfigBuilder(apiKey: "your-api-key", secretKey: "your-secret-key")
    Kumulos.initialize(config: builder.build())

    // Override point for customization after application launch.
    return true
  }
}

Your API Key and Secret Key can be obtained from your App Dashboard in your agency console.

You don't need to initialize Kumulos every time you wish to make an API call. It only needs to be initialized once, after which it will remember the API key and secret key you've given it the first time.

To talk to Kumulos, you need three things:

  • your method title (in lowerCamelCase)
  • a method parameters map (field names are also in lowerCamelCase)
  • some response handler code

Parameters

Parameters are provided as a Dictionary, simply add a key for each parameter your API method expects and pass it as the second parameter to the call method.

Kumulos.call("methodName", parameters: ["param1": "value", "param2": "value2"])
.success {
    (response, operation) in
    print(response.payload)
}

Handling Results

The result of an API call will be returned as a KSResponse object, the response body can be accessed via the payload property.

if let _ = response.payload as? Array<AnyObject > {
    // Handle a select action result
    print("It's an array of objects!")
}

if let _ = response.payload as? UInt {
    // Handle a create/delete/update action result
    print("It's an integer!")
}

Handling data fields

Kumulos stores data fields as base64 encoded data, so if you receive data from Kumulos, you will have to base64 decode it to access the original data. Similarly, when you send data to Kumulos, you should base64 encode it before transport.

Push Notifications

The Kumulos SDK provides push notifications via APNS. To integrate Kumulos Push into your iOS app you have to complete the following steps:

  1. Setup a provisioning profile with push certificates via the Apple Developer Member Center
  2. Configure Push in the Kumulos Agency Console
  3. Register for push notifications from your app

1. Setup APNS

In order to send push notifications to iOS devices with Kumulos, you'll need to create certificates in the Apple Developer Member Center. The steps to complete this are shown in the video guide.

Configuring APNS for iOS with Kumulos

After configuring your project, continue to follow the steps below.

If you are using a combined APNS certificate then the Kumulos SDK will automatically register devices as production / sandbox based on the application release mode, debug will be treated as sandbox.

2. Configure Push in the Kumulos Agency Console

Next you need to enable and configure the Kumulos push service with the certificates you have created

3. Register for Push Notifications

The app notification settings must be set which tells the OS which notification types are being requested, then the OS triggered to prompt the user to allow your app to receive push tokens and get the device token.

The KumulosSDK provides a helper method to configure notification permissions for alert, badge and sound permissions then trigger the prompt with one line.

Kumulos.pushRequestDeviceToken()

The Kumulos SDK will automatically detect iOS 10 vs older versions and register for notifications appropriately.

Now send the returned device token to the Kumulos Push service, the OS will trigger a callback with the device token, depending on the OS version the definition will change slightly. From either you can forward the token to the Kumulos SDK.

iOS 9 and lower

func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
      Kumulos.pushRegister(deviceToken)
}

iOS 10

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {    
    Kumulos.pushRegister(deviceToken)
}

You're done! The App can now receive push notifications from the Kumulos Push service.

Track Push Conversions

When your app receives a push notification, or is launched by tapping on a push notification, your app's delegate will be called back by the OS.

To correctly report on push open rates & conversions, you need to tell Kumulos that the app was launched by the remote notification.

For iOS 9 & 10, this is handled slightly differently. In our example, we show an application delegate that can respond correctly on both iOS 9 & 10.


import UIKit
import KumulosSDK
// Import the framework for iOS10
import UserNotifications

// Add the delegate protocol
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Set up the delegate (for iOS10)
        UNUserNotificationCenter.current().delegate = self;

        return true
    }

    ...

    // iOS9
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        if (UIApplication.shared.applicationState == UIApplicationState.inactive)) {
            Kumulos.pushTrackOpen(notification: userInfo)
        }
        completionHandler(UIBackgroundFetchResult.noData)
    }

    // iOS10
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([])
    }

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


}

This sample shows how to track push open conversions when a user has tapped on a notification and launched the app. However, you may wish to customize when you want to track a push open. In those cases, you can simply call pushTrackOpen as desired and pass in the userInfo object from the notification.

Handling URL Pushes

When you send a URL push with Kumulos, you will need to handle opening the browser from your delegate methods like so:

// iOS9 handler for push notifications
// iOS9+10 handler for background data pushes (content-available)
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    if (UIApplication.shared.applicationState == UIApplicationState.inactive) {
        Kumulos.pushTrackOpen(notification: userInfo)

        if let custom = userInfo["custom"] as? [AnyHashable:Any], let urlStr = custom["u"] as? String {
            if let url = URL.init(string: urlStr) {
                DispatchQueue.main.async {
                    UIApplication.shared.openURL(url)
                }
            }
        }
    }

    completionHandler(UIBackgroundFetchResult.noData)
}

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    let userInfo = response.notification.request.content.userInfo;
    Kumulos.pushTrackOpen(notification: userInfo)

    // Handle opening URL
    if let custom = userInfo["custom"] as? [AnyHashable:Any], let urlStr = custom["u"] as? String {
        if let url = URL.init(string: urlStr) {
            UIApplication.shared.open(url, options: [:], completionHandler: { (_) in
                /* noop */
            })
        }
    }

    completionHandler()
}

Handling Background Data Pushes

When you send a background data push with Kumulos, the content-available flag will be set on the notification.

This will allow your app to be woken up to process the push notification in the background.

Make sure you have enabled the "Remote notifications" background mode in your project's "Capabilities" settings

The background push notification will trigger the application:didReceiveRemoteNotification:fetchCompletionHandler: application delegate:

// iOS9 handler for push notifications
// iOS9+10 handler for background data pushes (content-available)
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        if (UIApplication.shared.applicationState == UIApplicationState.inactive) {
            Kumulos.pushTrackOpen(notification: userInfo)
        }

        if let aps = userInfo["aps"] as? [AnyHashable:Any],
           let custom = userInfo["custom"] as? [AnyHashable:Any] {
            let contentAvailable = aps["content-available"]
            let data = custom["a"]
            // ...
        }

        completionHandler(UIBackgroundFetchResult.noData)
    }

Note if you set a title & message then a notification will be shown to the user. If you want the push to be silent, don't set a title or message when sending.

Push Channels

You can create and manage subscriptions to push notification Channels via the SDK. Channels allow your users to define preferences for the type of content they would like to receive via notifications.

You can manage all channel interactions via the KumulosPushChannels class in the Kumulos SDK.

let pushChannels = KumulosPushChannels(sdkInstance: Kumulos.getInstance())

Helper methods are then available for creating, listing and managing subscriptions to channels.

pushChannels.listChannels()
pushChannels.createChannel(uuid: String, subscribe: Bool, name: String? = nil, meta: [String:AnyObject]? = nil)
pushChannels.subscribe(uuids: [String])
pushChannels.unsubscribe(uuids: [String])
pushChannels.setSubscriptions(uuids: [String])
pushChannels.clearSubscriptions()

Each helper can then be provided a success and failure block to handle the result, for example.

pushChannels.createChannel(uuid: "the-channel-uuid", subscribe: true, name: "channel name", showInPortal: true)
.success{ (item) in
    print("create success")
    print(item)
}
.failure{ (error) in
    print("create failed")
    print(error)
}

Channel visibility and metadata

Channel visiblity and meta data can be controlled when they are created.

Installation ID

When initialized for the first time, the Kumulos SDK will create a unique identifier for the app installation that initialized the SDK.

This identifier can be used to target push notifications to a specific device through KScript or the Push Notifications API.

In order to retrieve this installation ID, simply access the class variable:

let installId = Kumulos.installId;

Once you have the installation ID, you can send it to your app's backend to be used later for push targeting. For more information about push targeting, please see the KScript Documentation or push notification documentation as appropriate.

Location Tracking

You can send Kumulos location updates and use this to trigger events such as push notifications when an install enters a GeoFence.

How you configure the Core Location services for iOS depends on the specific use case of your app. You should consider both accuracy and battery life when making this decision. Refer to the Apple documentation for details of how to configure location services.

Once you have created a CLLocationManagerDelegate you can use the helper method in the Kumulos SDK to send location updates to Kumulos.

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
  let latestLocation: CLLocation = locations[locations.count - 1]
  Kumulos.sendLocationUpdate(location: latestLocation)
}

Crash Reporting

Crash reporting allows you to track unhandled exceptions in your app, and optionally log any caught exceptions for further investigation. Crash reporting is not enabled by default, to enable this feature, simply modify your Kumulos initialization to include enabling crash reporting.

let builder = KSConfigBuilder(apiKey: "your-api-key", secretKey: "your-secret-key").enableCrash()
Kumulos.initialize(config: builder.build())

That's it! Unhandled exceptions that lead to crashes will now be recorded automatically and shown in your App Delivery Console.

Note that crash reporting is not available whilst connected to a debugger, but it does work with debug builds.

If you wish to log any caught exceptions, you can record them with the helper method:

Kumulos.logException(name, reason, language, lineOfCode, stackTrace, logAllThreads);

Ensure that crash reporting is enabled when attempting to log exceptions.

Changelog

2.0.0

  • Add crash reporting
  • Change to builder pattern for SDK configuration

1.4.0

  • Add geolocation update helper method
  • Add locale & bundle to stats payload
  • Fix SDK type in stats payload

1.3.0

  • Add CocoaPods support

1.2.0

  • Add push channel & push subscription management
  • Mark blocks with @discardableResult to tidy up warnings on unused results

1.1.0

  • Swift 3 conversion
  • Add iOS10 push notifications support

1.0.1

  • Fixed issue with push token registration to allow use of combined certificates for push auth

1.0.0

  • Initial release with RPC & Kumulos Push Notification support