image


indigitall iOS SDK


Contents

  1. Introduction
    1. Obtaining the Indigitall SDK
    2. Obtaining the App Token of the application
    3. Obtaining the .cer and .p12 of APNS
  2. Integration
    1. Indigitall SDK
    2. Capabilities setting up
    3. Info.plist setting up
    4. Addition of the Notification Service Extension
  3. Use of the library
    1. Library initialization
    2. Push notification permissions
    3. Geofences and geolocalized push
    4. Synchronization with the device registration
    5. Functions available in the library
    6. Push messages
    7. External Apps Service
    8. Get DeviceID
  4. Implementation Updates
    1. Update to 3.3 from older sdk versions
    2. Changes in Location permissions
    3. Changes in AppDelegate file
    4. Add App Group
    5. Option for enable and disable the location
    6. Add register synchronization block
    7. Add possibility to catch the campaign description
  5. F.A.Q
  6. Contact us

1. Introduction

This document provides all the information needed to perform the integration of the Indigitall SDK into an application developed for devices with the iOS operating system. It shows everything you need to know to integrate the SDK into an existing application in order to use the services offered by the indigitall platform.

It is important to review this manual before carrying out the development and follow all the steps indicated in it to ensure the correct functioning of the integration. This document is intended for iOS developers, so a technical language will be used and examples of source code will be shown when necessary.

1.1 Obtaining the Indigitall SDK

The SDK is composed by two components, the .framework and the notification extension.

The SDK can be integrated by two different ways:

Manually

Download the sdk from the following link: Indigitall's SDK for iOS

CocoaPods

The SDK is available from CocoaPods. In order to integrate it, add the following lines in your 'Podfile':

source 'https://bitbucket.org/indigitallfuente/indigitall-ios-specs.git'

platform :ios, '8.0'

target 'MyApp' do
    pod 'Indigitall'
end

If the dependency is not founded try executing the next comand:

pod install --repo-update

Notification Extension

The notification extension is available in the next link: Indigitall's Notification Extension for iOS

Note:

It will be necessary to have the identifier required so that the app, in which you want to integrate the SDK, can communicate with the Indigitall environment. To receive this identifier the developer must provide to indigitall the necessary data to send the notifications (.cer and p12 certificates for notifications) obtained from the Apple Developer Console.

1.2 Obtaining the App Token of the application

Each application registered in the Control Panel of Indigitall will have a unique identifier called the App Token. This identifier will be used to start the SDK and will be responsible for linking the application with the indigitall platform, this way it will indicate to which application the notifications that come to the device belong. The App Token of an application can be obtained from the Control Panel of indigitall by an admin user in the section "Details" of the application.

1.3 Obtaining the .cer and .p12 of APNS

To send push notifications to iOS devices, it is necessary to have some certificates that allow APNS (Apple Push Notification Service) communication.

For this you will have to generate the corresponding certificates (.cer, .p12 and password if you have them) and send them to indigitall.

The following tutorial explains how to get these certificates. How to obtain the “.cer”and “.p12”from APNS.

2. Integration

2.1 Indigitall SDK

SDK Manually

Imported directly the file 'Indigitall.framework' into the project root directory. Also, add the framework in the 'Embedded Frameworks' section in the target general tab.

SDK CocoaPods

Once included the lines described in Point 1.1 execute the command 'pod install' from the terminal in the project path. Once the command execute, as CocoaPods indicates, close the 'MyApp'.xcodeproj and open 'MyApp'.xcworkspace.

2.2 Capabilities setting up

You must activate the Push Notifications and Background Modes Capabilities, in which Location updates and Remote notifications will be selected.

image

The capability App Groups also must be enabled and inside this capability, the group "group.net.MyApp" that must have been previously created in the Apple console for the app, must be selected. This capability should be configured by the next way:

image

2.3 Info.plist setting up

The next step is to set up the project's Info.plist file. It will establish the following keys:

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <false/>
        <key>NSExceptionDomains</key>
        <dict>
            <key>indigitall.net</key>
            <dict>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
                <true/>
                <key>NSTemporaryExceptionMinimumTLSVersion</key>
                <string>TLSv1.1</string>
            </dict>
        </dict>
    </dict>

