Implementação Swift 3.0 (compatível com Swift 4 e 5)

Veja a seguir como é simples a implementação Swift 3.0 da integração com a nossa SDK. Esta implementação é compatível com Swift 4

Para integrar a SDK Inngage ao seu aplicativo desenvolvido em Swift 3.0 siga os passos a seguir.

1. No arquivo **Info.plist** adicione as seguintes chaves **InngageAppToken** e **InngageApiEndpoint**. Onde:

  • InngageAppToken – corresponde ao token de acesso do aplicativo, e pode ser obtido na plataforma **Inngage** em Configurações do App > Aplication ID. *O token de autenticação é único, e varia de acordo com o ambiente.*
  • InngageApiEndpoint – corresponde ao endpoint da nossa API. Ambiente de *produção*: https://api.inngage.com.br/v1

<plist version="1.0">
<dict>
	<key>InngageApiEndpoint</key>
	<string>https://api.inngage.com.br/v1</string>
	<key>InngageAppToken</key>
	<string>seu_app_token_aqui</string>
</dict>
</plist>

🚧

As implementações que veremos a seguir deverão ser feitas no arquivo AppDelegate.swift

2. Adicione a importação da seguinte biblioteca:

import UserNotifications

A classe UserNotifications implementa métodos responsáveis por manipular o envio de notificações locais e remotas.

3. Na declaração da classe AppDelegate adicione a implementação do seguinte protocolo **UNUserNotificationCenterDelegate**.

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

O protocolo UNUserNotificationCenterDelegate implementa métodos responsáveis por tratar o evento de recebimento de notificações quando o seu aplicativo está em primeiro plano.

4. Logo abaixo da declaração da classe AppDelegate, adicione a seguinte variável de instância:

var pushManager: PushNotificationManager!

A variável pushManager é utilizada para chamar as funções implementadas em nossa SDK e sua instanciação utiliza o padrão *Singleton*, padrão este que foi utilizado na arquitetura da nossa SDK.

5. Dentro do corpo da função **application** (existente) que recebe como parâmetro um objeto **didFinishLaunchingWithOptions** adicione a seguinte implementação:

pushManager = PushNotificationManager.sharedInstance()
// iOS 10 support
if #available(iOS 10, *) {
  UNUserNotificationCenter.current().requestAuthorization(
    options:[.badge, .alert, .sound]
  )
  {(granted, error) in}
  application.registerForRemoteNotifications()
  let settings = UIApplication.shared.currentUserNotificationSettings       
  pushManager.handlePushRegister(forRemoteNotifications: settings)
}
// iOS 9 support
else if #available(iOS 9, *) {                            	        		

  UIApplication.shared.registerUserNotificationSettings(
   UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil)
  )
  UIApplication.shared.registerForRemoteNotifications()
  let settings = UIApplication.shared.currentUserNotificationSettings
  pushManager.handlePushRegister(forRemoteNotifications: settings)
}
// iOS 8 support
else if #available(iOS 8, *) {
  UIApplication.shared.registerUserNotificationSettings(
    UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil)
  )
  UIApplication.shared.registerForRemoteNotifications()
  let settings = UIApplication.shared.currentUserNotificationSettings
  pushManager.handlePushRegister(forRemoteNotifications: settings)
}
// iOS 7 support
else {
  application.registerForRemoteNotifications(matching: [.badge, .sound, .alert])
}
return true

6. Adicione na sequência a implementação da seguinte função.

func application(_ application: UIApplication,
            didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
       
	pushManager.handlePushRegistration(deviceToken);
}

A implementação do método de instância didRegisterForRemoteNotificationsWithDeviceToken é responsável por registrar o app no Apple Push Notification service (APNs).

📘

Identificador do Usuário e Campos Customizáveis

Caso o usuário do seu app possua um identificador único ou você necessite passar campos customizáveis que serão utilizados na segmentação de campanhas, a implementação da função mencionada no passo 6 poderá sofrer as seguintes variações:

pushManager.handlePushRegistration(deviceToken, 
																		identifier: "[email protected]");
let jsonBody : [String: Any] = ["Primeiro_Nome" : "Jose",
                                        "Cidade": "São Paulo",
                                        "Estado": "SP"];

pushManager.handlePushRegistration(deviceToken,
                                    identifier: "[email protected]",
                                   customField: jsonBody);

🚧

Lembre-se que, antes de enviar um campo customizável é necessário configurar a plataforma para recebê-lo. Esta configuração pode ser feita em: Configurações do App > Geral > Campos Customizáveis.

7. Adicione na sequência a implementação da seguinte função:

