欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

IOS小组件(8):App与Widget数据共享

程序员文章站 2022-06-26 14:15:28
引言 Widget是一个迷你版的App,IOS有沙盒机制,不同App之间无法直接共享数据。组件和主App之间其实就是不同App的关系,所以也无法通过userdefaults.standard来传数据,苹果为了在不打破沙盒的前提下能够传数据,就想出了App Group的方法。 数据共享方式 可以通过网 ......

引言

  widget是一个迷你版的app,ios有沙盒机制,不同app之间无法直接共享数据。组件和主app之间其实就是不同app的关系,所以也无法通过userdefaults.standard来传数据,苹果为了在不打破沙盒的前提下能够传数据,就想出了app group的方法。

数据共享方式

 可以通过网络和本地数据两种方式进行数据的共享,本地数据共享可以通过 app groups。

app groups 原理

  它是 ios 8 之后推出的在 app 之间共享数据的方式,只需要简单的配置就可以实现数据的共享。它主要用于同一group下的app共享同一份读写空间,以实现数据共享。编码 app groups只能异步同步数据,当widget读取数据的时候,只能读之前手机app保存的数据,相反也是如此。当手机app有新的数据保存时,不能及时的通知widget更新数据,只能是widget下次去主动获取数据。
IOS小组件(8):App与Widget数据共享
IOS小组件(8):App与Widget数据共享

配置证书

  由于widget项目和主项目其实是两个独立的appid,因为需要单独给widget配置证书,配置证书的过程参考app证书配置;

开启app groups

  开启app groups是为了widget和app之间实现数据共享;为了便于后续操作,请先确保你的开发者账号在xcode上处于登录状态。

在app中开启:

    • targets-->appextensiondemo-->capabilities-->app groups
    • 找到以后,将app groups右上角的开关打开,然后选择添加groups,注意命名要规范,比如:group.com.company.app;

在extension中开启

假设创建widget target的名称为todayextension,对应的app group位于

  • targets-->todayextension-->capabilities-->app groups
  • 开启的方式和app中一样,注意必须要保证这里的app groups名称和app中相同。

app groups特点

  app group容器只是在宿主app运行期间才存在,其中的容器用于扩展与宿主的文件共享,宿主被关闭了,共享也就没意义了。
以上来自于实际测试,测试过程是:在宿主app运行期间,点击其中的按钮弹出模态视图控制器,进行数据填充。完成后保存数据到app group容器中的文件中,以供today extension扩展进行数据使用。只要将宿主app杀掉后重启启动宿主app,today extension 中已经显示的数据就完全没有了。单纯将宿主app杀掉不重启,today extension的任然hi显示之前的内容。由于宿主app中显示的数据也是从app group中的文件中取出来的,所以数据也没了。

  由于这个共享机制的特殊性,这个容器不能用来长期保存文件!!!应该将文件存储到宿主app的文件夹中,可以长期存储。today extension展示的数据量较少,在合适的时候将其需要的数据搬运到app group中!

共享数据核心代码

filemanager实现创建一个文件夹

/*
 * 创建并返回目录路径url
 */
static private func makesharefolderexists(foldername: string) -> url? {
    let documentsdirectory = filemanager().containerurl(forsecurityapplicationgroupidentifier: groupid)
    guard let folderurl = documentsdirectory?.appendingpathcomponent(foldername) else { return nil}
    
    var isdir : objcbool = false
    var isexists = filemanager.default.fileexists(atpath: folderurl.path, isdirectory: &isdir)
    if isexists && !isdir.boolvalue {
        do {
            try filemanager.default.removeitem(at: folderurl)
            isexists = false;
        } catch {
            return nil
        }
    }
    if !isexists {
        do {
            try filemanager.default.createdirectory(atpath: folderurl.path, withintermediatedirectories: true, attributes: nil)
        } catch {
            return nil
        }
    }
    return folderurl
}

  更多 filemanager 请查看官网api

参考

结语

  本文讲解了app与小组件的数据共享方式是用app groups机制来实现的,配置相关的请参考其他文章里面的详细操作步骤。另外请特别注意app groups里面的数据不是永久的,只是暂存而已