2.4 Addition of the Notification Service Extension

From iOS 10 the options and control of the notifications are improved. To make use of these improvements it is necessary to include a new TARGET in the project called Notification Service Extension.

image

When you add it, you must set up some data such as the Product Name, Bundle Identifier or Language, setting the latter to ObjectiveC, as it is shown in the next image:

image

In the NSE configuration is neccesary that the Deployment Target field is set to 10 in the Deployment Info section. This configuration set the minimum version of O.S. that is supported:

image

The capability App Groups also must be enabled for the Notification Service Extension and inside this capability, the group "group.net.MyApp" that had been created in the Apple console, must be selected.

After create the NSE is neccesary to replace the .m and .h files that are created default by the NotificationService.h and NotificationService.m files. These files are found in the .zip file that was downloaded in the point 1.1 of the documentation.

This group must be set in the NSE code, in the file NotificationService.m in the next variable:

      NSString *const groupName       = @"group.net.MyApp";

It is important to mention that, to include this extension, you must use Xcode 8.1 or higher and you will have to set up the version of the Deployment Target of the extension to 10.0 as a minimum, as this extension only runs for iOS 10 or higher.

3. Use of the Library

In order to use the library, either if the integration has been done manually o throught CocoaPods, it is neccesary import the library in the header of every class where the library is going to be invoked.

Objective-c

#import <Indigitall/Indigitall.h>

Swift To integrate the library in the Swift project is neccesary to create a bridge file that allows the compatibility with Objective-C:

  1. If your app has the bridge file:

    • Add the next code:

      #import <Indigitall/Indigitall.h>
      #import <UserNotifications/UserNotifications.h>
      #import "NotificationService.h"
  2. If your app has not the bridge file:

    • Create the bridge file that is header type .h called Objective-Bridge-Swift.h

    • Add the next code in the file:

      #import <Indigitall/Indigitall.h>
      #import <UserNotifications/UserNotifications.h>
      #import "NotificationService.h"
    • Link the file to work as bridge: Select the TARGET of the app and go to "Build Settings" section. After that go to "Swift Compiler-General" part and set the next configutation:

      image

3.1 Library initialization

The initialization of the indigitall library is made in the AppDelegate method didFinishLaunching. The method requires the 'APP_TOKEN' key provided by Indigitall and indicate if the third party apps support is available.



 - (BOOL)application:(UIApplication * )application didFinishLaunchingWithOptions:(NSDictionary * )launchOptions {

     [[IndigitallLib sharedInstance] setGroupName: @"group.net.MyApp"];
     [[IndigitallLib sharedInstance] initializeWithAppToken:@"APP_TOKEN" thirdPartyApps:NO];
     [IndigitallLib sharedInstance].delegate = self;

     return YES;
 }
       


  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

      IndigitallLib.sharedInstance().setGroupName("group.net.indigitall")
      IndigitallLib.sharedInstance().initialize(withAppToken:"APP_TOKEN", thirdPartyApps:false)
      IndigitallLib.sharedInstance().delegate = self
      return true
  }
      

3.2 Push notification permissions

Once initialized de library, if the app has not request it previously, the library will ask the user for the notification permission.

