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.
Step 2: Navigate to General tab and scroll down until you see Embedded Binaries, and select the "+" button.
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.
Step 4: A prompt will appear when importing, where you need to select the Copy items if needed radio button.
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.
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.
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.
Step 5: In the new App IDs list, select the newly created App ID and click Edit.
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.
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)
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.
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 ?? "")
}
}
}