在 App 扩展和主 App 间共享数据

swift 发布于 2017年11月20日

我们看到,通过 App 扩展,奇妙清单将主 App 的任务数据显示到了通知中心上面。而这个通知中心插件的数据是来自它的主应用的。

要达到这个效果,就需要这两个 App 之间的数据进行共享。注意,是两个独立的应用哦。App 扩展虽然是以插件形式附属在主 App 中的,但它也作为一个独立的 App。

在两个独立的应用间共享存储数据有什么方法呢?这就需要 App Groups 的概念。

从名字就可以看出来啦,App Groups 就是应用分组,将不同的应用分到一个 App Groups 中,即可在这些应用之间共享数据。

具体操作流程如下:

  1. 在项目的设置界面中找到应用的 Target,然后选择 Capabilities 选项卡,然后会列出很多选项,往下拉就会找到 App Groups 选项,我们打开它的开关。如下图:
    {% img figures /images/extension_3.jpg 650 %}
    (注意一点:打开 App Groups 需要关联你的苹果开发者账号。所以在这之前,你还需要拥有一个苹果开发者账号。)

  2. 成功开启后,会出现 App Groups 设置界面。点击下方的加号按钮,来添加一个新的 App Groups。如下图:
    {% img figures /images/extension_4.jpg 650 %}
    App Groups 的命名规则和 Bundle Identifier 一样,都是使用反向 DNS 规则。比如 group.app.test
    添加完成后,新的 Group 就会显示在设置界面上,我们将它左边的复选框勾选上,就完成了。
    {% img figures /images/extension_5.jpg 650 %}

  3. 到此为止,主 App 的设置步骤就完成了,下面我们还要对扩展 App 进行类似的操作。首先还是找到 App Groups 选项框,并打开开关。
    {% img figures /images/extension_6.jpg 650 %}
    (注意:这次我们的 Target 选择的是 extension)

  4. 打开开关后,这次和刚才的操作步骤有所不同,因为我们之前已经创建过 App Groups 了,这次就不需要创建新的了,只需要点击 App Groups 设置界面中的刷新按钮,就可以看到我们之前创建过的 Group 了。
    {% img figures /images/extension_7.jpg 650 %}
    然后勾选上即可完成 App 扩展Group 设置。

这些基本设置操作完成后,我们就可以在这两个 App 之间进行数据共享啦。大家可以想一想,我们用什么方法进行数据共享比较合适呢? {% img figures /images/extension_8.jpg 500 %}

其实很简单啦,就是我们熟悉的 NSUserDefaults 了。相信每一位朋友对这个类都不陌生。没想到吧,它还有共享数据这个作用。如果仔细查看它的文档,你就会发现它还有这样一个初始化方法 initWithSuiteName: 而官方文档上对这个方法是这样解释的:

Returns an NSUserDefaults object initialized with the defaults for the specified app group.

看到了吧,里面提到了 App Group, 这个初始化方法就是为 App Group 量身打造的。如果有兴趣进一步研究,可以查看下 NSUserDefaults官方文档

下面我们就继续啦,App 数据共享即将大功告成。首先我们在主 App 中的 AppDelegate 中的 didFinishLaunchingWithOptions 方法中来写存入数据的代码:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -\> Bool {


    var defaultForExtension:NSUserDefaults! = NSUserDefaults(suiteName: "group.app.test")
    if(defaultForExtension != nil){
        defaultForExtension.setObject("2014", forKey: "year")
        defaultForExtension.synchronize()
    }
    return true

}

有没有注意到这里面 NSUserDefaults 的构造方法NSUserDefaults(suiteName: "group.app.test") ,我们将前面我们创建的 App Groups 的标识作为参数传给了它的构造方法。这样,这个 NSUserDefaults 就专为我们的这个 App Group 存储数据了。

接下来,再到 App 扩展 中,再用这个 NSUserDefaults 将我们设置的值读取出来:

var defaultForExtension:NSUserDefaults! = NSUserDefaults(suiteName: "group.app.test")
if(defaultForExtension != nil){
    var result:NSString = defaultForExtension.objectForKey("year") as NSString
    println(result)
}

到这里,我们的 AppExtension 之间的数据共享就完成了, 是不是解决了一个大问题呢。反正我觉得是。


如果你觉得这篇文章有帮助,还可以关注微信公众号 swift-cafe,会有更多我的原创内容分享给你~

本站文章均为原创内容,如需转载请注明出处,谢谢。
关注微信公众号
发现更多精彩
swift-cafe