For the correct management of the notification the following code is required in the AppDelegate:



       #import <UserNotifications/UserNotifications.h>
       @import Indigitall;

       @interface AppDelegate () <UNUserNotificationCenterDelegate,IndigitallDelegate>

       @end

       @implementation AppDelegate

       // MARK: - Push Notifications
       - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

          //Ask for location permission
          CLLocationManager *locationManager = [CLLocationManager new];
          if ([locationManager respondsToSelector:@selector (requestAlwaysAuthorization)]) {
              [locationManager requestAlwaysAuthorization];
          }

          UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
          center.delegate = self;

       }

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

       - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
          [[IndigitallLib sharedInstance] didFailToRegisterForRemoteNotificationsWithError:error];
       }

       - (void)application:(UIApplication *)application handleActionWithIdentifier: (NSString *)identifier forRemoteNotification:(NSDictionary *)notification completionHandler:(void(^)())completionHandler {
          // Check if the push notification comes from Indigitall
          INPushNotification *indigitallPush = [[INPushNotification alloc] initWithDictionary: notification];
          if (indigitallPush) {
              [[IndigitallLib sharedInstance] handleActionWithIdentifier:identifier forRemoteNotification:notification completionHandler:completionHandler];
          }else {
              // This push not comes from Indigitall
          }
       }

       - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {

          // Check if the push notification comes from Indigitall
          INPushNotification *indigitallPush = [[INPushNotification alloc] initWithDictionary: userInfo];
          if (indigitallPush) {
              [[IndigitallLib sharedInstance] didReceiveRemoteNotification:notification];
          }else {
              // This push not comes from Indigitall
          }
       }

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

          // Check if the push notification comes from Indigitall
          INPushNotification *indigitallPush = [[INPushNotification alloc] initWithDictionary: notification];
          if (indigitallPush) {
              [[IndigitallLib sharedInstance] didReceiveRemoteNotification:notification];
          }else {
              // This push not comes from Indigitall
          }
          completionHandler( UIBackgroundFetchResultNewData );
       }

       - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
          NSLog( @"Handle push from foreground" );

          // Check if the push notification comes from Indigitall
          INPushNotification *indigitallPush = [[INPushNotification alloc] initWithDictionary: notification.request.content.userInfo];
          if (indigitallPush) {
              [[IndigitallLib sharedInstance] didReceiveRemoteNotification:notification];
          }else {
              // This push not comes from Indigitall
          }
       }

       - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
          NSLog( @"Handle push from background or closed" );
          INPushNotification *indigitallPush = [[INPushNotification alloc] initWithDictionary: response.notification.request.content.userInfo];
          if (indigitallPush) {
              [[IndigitallLib sharedInstance] handleActionWithIdentifier:response.actionIdentifier forRemoteNotification:response.notification.request.content.userInfo completionHandler:completionHandler];
          }else {
              // This push not comes from Indigitall
          }
       }

       -(void)manageINPushNotification:(INPushNotification *)notification{

          //Do something

       }

       


    import UIKit

    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate, IndigitallDelegate, UNUserNotificationCenterDelegate {

       var window: UIWindow?

       func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

           IndigitallLib.sharedInstance().setGroupName("group.net.indigitall")
           IndigitallLib.sharedInstance().initialize(withAppToken:"APP_TOKEN", thirdPartyApps:false)
           IndigitallLib.sharedInstance().delegate = self
           return true
       }

       func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
           IndigitallLib.sharedInstance().didRegisterForRemoteNotifications(withDeviceToken: deviceToken)
       }

       func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
           IndigitallLib.sharedInstance().didFailToRegisterForRemoteNotificationsWithError(error)
       }

       func application(_ application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [AnyHashable : Any], completionHandler: @escaping () -> Void) {
           if (INPushNotification.init(dictionary: userInfo) != nil) {
               IndigitallLib.sharedInstance().handleAction(withIdentifier: identifier, forRemoteNotification: userInfo, completionHandler: completionHandler)
           }else {
               // This push not comes from Indigitall
           }
       }

       func application(_ application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [AnyHashable : Any], withResponseInfo responseInfo: [AnyHashable : Any], completionHandler: @escaping () -> Void) {
           if (INPushNotification.init(dictionary: userInfo) != nil) {
               IndigitallLib.sharedInstance().handleAction(withIdentifier: identifier, forRemoteNotification: userInfo, completionHandler: completionHandler)
           }else {
               // This push not comes from Indigitall
           }
       }

       func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
           if (INPushNotification.init(dictionary: userInfo) != nil) {
               IndigitallLib.sharedInstance().didReceiveRemoteNotification(userInfo)
           }else {
               // This push not comes from Indigitall
           }
           completionHandler(UIBackgroundFetchResult.newData)
       }

       func userNotificationCenter (_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void){
           print("Handle push from foreground")
           if ((INPushNotification.init(dictionary: notification.request.content.userInfo)) != nil){
               IndigitallLib.sharedInstance().didReceiveRemoteNotification(notification.request.content.userInfo)
           }else {
               // This push not comes from Indigitall
           }
       }

       func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
            print("Handle push from background or closed")
           if((INPushNotification.init(dictionary: response.notification.request.content.userInfo)) != nil){
               IndigitallLib.sharedInstance().handleAction(withIdentifier: response.actionIdentifier, forRemoteNotification: response.notification.request.content.userInfo, completionHandler: completionHandler)
           }else {
               // This push not comes from Indigitall
           }
       }

       func manage(_ notification: INPushNotification!) {
           // TODO something

       }

          

