Introduction

Since Herow SDK 5.0, we support Push notification technology (in addition of local notification for geofence) and we can now create mobile engagement campaign on Herow platform to push the right message to the right user thanks to the power of location data & intelligence.

When you launch a push campaign it creates a remote notification sent by our server (Herow Platform) to Apple Push Notification service (APNs). APNs will then deliver it to your application users on their devices.

To ensure a good SDK integration and a smooth development experience, there are a few important steps that you need to read.

Step 1: Configure push notifications

You need to enable push notifications in the Xcode project. Xcode adds the APNs entitlement to your project and the App ID. If necessary, Xcode creates an explicit App ID based on the bundle ID, and for development, an Xcode managed team provisioning profile containing the App ID.

After you enable push notifications, generate and export a TLS certificate.

Enable Push Notifications in your Xcode project

  • In the project editor, choose a target and click Capabilities.
  • In the Push Notifications section, click the switch to turn it from OFF to ON.

Enable Push KEY

Generate and export an APNS client TLS certificate from the Apple developer portal

Generating the certificate fully enables push notifications for the associated App ID. In your developer account, you will notice that the Push Notifications service for the App ID changes automatically from Configurable to Enabled.

  • In your developer account, go to Certificates, Identifiers & Profiles
  • Click the blue Add button (+)
  • In services section, select the “Apple Push Notification service SSL (Sandbox & Production)” checkbox, then click Continue. Enable Push KEY
  • Select the App ID that matches your Bundle ID from the App ID drop down menu, and click Continue.
  • Follow the instructions in “learn more” to create and upload a CSR (Certificate Signing Request) in order to create the new certificate, then click Continue. Enable Push KEY
  • Download your certificate to your Mac, then double click the .cer file to install in Keychain Access.
  • In Keychain access, go to “My Certificates” section, and you will see both a certificate and a private key. Select the key and click right to export in .p12 format.
  • A password will be asked to finally save it on your Mac. Keep in note the password because Herow platform need both the .p12 and the password to be setting-up.

Step 2: Herow Platform configuration

To configure push notifications on your Herow platform, connect to my.herow.io with your login/password, go in your app environnement, then open settings and click on "push credentials". As you can see below, to enable push notification service on iOS, you have to upload your certificate.p12 with password and save it.

Enable Platform KEY

Enable Platform KEY

You can swicth the developer mode to "on" in order to test the push in sandbox environnement (applications on debug).

Step 3: Registering for notifications

In order to register for user notifications, you can call the registerForUserNotificationsWithOptions method. This means that you're no longer required to maintain the registration code by yourself, just call this method and the library will request notification authorization for you with default options

Switch to Swift

HerowInitializer * herowInitializer = [HerowInitializer shared];
[herowInitializer registerForRemoteNotificationsWithAutomaticIntegration:YES];
 let herowInitializer = HerowInitializer.shared
 herowInitializer.registerForRemoteNotifications(automaticIntegration: true)

You can also request specific options thanks to this method

Switch to Swift


[herowInitializer requestNotificationsAuthWithOptions: HerowPushOptionsAlert  | HerowPushOptionsBadge | HerowPushOptionsSound completion:^{
           // whatever you want here
        }];
 herowInitializer.requestNotificationsAuth(options: [.alert,.badge,.sound]) {
            //wathever you want
        }

Note: The default options are alert badge and sound

If you want to test push on development mode (sandbox), you will need to add the following code:

Switch to Swift

#if DEBUG
    [herowInitializer sendPushOnSandBox:YES];
#endif
#if DEBUG
herowInitializer.sendPushOnSandBox(true)
#endif

Multi SDK, Automatic or Manual integration

Option 1: Automatic integration

The simplest way is the automatic integration, but if your application integrates more than one push sdk solution we strongly recommand you to go on the option 2: Manual integration.

Troubleshooting Multiple Push SDKs

While multiple push SDKs can be integrated into a single app, this may cause issues due to conflicts. This section provides some considerations you should keep in mind as you develop your app. Note that this is not an exhaustive list.

1.Registration

Only ONE call to register for push notifications can be made; otherwise, multiple notification banners, alerts, and/or sounds may be triggered in a single push. If you are using the HEROW -SDK registerForRemoteNotificationsWithAutomaticIntegration method, do not use a direct call to [[UIApplication sharedApplication] registerForRemoteNotifications] in your application.