func application(_ application: UIApplication,
                didFailToRegisterForRemoteNotificationsWithError error: Error) {
                
  pushManager.handlePushRegistrationFailure(error);
}

A implementação do método de instância didFailToRegisterForRemoteNotificationsWithError é responsável por tratar algum tipo de falha que possa ocorrer ao registrar o app no Apple Push Notification service (APNs).

8. Adicione na sequência a implementação da função que será responsável por tratar o evento de recebimento da notificação:

func application(_ application: UIApplication,
                     didReceiveRemoteNotification userInfo: [AnyHashable : Any],
                     fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> ()) {
        
  manager.handlePushReceived(userInfo)
}

Rich Push Notifications (Notificações com Imagem, GIF, Audio e Video)

Caso seu app for utilizar o recurso Rich Push Notifications você deve implementar a seguinte função

class NotificationService: UNNotificationServiceExtension {

    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

        if let bestAttemptContent = bestAttemptContent {
            // Modify the notification content here...
            if let userInfo = bestAttemptContent.userInfo as? [String: Any] {

              if let aps = userInfo["aps"] as? [String: Any], let otherCustomUrl = aps["otherCustomURL"] as? String { //Inngage format Image

                	guard let attachmentUrl = URL(string: otherCustomUrl) else {
                        contentHandler(bestAttemptContent)
                        return
                    }

                    guard let imageData = NSData(contentsOf: attachmentUrl) else {
                        contentHandler(bestAttemptContent)
                        return
                    }

                    guard let attachment = UNNotificationAttachment.create(imageFileIdentifier: "image.png", data: imageData, options: nil) else {
                        contentHandler(bestAttemptContent)
                        return
                    }

                    bestAttemptContent.attachments = [ attachment ]
                }

                contentHandler(bestAttemptContent)
            }
        }
    }


    override func serviceExtensionTimeWillExpire() {
        // Called just before the extension will be terminated by the system.
        // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }

}

extension UNNotificationAttachment {

    /// Save the image to disk
    static func create(imageFileIdentifier: String, data: NSData, options: [NSObject : AnyObject]?) -> UNNotificationAttachment? {
        let fileManager = FileManager.default
        let tmpSubFolderName = ProcessInfo.processInfo.globallyUniqueString
        guard let tmpSubFolderURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(tmpSubFolderName, isDirectory: true) else { return nil }

        do {
            try fileManager.createDirectory(at: tmpSubFolderURL, withIntermediateDirectories: true, attributes: nil)
            let fileURL = tmpSubFolderURL.appendingPathComponent(imageFileIdentifier)
            try data.write(to: fileURL, options: [])
            let imageAttachment = try UNNotificationAttachment(identifier: imageFileIdentifier, url: fileURL, options: options)
            return imageAttachment
        } catch let error {
            print("error \(error)")
        }

        return nil
    }

}

Geolocalização

📘

Esta configuração é opcional. Todavia, não adicionar o trecho abaixo impedirá a realização de campanhas de push geolocalizadas.

9. No arquivo Info.plist adicione as seguintes chaves: **NSLocationAlwaysUsageDescription** e **NSLocationWhenInUseUsageDescription**.

<plist version="1.0">
<dict>
  <key>NSLocationAlwaysUsageDescription</key>
  <string>Precisamos de sua localização para lhe enviar uma oferta direcionada</string>
  <key>NSLocationWhenInUseUsageDescription</key>
  <string>Precisamos de sua localização para lhe enviar uma oferta direcionada</string>
</dict>
</plist>

🚧

As implementações abaixo deverão ser feitas no arquivo ViewController.swift

10. Adicione a importação das seguintes bibliotecas:

import CoreLocation
import SystemConfiguration

11. Adicione a seguinte variável de instância dentro do corpo da classe ViewController:

var locationManager: CLLocationManager!

11. Adicione a seguinte implementação no corpo do método **viewDidLoad()**:

override func viewDidLoad() {
  super.viewDidLoad()
  // Do any additional setup after loading the view, typically from a nib.
  locationManager = CLLocationManager()
  locationManager.distanceFilter = kCLDistanceFilterNone
  locationManager.desiredAccuracy = kCLLocationAccuracyBest
  locationManager.startUpdatingLocation()
  locationManager.requestWhenInUseAuthorization()
        
	let pushNotificationManager: PushNotificationManager  =
            PushNotificationManager.sharedInstance()
  pushNotificationManager.handleUpdateLocations(locationManager)
}

📘

Código Fonte

O projeto exemplo utilizado neste guia se encontra disponível em nosso Github.
Fique a vontade para dar um Fork em nosso repositório 😃
https://github.com/inngage/swift3-sample