3.3 Geofences and geolocalized push

In order to have access to geofences and geolocalized push is mandatory that the app has the localization permission granted by the user.

The app needs to have included in its 'Info.plist' the keys related to the location permissions.

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Can we use your location always?</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Can we use your location always?</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Can we use your location when you use the app?</string>

The message associated to the keys NSLocationAlwaysAndWhenInUseUsageDescription, NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescription can be customized.

To ask the user for the permission there are two different methods available.



       #import <CoreLocation/CoreLocation.h>

       //Ask allways location permission
       CLLocationManager *locationManager = [CLLocationManager new];
       if ([locationManager respondsToSelector:@selector (requestAlwaysAuthorization)]) {
           [locationManager requestAlwaysAuthorization];
       }

       //Ask when in use location permission
       CLLocationManager *locationManager = [CLLocationManager new];
       if ([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
               [locationManager requestWhenInUseAuthorization];
           }

       


       import CoreLocation

       //Ask for location permission
       let locationManager = CLLocationManager()
       if(CLLocationManager.authorizationStatus() == .authorizedAlways){
           locationManager.requestAlwaysAuthorization()
       }

       //Ask when in use location permission
       let locationManager = CLLocationManager()
       if(CLLocationManager.authorizationStatus() == .authorizedWhenInUse){
           locationManager.requestWhenInUseAuthorization()
       }

      

3.4 Synchronization with the device registration

Indigitall provides the function called didRegisterForRemoteNotificationsWithDeviceToken that has a handler like parameter. This handler allows to know when the registration has been completed, to avoid possible conflicts.



    - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{

        [[IndigitallLib sharedInstance] didRegisterForRemoteNotificationsWithDeviceToken:deviceToken completionHandler:^(BOOL registerSuccess, NSError *error){
            if(error){
                NSLog(@"ERROR: %@d " , error.localizedDescription);

            }else{
              if(registerSuccess){
                 NSLog(@"OnReady to receive push!!");
               }
            }

            }];
        }
       


       func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

           IndigitallLib.sharedInstance().didRegisterForRemoteNotifications(withDeviceToken: deviceToken, handler:{(registerSuccess, error) in

               if (error) {
                    print("ERROR: %@d " , error.localizedDescription);
               }else {
                 if(registerSuccess){
                   print("OnReady to receive push!!");
                 }
               }
           })
       }

      

3.5 Functions available in the library

Indigitall provides different methods for applications that make use of the library. These methods offer features ranging from subscribing and managing Tags to operations to enable or disable the device.

There are some properties with info related to de SDK and the device.



       NSString *deviceId = [IndigitallLib getDeviceID];
       NSString *lVersion = [IndigitallLib getIndigitallSDKVersion];

       


       var deviceId = IndigitallLib.getDeviceID()
       var lVersion = IndigitallLib.getIndigitallSDKVersion()

      

The properties:

  • deviceId: Is the identifier of the device.
  • lVersion: Is the SDK version.

The methods for the device management are:

