APNs (Apple Push Notification services)

Before integrating APNs with Fyno, you will need to have the below prerequisites in place:

  1. Fyno Account
  2. Fyno App ID, available in Settings > Keys & IDs
  3. iOS 13+ or iPadOS 13+ device (iPhone, iPad, iPod Touch) for testing. Xcode 14+ simulator running iOS 16+ also works.
  4. Mac with Xcode 12+
  5. p8 Authentication Token
  6. Your Xcode Project Should can target any Apple Device excluding the Mac

Setup of Account

Step 1: Add a Notification Service Extension

The FynoNotificationServiceExtension enables your iOS app to receive rich notifications with images, buttons, badges, and other features. It is also essential for Fyno's analytics capabilities.

  1. In Xcode, select File > New > Target...
  2. Choose Notification Service Extension, then press Next.

  1. Enter the product name as FynoNotificationServiceExtension and press Finish.

  1. Do not Select Activate on the ensuing dialog.
  1. Press Cancel on the Activate scheme prompt. This step keeps Xcode debugging your app, rather than the extension you just created. If you accidentally activated it, you could switch back to debug your app within Xcode (next to the play button).

  1. In the project navigator, select the top-level project directory and pick the FynoNotificationServiceExtension target in the project and targets list.
  2. Ensure the Deployment Target is the same value as your Main Application Target. It should be set to at least iOS 10, the version of iOS that Apple released Rich Media for push. iOS versions under 10 will not support Rich Media.
  3. In the project navigator, click the FynoNotificationServiceExtension folder and open the NotificationService.m or NotificationService.swift and replace the entire file's contents with the provided code. Ignore any build errors at this point. We will import Fyno which will resolve these errors.
import UserNotifications
import fyno

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)
        fynoService.handleDidReceive(request, withContentHandler: contentHandler)
    }

    override func serviceExtensionTimeWillExpire() {
        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }
}

This code represents a 'NotificationService' class, which is an 'UNNotificationServiceExtension'. An 'UNNotificationServiceExtension' is used to intercept and modify incoming remote push notifications before they're displayed to the user. This is especially useful when you need to add rich content to notifications, such as media attachments, or decrypt encrypted notification content.

Step 2: Import the Fyno SDK into your Xcode project

  1. The fyno SDK can be added as a Swift Package (compatible with Objective-C as well). Check out the instructions on how to import the SDK directly from Xcode using Swift Package Manager.
  2. Add the Fyno SDK under Fyno Extension Service in order to enable for Fyno SDK to be handle and handle background/rich Push notifications via the service extension.

Step 3: Add Required Capabilities

This step ensures that your project can receive remote notifications. Apply these steps only to the main application target and not for the Notification Service Extension.

  1. Select the root project > your main app target and "Signing & Capabilities".
  2. If you do not see Push Notifications enabled, click + Capability and add Push Notifications.

  1. Click + Capability and add Background Modes. Then check Remote notifications.

Step 4: Add the Fyno Initialisation Code

  1. Navigate/Create to your AppDelegate file and add the Fyno initialisation code.
import Foundation
import UIKit
import fyno

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate  {
    let fynosdk  =  fyno.app

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        fynosdk.requestNotificationAuthorization { granted in
            if granted {
                DispatchQueue.main.async {
                    self.fynosdk.registerForRemoteNotifications()
                }
            }
        }
       fynosdk.enableTestMode(testEnabled: false)
       return true
    }


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

    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("Failed to register for remote notifications: \(error.localizedDescription)")
    }
    
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        // Send the device token to fynoServer
        let token = deviceToken.map { String(format: "%.2hhx", $0) }.joined()
        
        fynosdk.initializeApp(WSID: YOUR_WORKSPACE_ID,api_key: YOUR_API_KEY, integrationID: YOUR_INTEGRATION_ID, deviceToken: token){
                    result in
                    switch result{
                    case .success(_):
                        self.fynosdk.createUserProfile(distinctID: "your_database_unique_identifier",name: "John Doe"){result in
                                            switch result{
                                            case .success(let success):
                                            print(success)
                                            case .failure(let error):
                                            print(error)
                                            }
                                        }
                        
                    case .failure(let error):
                        print(error)
                         
                    }
                }
            }
  
  // DELETE USER PROFILE
  //SIGNOUT
  /**
  fynosdk.deleteProfile(name: anonymous_profile_name){result in
                switch result{
                case .success(let success):
                    print(success)
                case .failure(let error):
                    print(error)
                }
            }
  **/
  
    
}

The Fyno iOS SDK allows you to leverage Fyno's services in your iOS applications. It provides you with a set of tools to handle remote notifications, among other features.