BAKit-iOS
基于位置的用户互动
增强您的应用。赋予您的营销力量。
这不仅仅是关于广告... 这是对“个性化”的体现
BoardActive 的平台通过基于位置的互动将品牌与消费者连接。我们的国际专利待审的 Visualmatic™ 软件是一款强大的营销工具,允许品牌在任意位置设立虚拟区域,测量人流量,并在用户进入地理位置时发布个性化的消息…… 除此之外,通过查看用户的印象后去了哪里,有效地归因于营销活动的效率!
使用您的 BoardActive 账户创建地点(地理围栏区域)和消息(通知),以便将定制消息发送给您的应用程序用户。
一旦客户端建立了至少一个地理围栏,BAKit SDK 利用任何智能手机的本地位置监控,确定何时用户进入该围栏,并向客户端发布由其组成的个性化通知。
所需用于设置
- 添加了您的应用的 Firebase 项目的项目。
- BoardActive 账户
创建 Firebase 项目
将 Firebase Core 和 Firebase Messaging 添加到您的应用
要使用 Firebase Cloud Messaging,您必须创建一个 Firebase 项目。
- Firebase iOS 快速入门 - 创建和了解 Firebase 项目的指南。
- 在 iOS 上设置 Firebase Cloud Messaging 客户端应用 - 如何处理 Firebase Cloud Messaging(BoardActive 发送推送通知的方式)。
- 请参阅以下两篇文章有关 APNS,因为 Firebase 的文档有点过时。我们还将讨论在安装 SDK 时如何将推送通知添加到您的帐户
- 点击此处进入 Firebase 控制台
创建相关的 Firebase 项目后,您可以下载 GoogleService-Info.plist
并将其保存在“CocoaPods”部分中使用。
接收您的 BoardActive AppKey
- 请将 Firebase 项目设置中的“服务帐户” -> “Firebase Admin SDK”下的 Firebase 服务帐户中找到的 Firebase 密钥通过电子邮件发送到 [email protected],他将回复您的 BoardActive AppKey。
安装BAKit SDK
- BoardActive for iOS使用Swift 4.0,并支持iOS 10及以上版本。
- 需要使用Xcode 9以上版本构建,以支持iPhone X和iOS 11。
- 目前,SDK可通过CocoaPods或下载仓库并将SDK的源代码手动链接到您的项目来获取。
CocoaPods
- 设置CocoaPods
- 关闭/退出Xcode。
- 在您的项目目录中的终端运行
$ pod init
。 - 打开您刚刚创建的
Podfile
文件,并添加以下插件(请参阅本节最后的示例Podfile)。pod 'BAKit'
pod 'Firebase/Core', '~> 5.0'
pod 'Firebase/Messaging'
- 在主项目目录中的终端运行
$ pod repo update
。 - 在主项目目录中的终端运行
$ pod install
,一旦CocoaPods创建了工作空间,请打开 workspace 文件。 - 通过将文件拖入您的项目,将之前在 创建Firebase项目 部分中提到的
GoogleService-Info.plist
集成到您的项目中。
示例Podfile
platform :ios, '10.0'
use_frameworks!
target :YourTargetName do
pod 'BAKit'
pod 'Firebase/Core', '~> 5.0'
pod 'Firebase/Messaging'
end
更新Info.plist - 位置权限
请求位置权限需要在您的 Info.plist
文件中包含以下条目。每个条目都需要一个伴随的关键字,形式为String
,解释用户地理位置数据将如何使用。
NSLocationAndWhenInUseUsageDescription
隐私 - 总是和在使用时位置隐私说明
NSLocationWhenInUseUsageDescription
隐私 - 在使用时描述
NSLocationAlwaysUsageDescription
隐私 - 总是位置描述
更新应用权限
在您的应用的主要目标下,您需要编辑其 权限 如下
- 启用 后台模式。Apple提供了关于不同 后台模式 的文档,请在此处。
- 勾选 位置更新 复选框
- 勾选 后台获取 复选框
- 勾选复选框 远程通知
- 启用 推送通知
使用 BAKit
AppDelegate
在“将 Firebase Core 和 Firebase Messaging 添加到您的应用程序”部分中,按照 Apple 的说明操作后,请将以下代码添加到您的 AppDelegate.swift
文件的顶部
import BAKit
import Firebase
import UIKit
import UserNotifications
import Messages
在 AppDelegate
类声明的之前,声明了一个协议。符合该协议的类在示例应用程序中接收通知
protocol NotificationDelegate: NSObject {
func appReceivedRemoteNotification(notification: [AnyHashable: Any])
}
在 AppDelegate
类声明的刚下方,声明了以下变量和常量
public weak var notificationDelegate: NotificationDelegate?
private let authOptions = UNAuthorizationOptions(arrayLiteral: [.alert, .badge, .sound])
在配置 Firebase 并声明 AppDelegate
对 Firebase 的 MessagingDelegate
的一致性后,将您的 BoardActive AppId 和 AppKey 存储到 BoardActive.client.userDefaults
中,如下所示
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
FirebaseApp.configure()
Messaging.messaging().delegate = self
UNUserNotificationCenter.current().delegate = self
application.applicationIconBadgeNumber = UserDefaults.extensions.badge
// AppId is of type Int
BoardActive.client.userDefaults?.set(<#AppId#>, forKey: "AppId")
// AppKey is of type String
BoardActive.client.userDefaults?.set(<#AppKey#>, forKey: "AppKey")
return true
}
在您的 AppDelegate
类的闭合大括号下添加以下代码
extension AppDelegate {
/**
Call this function after having received your FCM and APNS tokens.
Additionally, you must have set your AppId and AppKey using the
BoardActive class's userDefaults.
*/
func setupSDK() {
let operationQueue = OperationQueue()
let registerDeviceOperation = BlockOperation.init {
BoardActive.client.registerDevice { (parsedJSON, err) in
guard err == nil, let parsedJSON = parsedJSON else {
fatalError()
}
BoardActive.client.userDefaults?.set(true, forKey: String.ConfigKeys.DeviceRegistered)
BoardActive.client.userDefaults?.synchronize()
}
}
let requestNotificationsOperation = BlockOperation.init {
self.requestNotifications()
}
let monitorLocationOperation = BlockOperation.init {
DispatchQueue.main.async {
BoardActive.client.monitorLocation()
}
}
monitorLocationOperation.addDependency(requestNotificationsOperation)
requestNotificationsOperation.addDependency(registerDeviceOperation)
operationQueue.addOperation(registerDeviceOperation)
operationQueue.addOperation(requestNotificationsOperation)
operationQueue.addOperation(monitorLocationOperation)
}
public func requestNotifications() {
UNUserNotificationCenter.current().requestAuthorization(options: authOptions) { granted, error in
if BoardActive.client.userDefaults?.object(forKey: "dateNotificationPermissionRequested") == nil {
BoardActive.client.userDefaults?.set(Date().iso8601, forKey: "dateNotificationPermissionRequested")
BoardActive.client.userDefaults?.synchronize()
}
guard error == nil, granted else {
// Handle error and possibility of user not granting permission
return
}
}
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
}
在一个遵循 Firebase 的 MessagingDelegate
扩展中接收 FCM Token 时,将此令牌存储到 BAKit 的 userDefaults
中。
// MARK: - MessagingDelegate
extension AppDelegate: MessagingDelegate {
/**
This function will be called once a token is available, or has been refreshed. Typically it will be called once per app start, but may be called more often, if a token is invalidated or updated. In this method, you should perform operations such as:
* Uploading the FCM token to your application server, so targeted notifications can be sent.
* Subscribing to any topics.
*/
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
BoardActive.client.userDefaults?.set(fcmToken, forKey: "deviceToken")
BoardActive.client.userDefaults?.synchronize()
}
}
作为验证您已实现必要的 UNUserNotificationCenterDelegate
函数的一种手段,以下提供了一个代码片段。
// MARK: - UNUserNotificationCenterDelegate
extension AppDelegate: UNUserNotificationCenterDelegate {
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let deviceTokenString = deviceToken.reduce("", { $0 + String(format: "%02X", $1) })
os_log("\n[AppDelegate] didRegisterForRemoteNotificationsWithDeviceToken :: APNs TOKEN: %s \n", deviceTokenString)
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
// Handle APNS token registration error
os_log("\n[AppDelegate] didFailToRegisterForRemoteNotificationsWithError :: APNs TOKEN FAIL :: %s \n", error.localizedDescription)
}
/**
Called when app in foreground or background as opposed to `application(_:didReceiveRemoteNotification:)` which is only called in the foreground.
(Source: https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623013-application)
*/
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
handleNotification(application: application, userInfo: userInfo)
completionHandler(UIBackgroundFetchResult.newData)
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo as! [String: Any]
if userInfo["notificationId"] as? String == "0000001" {
handleNotification(application: UIApplication.shared, userInfo: userInfo)
}
NotificationCenter.default.post(name: NSNotification.Name("Refresh HomeViewController Tableview"), object: nil, userInfo: userInfo)
completionHandler(UNNotificationPresentationOptions.init(arrayLiteral: [.badge, .sound, .alert]))
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
guard (response.actionIdentifier == UNNotificationDefaultActionIdentifier) || (response.actionIdentifier == UNNotificationDismissActionIdentifier) else {
return
}
let userInfo = response.notification.request.content.userInfo as! [String: Any]
self.notificationDelegate?.appReceivedRemoteNotification(notification: userInfo)
completionHandler()
}
/**
Creates an instance of `NotificationModel` from `userInfo`, validates said instance, and calls `createEvent`, capturing the current application state.
- Parameter userInfo: A dictionary that contains information related to the remote notification, potentially including a badge number for the app icon, an alert sound, an alert message to display to the user, a notification identifier, and custom data. The provider originates it as a JSON-defined dictionary that iOS converts to an `NSDictionary` object; the dictionary may contain only property-list objects plus `NSNull`. For more information about the contents of the remote notification dictionary, see Generating a Remote Notification.
*/
public func handleNotification(application: UIApplication, userInfo: [AnyHashable: Any]) {
let tempUserInfo = userInfo as! [String: Any]
if let _ = tempUserInfo["aps"], let messageId = tempUserInfo["messageId"] as? String, let firebaseNotificationId = tempUserInfo["gcmmessageId"] as? String {
switch application.applicationState {
case .active:
os_log("%s", String.ReceivedBackground)
BoardActive.client.postEvent(name: String.Received, messageId: messageId, firebaseNotificationId: firebaseNotificationId)
break
case .background:
os_log("%s", String.ReceivedBackground)
BoardActive.client.postEvent(name: String.Received, messageId: messageId, firebaseNotificationId: firebaseNotificationId)
break
case .inactive:
os_log("%s", String.TappedAndTransitioning)
BoardActive.client.postEvent(name: String.Opened, messageId: messageId, firebaseNotificationId: firebaseNotificationId)
break
default:
break
}
}
}
}
下载示例应用程序源代码
在代码库的“示例”部分包含了一个示例应用程序。
寻求帮助
我们团队愿意提供帮助。请联系我们
- 电话: (678) 383-2200
- 给我们发邮件 [email protected]
- 在线支持 网站