Methods to manage the NOTIFICATION RECEIVING



       //Allows enable the notifications reception in the device.
       - (IBAction)enableDevice:(id)sender {
           [[IndigitallLib sharedInstance] enableDeviceWithHandler:^(NSError *error) {
               if (error == nil) {
                   NSLog(@"The device is enabled correctly");
               }else {
                   NSLog(@"Error is happened enabling the device");
               }
           }];
       }
       //Allows disable the notifications reception in the device.
       - (IBAction)disableDevice:(id)sender {
           [[IndigitallLib sharedInstance] disableDeviceWithHandler:^(NSError *error) {
               if (error == nil) {
                   NSLog(@"The device is disabled correctly");
               }else {
                   NSLog(@"Error is happened disabling the device");
               }
           }];
       }
       //Allows know if the notifications reception is enable or disable in the device.
       - (IBAction)checkStatus:(id)sender {
           [[IndigitallLib sharedInstance] checkDeviceStatusWithHandler:^(BOOL enabled, NSError *error) {
               if (error == nil) {
                   if (enabled) {
                       NSLog(@"The device is enabled.");
                   }else {
                       NSLog(@"The device is disabled.");
                   }

               }else {
                   NSLog(@"Error: %@", error.localizedDescription);
               }
           }];
       }

       


    //Allows enable the notifications reception in the device.
        func enableDevice(sender:Any){
            IndigitallLib.sharedInstance().enableDevice(handler:{ (error) in
                if (error == nil) {
                    print("The device is enabled correctly");
                }else {
                    print("Error is happened enabling the device");
                }
            })
        }

    //Allows disable the notifications reception in the device.
      func disableDevice(sender:Any){
          IndigitallLib.sharedInstance().disableDevice (handler:{(error) in
              if(error == nil){
                  print("The device is disabled correctly")
              }else{
                  print("Error is happened disabling the device")
              }
          })
      }

    //Allows know if the notifications reception is enable or disable in the device.
      func checkstatus (sender:Any){
          IndigitallLib.sharedInstance().checkDeviceStatus(handler: {(enabled, error) in
              if(error == nil){
                  if(enabled){
                      print("The device is enabled")
                  }else{
                      print("The device is disabled")
                  }
              }else{
                  print("Error: %@", error?.localizedDescription ?? "Unknown error")
              }
          })
      }

      

Methods to manage the LOCATION

The next methods allow to control the location in the device. To use them is necessary that the library has been initialized before.



       //Allow to check if the location shipping is enabled or disabled in the device.
       - (BOOL) checkLocationStatus{
          return [[IndigitallLib sharedInstance] checklocationStatus];
       }

       //Allow to enable the location shipping of the device.
       - (void) enableLocation{
         [[IndigitallLib sharedInstance] enableLocation];
       }
       //Allow to disable the location shipping of the device.
       - (void) disableLocation{
         [[IndigitallLib sharedInstance] disableLocation];
       }

       


       //Allow to check if the location shipping is enabled or disabled in the device.
       func checkLocationStatus() -> Bool{
           return IndigitallLib.sharedInstance().checkLocationStatus()
       }

       //Allow to enable the location shipping of the device.
       func enableLocation (){
           IndigitallLib.sharedInstance().enableLocation()
       }

       //Allow to disable the location shipping of the device.
       func disableLocation(){
           IndigitallLib.sharedInstance().disableLocation()
       }

      

Methods to manage the TAGS

