Skip to main content

iOS SDK

An iOS Framework that makes it easy for mobile developers to build in-app A8Chat supports.

Target OS: iOS 13+

Installation

Step 1: In the Xcode Project Navigator, select your project and then click the app target that you want the framework to be integrated with.

A8Flow Sample App

Step 2: Navigate to General tab and scroll down until you see Embedded Binaries, and select the "+" button.

A8Flow Sample App

Step 3: On the bottom-left of the pop-up, click Add Other button and pick the A8Flow.framework & A8FlowScanner.framework file that were previously downloaded.

A8Flow Sample App

Step 4: A prompt will appear when importing, where you need to select the Copy items if needed radio button.

A8Flow Sample App

Step 5: Once you find the framework added in the Embedded Binaries , change the drop-down value beside the name of the framework to Embed & Signing to embed the framework to your app.

A8Flow Sample App

Now, you have successfully added the framework to your project!

A Quick Alternative way to do all the above is to just drag & drop the framework you download into your workspace and embed it in the Embedded Binaries section.

Importing

Use this import statement in the ViewController wherever you want to load the ChatWidget.

import A8Flow
import A8FlowScanner

FCM Implementation

Follow the steps below in integrating FCM Firebase Cloud Messaging (FCM) for implementing cloud messaging into your application.

Generate an APNs certificate

Step 1: Head over to Apple, click Account and log into your developer account.

A8Flow Sample App

Step 2:In the left menu, select Certificates, IDs & Profiles.

Step 3: Under the Identifiers section, select App ID and click the Add New App ID button. Then, fill out App ID Description & Bundle ID fields.

Step 4: Check Push Notifications and click Continue. Navigate to the next screen and click Register.

A8Flow Sample App

Step 5: In the new App IDs list, select the newly created App ID and click Edit.

A8Flow Sample App

A8Flow Sample App

Step 6: Scroll down to the Push Notifications section and click on Create Certificate (Development SSL Certificate is sufficient for now) – you’ll create another one only when the app is submitted to the App Store.

Step 7: Now, follow the given instructions for creating a CSR certificate from a Certificate Authority, using Keychain Access app on your laptop and then click Continue.

A8Flow Sample App

Step 8: In the next screen on Apple’s website, upload the certificate that you’ve just saved to your disk. If you’re getting an Invalid Certificate error, try removing all the expired certificates in your Keychain and re-create the CSR from the previous step. Now you should have a certificate created – download and store it securely on your laptop (the file extension is .cer).

Step 9: Open the .cer file (by double-clicking on it) and add it to your Keychain. After it is moved to Keychain, right-click on the certificate and then select Export. This will create a .p12 file for you (you can choose an encryption password as well for extra security)

A8Flow Sample App

Enable Push Notification in Firebase Cloud Messaging Console

Step 1: Navigate to Firebase Console. If you don’t have a project, create one. Then choose a project and go to its console.

Note: If you don’t have an iOS app already, create one by clicking Add App on Firebase Console homepage. Make sure you use exactly the same bundle ID as the one you used in Apple Developer portal. Then download the GoogleService.plist file, which you’ll need to add to your Xcode project.

Step 2: Locate the APNs Certificates section and upload the .p12 file you’ve generated previously. If you have used a password, you will also need to type it in the password field.

A8Flow Sample App

Now, you will be able to send push notifications with Firebase in Swift 5.

Add GoogleService.plist File to Your Xcode Project

This is the file that you have downloaded earlier from the Firebase Console. In order to connect the iOS app to the Firebase server, you will have to add this to the Xcode project. On failure to add this to the project, you will experience a crash.

Write The Code to Generate Push Notification

Step 1: Import Firebase in Appdelegate.swift.

import A8Flow
import UserNotifications
import Firebase
import FirebaseInstanceID
import FirebaseMessaging

Step 2: Add the following code into apDidFinishLaunchingWithOptions method to register pushnotification service.