2. Notification Settings

An app can call registerUserNotificationSettings multiple times, but only the last call is used. The settings are overwritten each time it is called.

3. Badging

There is no way to guarantee the value of a badge.

4. Notification Handling

Notification handling in the AppDelegate with multiple SDKs depends on the SDKs used. The notifications may be visually stacked, discarded, or otherwise confused.

5. Custom Payload Keys

Use custom keys or other payload-specific data to ensure that the correct SDK handler is called in an app that supports multiple notification handlers.

6. Method Swizzling

Warning: If a push SDK uses method swizzling (a means of replacing iOS framework code at runtime), the HEROW SDK will not work.

In order to tell if an SDK uses swizzling, look for SDKs that do not use:

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

Some SDKs offer a secondary implementation, which uses standard app delegate methods. If so, you must use the secondary implementation.

7.How Proceed actions when app receive a push notification and you are using Automatic Integration?

HerowPushCenter allows you to define some code when you received a notification

Switch to Swift

 [[[HerowInitializer shared] pushCenter] setNotificationHandler:^(NSDictionary * _Nonnull userInfos)  {
        NSInteger  number = [[UIApplication sharedApplication] applicationIconBadgeNumber];
        [[UIApplication sharedApplication] setApplicationIconBadgeNumber:number + 1];
    }];
 HerowInitializer.shared.pushCenter().setNotificationHandler { (userInfos in
            UIApplication.shared.applicationIconBadgeNumber = UIApplication.shared.applicationIconBadgeNumber + 1
        }

Option 2: Manual integration

Switch to Swift

HerowInitializer * herowInitializer = [HerowInitializer shared];
[herowInitializer registerForRemoteNotificationsWithAutomaticIntegration: NO];
 let herowInitializer = HerowInitializer.shared
 herowInitializer.registerForRemoteNotifications(automaticIntegration: false)

1 Set UNUserNotificationCenter delegate

Switch to Swift

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
 
    // Set up the UNUserNotificationCenter delegate
    [UNUserNotificationCenter currentNotificationCenter].delegate = self;
}
 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
 
    // Set up the UNUserNotificationCenter delegate
    UNUserNotificationCenter.current().delegate = self
}

2 Implement the delegates methods

Switch to Swift

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(nonnull NSData *)deviceToken {
 
    [[[HerowInitializer  shared] pushCenter] didRegisterForUserNotificationsWithDeviceToken:deviceToken];
}
 
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler {
 
    [[[HerowInitializer  shared] pushCenter]  didReceiveRemoteNotification:userInfo];
    completionHandler(UIBackgroundFetchResultNoData);
}
 
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(nonnull NSDictionary *)userInfo completionHandler:(nonnull void (^)())completionHandler {
 
    [[[HerowInitializer  shared] pushCenter]  handleActionWithIdentifier:identifier forRemoteNotification:userInfo];
    completionHandler();
}
 
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(nonnull NSDictionary *)userInfo withResponseInfo:(nonnull NSDictionary *)responseInfo completionHandler:(nonnull void (^)())completionHandler {
 
    [[[HerowInitializer  shared] pushCenter]  handleActionWithIdentifier:identifier forRemoteNotification:userInfo withResponseInfo:responseInfo];
    completionHandler();
}
 
- (void)application:(UIApplication *)application didReceiveLocalNotification:(nonnull UILocalNotification *)notification {
 
    [[[HerowInitializer  shared] pushCenter]  didReceiveLocalNotification:notification];
}
 
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(nonnull UILocalNotification *)notification completionHandler:(nonnull void (^)())completionHandler {
 
    [[[HerowInitializer  shared] pushCenter]  handleActionWithIdentifier:identifier forLocalNotification:notification];
    completionHandler();
}
 
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(nonnull UILocalNotification *)notification withResponseInfo:(nonnull NSDictionary *)responseInfo completionHandler:(nonnull void (^)())completionHandler {
 
    [[[HerowInitializer  shared] pushCenter]  handleActionWithIdentifier:identifier forLocalNotification:notification withResponseInfo:responseInfo];
    completionHandler();
}
 
// UNUserNotificationCenterDelegate methods
 
- (void) userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
 
    completionHandler([[[HerowInitializer  shared] pushCenter]  willPresentNotification:notification]);
}
 