Tags must be previously created in the panel to be able to list, subscribe or unsubscribe from them.



       //Allows list all tags that are defined in the panel
       - (void) loadTags {
           [[IndigitallLib sharedInstance] tagsListWithHandler:^(NSArray *tags, NSError *error) {
               if (error == nil) {
                   tagsList = tags;
                   [self loadSubscribedTags];
               }else {
                   NSLog(@"Error obtaining all Panel tags.");
               }
           }];
       }
       //Allows list the tags to which the device is subscribed.
       - (void) loadSubscribedTags {
           [[IndigitallLib sharedInstance] tagsSubscriptionsWithHandler:^(NSArray *tags, NSError *error) {
               if (error == nil) {
                   for (INTag *tag in tags) {
                       for (INTag *currentTag in tagsList) {
                           if ([tag.tagId isEqualToString: currentTag.tagId]) {
                               currentTag.selected = YES;
                           }
                       }
                   }
                   [self.tableView reloadData];
               }else {
                   NSLog(@"Error obtaining the tags of the device.");
               }
           }];
       }
       //Allows subscribe or unsubscribe the device to a tag.
       - (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

           INTag *tag = [tagsList objectAtIndex:indexPath.row];
           if (tag.selected) {
               [[IndigitallLib sharedInstance] tagsUnsubscribeFromTags:[[NSArray alloc] initWithObjects:tag.tagId, nil] completionHandler:^(NSError *error) {
                   if (error == nil) {
                       tag.selected = NO;
                       [self.tableView reloadData];
                   }else {
                       NSLog(@"Error unsubscring the tag.");
                   }
               }];

           }else {
               [[IndigitallLib sharedInstance] tagsSubscribeToTags:[[NSArray alloc] initWithObjects:tag.tagId, nil]  completionHandler:^(NSError *error) {
                   if (error == nil) {
                       tag.selected = YES;
                       [self.tableView reloadData];
                   }else {
                       NSLog(@"Error subscring the tag.");
                   }
               }];
           }
       }

       


   //Allows list all tags that are defined in the panel
      func loadTags(){
         IndigitallLib.sharedInstance().tagsList( handler:{(tags, error) in
             if (error == nil) {
                 print("Panel tags obtained with success.")
             }else {
                 print("Error obtaining all Panel tags.")
             }
         })
      }

   //Allows list the tags to which the device is subscribed.
      func loadSubscribedTags(){
         IndigitallLib.sharedInstance().tagsSubscriptions (handler:{(tags, error) in
             if (error == nil) {
                 print("Device tags obtained with success.")
             }else{
                 print("Error obtaining the tags of the device.")
             }
         })

     }

   //Allows subscribe the device to a tag.
    func subscribe(tags: NSArray){
        IndigitallLib.sharedInstance().tagsSubscribe(toTags: tags as! [Any], completionHandler:{(error) in
            if (error == nil) {
                print("Device subscribed with success.")

            }else {
                print("Error subscribing the tag.")
            }
        })
    }

    //Allows unsubscribe the device to a tag.
    func unsubscribe(tags: NSArray){
        IndigitallLib.sharedInstance().tagsUnsubscribe(fromTags: tags as! [Any],completionHandler:{(error) in
            if (error == nil) {
                print("Error unsubscring the tag.")

            }else {
                print("Error subscribing the tag.")
            }
        })
    }
      

3.6 Push messages

Once we have completed the registration and initialization process, the application is ready to receive push messages, the library will handle the messages and display the appropriate notifications. The application will be able to collect the data of the push messages when notifications type "Open App" are sent.

If the object of type INPushNotification is created and the notification comes from Indigitall the properties of the message are:

NSNumber *type; //Notification type
NSNumber *subtype; //Notification subtype
NSString *message_id; //Identifier of the message
NSString *appToken; //App Token of the application
NSString *title; //Notification title
NSString *body; // Notification body
NSString *iconURL; // Notification icon
NSString *imageURL; //Notification image
NSString *data;//Data sent into the push
NSString *descCampaign;//Campaign of the push
NSString *action;// Action asociated to the push
BOOL destructive;//Flag that indicates the push has been discart
NSArray *tagsToSubscribe; //Tags applied in the message creation
NSArray *buttons; //Notification buttons
BOOL launch;//Flag that indicates the push has been shown
NSString *urlButton1; //Url asociated to the button 1
NSString *urlButton2; //Url asociated to the button 2

The way to collect this data is in the AppDelegate in the different methods where a notification could be received:



   INPushNotification *indigitallPush = [[INPushNotification alloc] initWithDictionary: notification];

       


    var indigitallPush = INPushNotification.init(dictionary:notification)

      

3.7 External Apps Service

The External Apps service allows send notifications depending on the user has or has not installed one or more than one applications. The applications that want to be checked, must be specified in the panel.

For can use the service externalApps is necessary make the next changes in the *-Info.plist file:

  • For initialize the library, put the field thirdPartyApps a YES. The initialization should be configurated by the next way:


 - (BOOL)application:(UIApplication * )application didFinishLaunchingWithOptions:(NSDictionary * )launchOptions {

     [[IndigitallLib sharedInstance] setGroupName: @"group.net.MyApp"];
     [[IndigitallLib sharedInstance] initializeWithAppToken:@"APP_TOKEN" thirdPartyApps:YES];
     [IndigitallLib sharedInstance].delegate = self;

     return YES;
 }
       


  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

      IndigitallLib.sharedInstance().setGroupName("group.net.indigitall")
      IndigitallLib.sharedInstance().initialize(withAppToken:"APP_TOKEN", thirdPartyApps:true)
      IndigitallLib.sharedInstance().delegate = self
      return true
  }
      
  • In the *-Info.plist file: Add a new Array key LSApplicationQueriesSchemes whose items must be strings with the URL Scheme of the application that want to be checked in the service. With the array, we indicate the applications that we desire the user has installed to send him the pushes.

