iOS 实现App 和 Extension扩展的数据交互

[TOC]

​ 昨天新增了一个任务,让App在接收到通知后上传记录以达到通知送达统计的功能,其实大部分推送都是可以从他们的控制台看到通知送达率这个信息点的。是不会用,还是碍于市场部没有权限查看,好吧,废话有点多,那我们考试考虑一下,该如何实现。(由于公司业务需求,推送选择的是Firebase的Cloud Messaging)

WX20200109-110730.png

​ 自iOS 10 之后Apple推行新特性 UNNotificationServiceExtension,这里就不过多说了,不熟悉的可以查看WWDC2016相关文章。

​ 然后我们思考一下常用数据存储的几种方式:

  • write直接写入文件的方法
  • NSUserDefault方法
  • 归档方法
  • Sqlite方法(FMDB)

NSUserDefault 无疑是大家用的最多的方式之一,我也是如此。那么问题就来了,也是此次写这篇文章的目的。

以下是我部分代码:

extension AppDelegate : MessagingDelegate {

    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {

        let token = Messaging.messaging().fcmToken

        NSLog("FCM token: (token ?? "")")

        UserManager.shared.firebase_device = token!
        
        UserPreference.setValueForKey(UserManager.shared.firebase_device, forKey: firebase_token)

    }

}
private func sendBackData(){
    if let token = UserDefaults.standard.value(forKey: "firebase_token") {
        print("\(token as? String)")
    }
}

使用的UserDefaults 去做存储Firebase生成的token,当我去serviceExtension去取值时候你会发现

控制台打印的是个nil,值得思考的是firebaseToken确实是存储了,为什么我在扩展里取不到

思考会不会是App Target 与 Extension Target相互独立存在的关系,所持有的路径并不是一致的。

Google一番知道了App Groups这么个东西,很显然我并没有接触过它,去吸收它!

常见使用场景1:APP之间数据共享(如账号登录)

常见使用场景2:容器APP与扩展应用之间资源共享(如:iMessage、keyboard等)

App Group

AppGroup allows data sharing between two different apps or even app and widgets by creating one common shared path (like document directory). Data saved over there can be accessed by any app which is associated with that particular AppGroup. It is an offline data sharing between apps.

这是Apple给我们的说明,正好使用场景2的情况

配置APP Groups

  1. 在App的所需要数据共享的Target下添加 App Groups

    add App Group 1.png
add App Group 2.png

并且从扩展目标中添加App Groups。

add App Group 3.png
add App Group 2.png

添加完成之后将在项目中生成一个xxx.entitlements文件


add App Group 4.png

App Group的使用

App Groups支持的常用数据共享包括NSUserDefaults、NSFileManager、NSFileCoordinator、NSFilePresenter、UIPasteboard、KeyChain、NSURLSession等。
下边以NSUserDefaults为例:

生成数据部分

extension AppDelegate : MessagingDelegate {
    // [START refresh_token]
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
        NSLog("Firebase registration token: \(fcmToken)")
        
        let token = Messaging.messaging().fcmToken
        NSLog("FCM token: \(token ?? "")")
        UserManager.shared.firebase_device = token!
        let defaults = UserDefaults(suiteName: "group.urwork.firebasetoken")
        defaults?.set(UserManager.shared.firebase_device, forKey: "token")
        defaults?.synchronize()
    }
}

获取共享数据部分

private func sendBackData(){
    let defaults = UserDefaults(suiteName: "group.urwork.firebasetoken")
    if (defaults?.object(forKey: "token") != nil) {
        let firebase_token = defaults?.value(forKey: "token") as! String
        param["deviceNo"] = firebase_token
    }
}

至此完美解决这个需求。

参考链接:

Notification Service Extension

iOS开发系列--App扩展开发

官方文档

你可能感兴趣的:(iOS 实现App 和 Extension扩展的数据交互)