- (void) userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
     
    [[[HerowInitializer  shared] pushCenter]  didReceiveNotificationResponse:response];
    completionHandler();
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
 
     HerowInitializer.shared.pushCenter().didRegisterForUserNotifications(withDeviceToken: deviceToken)
}
     
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
 
     HerowInitializer.shared.pushCenter().didReceiveRemoteNotification(userInfo)
    completionHandler(.noData)
}
     
func application(_ application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [AnyHashable : Any], completionHandler: @escaping () -> Void) {
 
     HerowInitializer.shared.pushCenter().handleAction(withIdentifier: identifier!, forRemoteNotification: userInfo)
    completionHandler()
}
     
func application(_ application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [AnyHashable : Any], withResponseInfo responseInfo: [AnyHashable : Any], completionHandler: @escaping () -> Void) {
 
     HerowInitializer.shared.pushCenter().handleAction(withIdentifier: identifier!, forRemoteNotification: userInfo)
    completionHandler()
}
     
func application(_ application: UIApplication, didReceive notification: UILocalNotification) {
 
     HerowInitializer.shared.pushCenter().didReceive(notification)
}
     
func application(_ application: UIApplication, handleActionWithIdentifier identifier: String?, for notification: UILocalNotification, completionHandler: @escaping () -> Void) {
 
     HerowInitializer.shared.pushCenter().handleAction(withIdentifier: identifier, for: notification)
    completionHandler()
}
     
func application(_ application: UIApplication, handleActionWithIdentifier identifier: String?, for notification: UILocalNotification, withResponseInfo responseInfo: [AnyHashable : Any], completionHandler: @escaping () -> Void) {
 
     HerowInitializer.shared.pushCenter().handleAction(withIdentifier: identifier, for: notification)
    completionHandler()
}
 
// UNUserNotificationCenterDelegate methods
 
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (_ options: UNNotificationPresentationOptions) -> Void) {
 
    completionHandler( HerowInitializer.shared.pushCenter().willPresent(notification))
}
 
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
 
     HerowInitializer.shared.pushCenter().didReceive(response)
    completionHandler()
}

Rich remote notification and Analytics

Media attachments

iOS 10 introduces support for rich notifications, it adds the ability to send push notifications with media attachments such as images, sounds and videos. To enable this functionality, you will need to create a Notification Service Extension. (set the deployment target to iOS 10.0)

Note: Rich notifications are available on iPhone 5s or later, iPad Pro, iPad Air or later, and iPad mini 2 or later.

Enable Push KEY

Warning: YOU NEED TO USE SWIFT LANGUAGE FOR THIS EXTENSION

  • Add a iOS target and choose Notification Service Extension from the list
  • Add a product name and click on finish
  • Activate the target when prompted
  • Add the following lines to your Podfile:
  target 'YOUR_NOTIFICATION_SERVICE_EXTENSION' do
      use_frameworks!
      pod 'HerowNotificationServiceExtension', '~> 1.1.0'
  end

  • Run $ pod update in your project directory
  • Inherit from HerowNotificationServiceExtension in NotificationService and delete all the code generated by XCode.
import HerowNotificationServiceExtension

class NotificationService: HerowNotificationService {
}

Analytics

Our sdk is able to send log analytics to the platform to notify when a remote notification has been received or when it has been opened.

Note that when the user has itself killed the application, the system can't wake up the application, so there is no way to send analytics but we provide a solution: thanks to our application extension, we can then keep and send (when the application restarts due to a location event or opened by the user) the analytic logs to Herow platform. To do this, we need the application and its extension to share the same groupID

  • Go to capabilities in your App target AND your extension target then switch on AppGroups It will ask you to add your Apple ID account that is enrolled in a Developer Program.

Enable Push KEY

  • Add AppGroup by clicking on + button it will ask you to enter group name.

Enable Push KEY

  • you need to pass it to the sdk and to application

In your application

Switch to Swift

[[HerowInitializer shared] setAppGroupNameWithGroupName:@"group.your.app.groupame"];
 HerowInitializer.shared.setAppGroupName(groupName: "group.your.app.groupame")

In your SWIFT extension

import HerowNotificationServiceExtension

class NotificationService: HerowNotificationService {
    public override func getAppGroup() -> String? {
       return "group.connecthings.herow"
    }
}