The *Info.plist file should be configured by the next way if we want to check the Facebook application like externalApp:

  ...
  <key>LSApplicationQueriesSchemes</key>
  <array>
    <string>fb</string>
  </array>
  ...
  • Have defined in the panel, the URL Scheme of the app that want to be checked.

3.8 Get DeviceID

When we talk about DeviceID, we refer to the unique identifier that the indigitall library generates to identify the device and send them push messages. This example indicates how to collect this data in order to work with it.



       NSString * deviceID = [IndigitallLib getDeviceID];
       [self sendToYourBackend:deviceID];

       


       var deviceID = IndigitallLib.getDeviceID()
       self.sendToYourBackend(deviceID)

      

4. Implementation updates

4.1 Update to 3.3 from older sdk versions.

For update the SDK to version 3.3:

  • Download the new version like is indicated in the point 1.1 of the documentation: Obtaining the Indigitall SDK

  • Add the SDK to the project like is indicated in the point 2.1 of the documentation: Indigitall SDK

4.2 Changes in Location permissions

For give support to geolocated pushes in IOS11 is necessary add the key "Privacy - Location Always and When In Use Usage Description" in the *-Info.plist file. For configure the previous file follow the steps indicates in the point 3.3 of the documentation: Geofences and geolocalized push

4.3 Changes in AppDelegate file

For can receive the notifications when the application is in the first plane, is necessary make several changes in the AppDelegate.m file:

  • Make that the AppDelegate implements the delegate of indigitall, IndigitallDelegate:


    AppDelegate () <UNUserNotificationCenterDelegate, IndigitallDelegat>

       


    class AppDelegate: UIResponder, UIApplicationDelegate, IndigitallDelegate, UNUserNotificationCenterDelegate {

      
  • Assign the IndigitallDelegate after the library initialization:


   - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
        ...
        [[IndigitallLib sharedInstance] initializeWithAppToken:@"APP_TOKEN" thirdPartyApps:NO];
        [IndigitallLib sharedInstance].delegate = self;
        ...
     }

     


   func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

      ...
       IndigitallLib.sharedInstance().initialize(withAppToken:"APP_TOKEN", thirdPartyApps:false)
       IndigitallLib.sharedInstance().delegate = self
       ...
   }

    
  • Add the method that manage the notifications and overwrite it. In this method must be configured the actions that want to be realized when a notification of type 'Open App' is received:


       -(void)manageINPushNotification:(INPushNotification *)notification{

           //Do something

       }

       


       func manage(_ notification: INPushNotification!) {

         //Do something

       }

      

4.4 Add App Group

In this SDK version, several changes are introduced for a better tracing of notifications sending and receiving and so a better statistics support. This changes affect to NSE and Capabilities of the app.

  1. Changes in the app Capabilities:

    • Create a "App Group" for the application in the Apple console. This group should be like the next: "group.net.MyApp".

    • Activate the "App Group" in the app Capabilites and select the group created in the previous step.

    Note: The app Capabilities must be configured as it is indicated in the point 2.2 of the documentation: Capabilities setting up

  2. Changes in the NSE:

    • Add the "App Group", created in the Apple console, to the Capabilities of the NSE.

    • Set the group in the variable groupName in the file NotificationService.m.

    Note: The NSE must be configured as it is indicated in the point 2.4 of the documentation:Addition of the Notification Service Extension

  3. Changes in the initialization of the library:

    • The App Group has to be set through the setGroupName method before the library initialization, as it is indicated follows:


       - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

           [[IndigitallLib sharedInstance] setGroupName: @"group.net.MyApp"];
           ...

           return YES;
       }

       


       func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        IndigitallLib.sharedInstance().setGroupName("group.net.indigitall")
        ...

        return true;
        }

      