FirebaseApp.configure()

Messaging.messaging().delegate = self

if #available(iOS 10.0, *) {
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self

let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: {granted, error in

if granted == true{

DispatchQueue.main.async {
application.registerForRemoteNotifications()
}

// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self

} else {
}
})

} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}

//get application instance ID
InstanceID.instanceID().instanceID { (result, error) in
if let error = error {
print("Error fetching remote instance ID: \(error)")
} else if let result = result {
print("Remote instance ID token: \(result.token)")
}
}

application.registerForRemoteNotifications()

Step 3: Implement messaging delegate extension in AppDelegate.swift

extension AppDelegate: MessagingDelegate{
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
print("Firebase registration token: \(fcmToken)")

fcmTokenVal = fcmToken


let dataDict:[String: String] = ["token": fcmToken]
NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
// TODO: If necessary send token to application server.
// Note: This callback is fired at each app startup and whenever a new token is generated.
}

func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
print("Received data message: \(remoteMessage.appData)")
}
}

Step 4: Add Remote notification method code.

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler handler: (UIBackgroundFetchResult) -> Void)
{

print("tapped notificcation Recived: \(userInfo)")

}

func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Unable to register for remote notifications: \(error.localizedDescription)")
}

Step 5: Add the following code for UserNotification method into AppDelegate.Swift.

extension AppDelegate: UNUserNotificationCenterDelegate{
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo

// With swizzling disabled you must let Messaging know about the message, for Analytics
// Messaging.messaging().appDidReceiveMessage(userInfo)
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}

// Print full message.
print("willPresent notification",userInfo)

let TaskName = userInfo[taskName] as? String ?? ""
let ProcessInstanceId = userInfo[processInstanceId] as? String ?? ""
let processDefinitionName = userInfo[ProcessDefinitionId] as? String ?? ""
let taskID = userInfo[taskId] as? String ?? ""
let FormKey = userInfo[formKey] as? String ?? ""
let Type = userInfo[type] as? String ?? ""
let Title = userInfo[title] as? String ?? ""
let Body = userInfo[body] as? String ?? ""
let CreatedDate = userInfo[created] as? String ?? ""


A8FlowBuilder(self).recieveNotificationData(taskName: TaskName, processInstanceID: ProcessInstanceId, ProcessDefinitionName: processDefinitionName, taskId: taskID, formKey: FormKey, title: Title, type: Type, body: Body, created: CreatedDate, formStatus: false)



// Change this to your preferred presentation option
completionHandler([.alert, .badge, .sound])
}

func userNotificationCenter(center: UNUserNotificationCenter, willPresentNotification notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
{
//Handle the notification
completionHandler(
[UNNotificationPresentationOptions.alert,
UNNotificationPresentationOptions.sound,
UNNotificationPresentationOptions.badge])
}

func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {

if(application.applicationState == .active){
print("user tapped the notification bar when the app is in foreground")
let userInfo = response.notification.request.content.userInfo
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}

// Print full message.
print("didReceive notification tapped",userInfo)

TaskName = userInfo[taskName] as? String ?? ""
ProcessInstanceId = userInfo[processInstanceId] as? String ?? ""
processDefinitionName = userInfo[ProcessDefinitionId] as? String ?? ""
TaskID = userInfo[taskId] as? String ?? ""
FormKey = userInfo[formKey] as? String ?? ""
Types = userInfo[type] as? String ?? ""
Title = userInfo[title] as? String ?? ""
Body = userInfo[body] as? String ?? ""
CreatedDate = userInfo[created] as? String ?? ""


window = UIWindow(frame: UIScreen.main.bounds)
let vc = ImagePreviewViewController()
window?.rootViewController?.present(vc, animated: true, completion: nil)
window?.makeKeyAndVisible()

}

if(application.applicationState == .inactive)
{
print("user tapped the notification bar when the app is in terminated")
let userInfo = response.notification.request.content.userInfo
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}

// Print full message.
print("didReceive notification tapped",userInfo)

let TaskName = userInfo[taskName] as? String ?? ""
let ProcessInstanceId = userInfo[processInstanceId] as? String ?? ""
let processDefinitionName = userInfo[ProcessDefinitionId] as? String ?? ""
let taskID = userInfo[taskId] as? String ?? ""
let FormKey = userInfo[formKey] as? String ?? ""
let Type = userInfo[type] as? String ?? ""
let Title = userInfo[title] as? String ?? ""
let Body = userInfo[body] as? String ?? ""
let CreatedDate = userInfo[created] as? String ?? ""


A8FlowBuilder(self).recieveNotificationData(taskName: TaskName, processInstanceID: ProcessInstanceId, ProcessDefinitionName: processDefinitionName, taskId: taskID, formKey: FormKey, title: Title, type: Type, body: Body, created: CreatedDate, formStatus: false)

}

