AppGroups
1.1-简介
1.1.1-苹果沙盒机制
我们都知道苹果的沙盒机制,不同的沙盒之间是不能互相访问数据的
在开发Watch App的时候,假如说有一张图片文件,既要在iPhone中显示也要在Watch中显示应该怎么办呢?
我们可以把这张图片分别放到iOS的工程文件中和Watch App对应的Extension文件中,显然这种方式使我们的App文件大小产生不必要的增大
那么有没有一种简单的方式,使得只在工程中拖入一张图片,既可以在iPhone沙盒中使用也可以在Watch沙盒中使用呢?
答案是有,它就是AppGroups!
1.1.2-什么是AppGroups
AppGroups实际上是在苹果的服务器上配置一个共享文件夹的权限来让我的iPhone沙盒和Extension沙盒进行数据共享。他的本质上可以理解为重新生成一个沙盒使得以上两个沙盒之间都有权限来访问AppGroups沙盒里面的数据
AppGroups的概念并不是使得iPhone沙盒或者Extension沙盒有权限去访问对方的数据,而是新建一个AppGroups沙盒来使得以上两个沙盒有权限访问同一个沙盒
1.2-如何使用AppGroups
1.2.1-配置Appgroups证书
(1)打开电脑的钥匙串管理,我们从证书机构请求一个根证书并且保存在磁盘
(2)进入 https://developer.apple.com/membercenter 登陆我们的开发者账号,选择证书
(3)我们先根据根证书生成一个Development证书
选择Continue之后我们Download证书并且双击运行它
(4)给我们的App生成一个Identifiers
设置Identifier对应的项目Bundle ID 这里为com.heima.app
(5)使用第一个的开发者证书生成一个用于编译的Provisioning Profiles
continue之后我们选择刚刚生成的App ID的identifier
接下来是一些选择证书和设备的界面,这里我们根据个人情况随意勾选,在讲课中我们都勾选Select All 然后Continue
然后我们给这个Provisioning Profiles输入一个文件名,这里我就用heima.dev命名,前面部分随意,但是后缀最好用dev命名,这样别人一看就知道这是开发时的编译证书,形成一个统一规范
然后我们Download它并且双击运行
(6)生成一个App Groups的Identifier
我们给App Group添加一个描述并且设置对应的Identifie 这里需要注意的是,我们的App Groups的Identifier的名字以我们项目的Bundle Identifier的前缀命名
完成之后我们可以看到App Groups多了一个组
1.2.2-项目配置AppGroups
在配置App Group之前,我们最好先登录对应的AppID,否则会出现各种奇葩的坑爹的bug
如果你的项目bundle identifier与生成的appgroups的identifier前缀不一致,修改Watch App在本章节第10小节<修改Watch工程的bundle identifier>
(1)我们先给项目配置刚才导入的开发证书
配置iPhone的App Groups,点击开关
我们点开App Group可以看到下方的steps,这里需要注意的是,这个地方的三个选项是不能有任何报错的,其中第一项是我们是否添加App Groups,第二项是我们的Bundle Identifier是否与App Groups中的Identifier的后缀兼容,第三项是我们是否在我们的App ID中添加了App Groups。下图可以看到我项目的Bundle Identifier与AppGroups 设置的后缀不兼容,所以这里我们需要更改我们的Bundle Identifier
更改我的Bundle Identifier 使用com.heima作为前缀的时候,我们在点击上图的Fix issue进行修复,可以看到现在三个选项全部都是勾选,无报错
进行到这一步的时候,我们可以看到我的iPhone沙盒中多了一个文件,并且里面的键值是空的,这是我们虽然添加了App Groups权限但是还没有给项目配置App Groups 所致。说明我们已经生成了App Groups沙盒(本质上不是沙盒,而是一个共享的文件管理系统,但是我们可以这样理解为一个沙盒)
我们再回到刚才的设置界面,勾选我的group.con.heima
这时就可以看到iPhone的AppGroups文件夹中多了一个对应的值(既然这是一个数组,说明我们可以给一个项目添加多个App Groups,虽然这在实际开发中很少这样,但是也不排除这种情况的存在)
要想Watch与iPhone能够共享数据,我们不仅仅要给iPhone文件夹配置AppGroups,也要给Watch的文件夹配置AppGroups,在项目的Extension文件夹中我们重复上面的步骤来配置AppGroups
1.2.3-代码实现
(1)我们需要在iPhone的ViewController(也可以是其他,只要是代码能运行)文件中先将沙盒中的文件写入AppGrous文件夹 这里我们分别用NSFileManager和NSUserDefaults为例
//第一种方式 使用NSFileManager
//1读取图片
let path = NSBundle.mainBundle().pathForResource("appgroups01", ofType: "jpg")
let data = NSData(contentsOfFile: path!)
//2 读取共享文件夹路径
let sharePath = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("group.com.heima")?.path
let filePath = (sharePath as! NSString).stringByAppendingPathComponent("appgroups01.png")
//3 复制图片到共享文件夹路径
NSFileManager.defaultManager().createFileAtPath(filePath, contents: data, attributes: nil)
//第二种方式 NSUserDefaults
let shareDefaults = NSUserDefaults(suiteName: "group.com.heima")
shareDefaults?.setObject("这是我在groups中缓存的信息", forKey: "group")
shareDefaults?.synchronize()
(2)在AppWatch的Extension代码中获取AppGroups文件夹中的文件
//第一种方式 NSFileManager
//1 读取共享文件夹
let sharePath = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("group.com.heima")?.path
//2 拼接路径
let filePath = (sharePath as! NSString).stringByAppendingPathComponent("appgroups01.png")
//3 复制
image.setImageData(NSData(contentsOfFile: filePath))
//第二种方式 NSUserDefaults
let shareDefault = NSUserDefaults(suiteName: "group.com.heima")
shareDefault?.synchronize()
label.setText(shareDefault?.stringForKey("group"))
1.2.4-效果
我们需要先运行一次iPhone应用来让iOS沙盒中的图片写入到AppGroups文件夹,然后再运行Watch App
思考:那么NSFileManager和NSUserDefaults有何区别呢?
文件夹路径不同而已