The initialization of the library has to be done as is indicated in the point 3.1 of the documentation:Library initialization

4.5 Option for enable and disable the location

En esta versión se ha añadido la opción de activar/desactivar el envío de localización del dispositivo. Para ello se han creado tres métodos:

  • To check if the location is enabled or disabled:


         (BOOL) checkLocationStatus()

       


          func checkLocationStatus()-> Bool

      
  • To enable the location:


        (void) enableLocation()

       


        func enableLocation()

      
  • To disable the location:


         (void) disableLocation()

       


        func disableLocation()

      

IMPORTANT NOTE: For use these three methods is necessary that the library has been initialized before.

All information regarding these methods are available in the point 3.4 of the documentation: Functions available in the library

4.6 Add register synchronization block

A function with a handler as input parameter has been added to the library. This handler is executed when the device has been registered in our systems. By this way, the user has a secured point, in which can make requests.

To see how implement this functionality, the user must consult the point 3.4 of the documentation:Synchronization with the device registration

4.7 Add possibility to catch the campaign description

The possibility to catch the campaign description of the sent push is added. In the next example we can see the way to catch this parameter from the AppDelegate's function that manage the notifications of type Open App:


         -(void)manageINPushNotification:(INPushNotification *)notification{

           NSString* descCampaign = notification.descCampaign;
        }

         

        func manage(_ notification: INPushNotification!) {

          NSString* descCampaign = notification.descCampaign;
        }
        

All push parameters are specified in the point 3.6 of the documentation: Push messages

5. F.A.Q

  • Q: There are no notifications, what can I do?
  • A: Look in the logs for the following message "Device Token: {identifier}". If you receive this message is because the notification log is being performed correctly. If you still do not receive notifications, check the "Token App" and check that they are correct. You should also check that the certificates sent to the indigitall device are correct.

  • Q: What iOS versions are supported by indigitall?
  • A: The indigitall library is compiled with deploymentTarget 6, so the minimum version supported is iOS 6, although you will not receive photos in versions below iOS 10 and will not receive interactive in versions below iOS 8.

  • Q: The image comes small, is there any way to fix this?
  • A: Photo notifications in iOS 10 are shown as a small square down the right on devices prior to iPhone 6. Instead for iPhone 6 and later the image can be seen in large giving the option "See" or with a deep pulse if the device has 3D Touch.

  • Q: I cannot get Geolocalised notifications, how can I fix it?
  • A: Check that you have geolocation enabled on the device and the granted permissions. Open the app and look for the logs corresponding to "INDIGITALL_LOCATION", in them you can see how the location changes and if it is significant. We mean significant changes in location when the device moves more than 500 m (Apple indicates that this is a significant distance) from the last known position.

  • Q: Is it mandatory for me to request location permissions to my users?
  • A: The location permission is optional; you can exclude them from the application manifest. In these cases some functionality related to these permissions are lost, such as Geolocation notifications and Geofencing or Click to Call notifications.

  • Q: My notifications are not positioned first, How can I do it?
  • A: IOS notifications are managed by the Operating System; therefore, you cannot prioritize them. In this way, the notification that arrives last will be the one that appears above in the list of notifications.

  • Q: How do I perform tests in development without affecting production users?
  • A: The "App Token" of the development application and the production application are different; this is to avoid production users from getting notifications created in development. For this reason the tests carried out in development have no risk. Even so, you can always filter in the indigitall panel by DeviceID by creating and uploading a .csv containing the identifiers of the devices to which you want the notification to each.

  • Q: How do I carry out test in production without affecting users?
  • A: The production tests are very sensitive; making a mistake here can cause our notification to reach real users. Therefore, we advise you that at the time of doing tests in production, you make Geolocalised sends or to be filtered by DeviceID as explained in the previous case.

6. Contact us

In indigitall, we are delighted to help you with any problem or question that may come up with the use of our solution. To contact use you can write us at soporte@indigitall.net and we will gladly get in contact with you as soon as possible.