if(application.applicationState == .background)
{
print("user tapped the notification bar when the app is in background")
let userInfo = response.notification.request.content.userInfo
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}

// Print full message.
print("didReceive notification tapped",userInfo)

let TaskName = userInfo[taskName] as? String ?? ""
let ProcessInstanceId = userInfo[processInstanceId] as? String ?? ""
let processDefinitionName = userInfo[ProcessDefinitionId] as? String ?? ""
let TaskID = userInfo[taskId] as? String ?? ""
let FormKey = userInfo[formKey] as? String ?? ""
let Type = userInfo[type] as? String ?? ""
let Title = userInfo[title] as? String ?? ""
let Body = userInfo[body] as? String ?? ""
let CreatedDate = userInfo[created] as? String ?? ""


A8FlowBuilder(self).recieveNotificationData(taskName: TaskName, processInstanceID: ProcessInstanceId, ProcessDefinitionName: processDefinitionName, taskId: TaskID, formKey: FormKey, title: Title, type: Type, body: Body, created: CreatedDate, formStatus: false)

}

completionHandler()

}

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler handler: (UIBackgroundFetchResult) -> Void)
{

print("tapped notificcation Recived: \(userInfo)")

}

}

Implementation

info.plist

Add Transport Security to info.plist File to Get HTTP Service

<dict>
<key>NSExceptionDomains</key>
<dict>
<key>www.myurl.com</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>

Add Camera Permission in info.plist

<key>NSCameraUsageDescription</key>
<string>This app wants to access your camera</string>

Add File Access Permission in info.plist

<key>NSFileProviderDomainUsageDescription</key>
<string>yes</string>
<key>NSFileProviderPresenceUsageDescription</key>
<string>yes</string>

Add Location Permission in info.plist

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Application requires user’s location for better user experience.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Application requires user’s location for better user experience.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Application requires user’s location for better user experience.</string>

Write The Code to Get A8Flow SDK Interface

Step 1: In ViewController.swift add import framework & firebase.

import A8Flow
import A8FlowScanner
import UserNotifications
import Firebase
import FirebaseInstanceID
import FirebaseMessaging

Step 2: Add user notification method into viewDidAppear & Objective-c method of user notification**

NotificationCenter.default.addObserver(self, selector: #selector(self.fcmTokenUpdated(notification:)), name: Notification.Name("FCMToken"), object: nil)

deinit {
//Don't forget to removeObserver
NotificationCenter.default.removeObserver(self, name: Notification.Name("FCMToken"), object: nil)
}

@objc func fcmTokenUpdated(notification:Notification){


if let userInfo = notification.userInfo as? [String: String]{

if let c = userInfo["token"] {

print(c)
UserDefaults.standard.set(c,forKey: "Token")

let d = UserDefaults.standard.string(forKey: "Token")

fcmval = d

let baseURL = "https://url.com"
A8FlowBuilder(self).showLoginView(url: baseURL, fcm: fcmval ?? "")
}

}
}