http://www.tuicool.com/articles/UfI7vy6

注意:一个说法----宿主应用和容器应用是一个东西(container app)

扩展(Extension)是 iOS 8 和 OSX 10.10 中引入新功能,Extension 不会单独存在,它将做为 App 的附加功能出现,为 App 提供更好的交互体验。由此 Extension 和容器应用(Containing App)之间的数据共享在所难免。Apple 在它的 官方文档 中只是以 NSUserDefaults 举例做了介绍,然后丢了一句“ Use Core Data, SQLite, or Posix locks to help coordinate data access in a shared container.”就算完事儿了。下面就来介绍下具体如何操作。

Extension Target

喵神在 WWDC 2014 Session笔记 – iOS 通知中心扩展制作入门 已经有了非常详尽的介绍,总之你需要在项目中添加一个 Application Extension Target( File > New Target > Application Extension > …),然后就可以从你非常熟悉的 view controller 开始编写 widget 代码了。

App Groups

在默认情况下,Extension 是无法直接获取 Containing App 的数据的,但在 iOS 8 中我们可以通过开启 App Groups 以实现同一个 team 的 Apps 及其 Extension 之间的数据共享。开启 App Groups:

  • 在 Xcode 6 的 Targets 中选中主 App‘s Target,找到 Capabilities 标签
  • 找到 App Groups 选项并展开,然后戳一下添加按钮
  • 给你的 App Groups 起个名字,通常是 group.xxx 的格式,随后 Xcode 自动创建 .entitlements 授权文件,其中包含了共享容器的访问名称,并将此 App Group 登记在你的开发者账号下的,确保只有你的 team 的 app 可以使用这些共享容器 
  • 选中 Extension’s Target,重复以上操作,勾选刚才创建的 group 就可以了

现在你把原来存在 App 沙箱中的数据改存在 这个 group 中就可以实现数据的共享了,在具体举例之前,你可能发现仅有数据好像还不够,比如你使用了 CoreData,还需要选中 .xcdatamodeld 文件和要用到的 model 文件,在 Xcode 的右侧工具栏中的找到 Target Membership 勾选 Extension 名,把它们加到 Extension Target 中。然后把 .xcdatamodeld 文件加到 Extension 的 Resource Bundle 里面:

  • Targets 中选中 Extension‘s Target,找到 Build Phase 标签
  • 找到 Copy Bundle Resources 选项并展开,然后戳一下添加按钮
  • 添加相应的 .xcdatamodel 文件

数据共享

好了,一切准备就绪,把

[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];

换成

[[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.xxx"]

也就是让主 App 和 Extension 都去访问共享容器中的文件,从而实现数据的共享。现在“you can also use Core Data, or in some cases SQLite, to help coordinate data access in a shared container.”(捂嘴笑)

如果是 NSUserDefaults 就是把

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

换成

NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.xxx"];

http://www.jianshu.com/p/7f8472a97aa6

======================================================

在整个通信过程中,难点在于宿主应用和应用扩展的数据共享,不仅仅是数据共享,可能还需要共享一些开发文件,比如类文件、xib、storyboard等。不要以为宿主应用和应用扩展同属于一个工程项目,它们两个就可以共同使用项目内的数据和所有文件。这是错误的。那么,宿主应用和应用扩展如何进行数据共享?我们需要创建一个共享域,当然,苹果早就给我们准备好了,我们只需要配置一下即可。

1、配置共享域
(1)配置宿主应用共享域

点击ON后,其实App Groups这里是空的,因为我之前做项目有配置过共享域,所以在选择证书的时候,系统会把证书配置过的共享域都给我自动加载了出来。如果这里是空的,就点击下面的+号,添加一个共享域。

这时,Xcode会弹出提示框,让你给共享库起一个名字以辨别,因为有些项目可能需要不只一个共享域,如果项目支持Apple watch,就需要一个新的共享域支持Apple watch。共享域的名字以group.开头,名字自己起。

OK,添加完共享域后,新的共享域就出现在了APP Groups中,选中它。

到这里,宿主应用的共享域配置告一段落。

(2)配置应用扩展

点击ON后,系统会弹出提示框,让你选择证书,因为共享域是在证书的基础上配置的。证书选择后,会把对应的所有共享域显示在App Groups中。

选中我们之前在宿主应用创建(选择)的共享域。

OK,应用扩展的共享域配置完毕。

2、数据共享
(1)NSUserDefaults

NSUserDefaults *userDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group.testAppExtension"];
获取共享域的偏好设置

接下来平时怎么用这里就怎么用。
(2)数据库
在创建应用扩展前,数据库我是放到这个路径下的。

[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"TestDB.sqlite"]

而现在,即使共享域配置完毕,应用扩展继续访问这个路径下的数据库也是访问不到的,因为共享域它有自己的路径。宿主应用和应用扩展之间的空间关系如下:

所以,我们要将数据库放在共享域的路径下。共享域的路径如下:

[[[[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.testAppExtension"] absoluteString] stringByAppendingPathComponent:@"TestDB.sqlite"]通过containerURLForSecurityApplicationGroupIdentifier方法和共享域标识符我们可以获取到该共享域的路径

OK,共享数据到这里暂告一段落。

共享类文件

创建一个Framework文件,让Framework文件引用这些需要共享的类,再让宿主应用和应用扩展分别导入Framework文件。这样做就很好的解决了问题,还不容易出错,也便于后期维护。

1、创建framework文件

framework文件的命名规范一些,以Kit为结尾。

创建完framework后工程目录如下

2、引用文件
(1)先把宿主应用target的文件引用删除,因为应用扩展同样要使用FMDB,所以也要把第三方文件从target中删除,否则编译照样会报错。

(2)增加AppExtensionKit的引用文件

需要注意的是,在这里不要添加xib文件,xib在哪修改下面会说。

(3)为应用扩展导入AppExtensionKit文件

添加完后编译一下,报错,40多个。
这是因为应用扩展也要用到libsqlite3.0.tbd这个包,但是并没有为应用扩展添加这个包,所以,重复上面的操作,把libsqlite3.0.tbd加入到AppExtensionKit中。

再编译一下,错误全部消失不见。OK,配置全部完成。

共享xib文件

PasswrodCell是从xib加载的,但我们并没有把xib文件加入到AppExtensionKit中。知道问题出在哪了,去解决。

在宿主应用的target中,找到PasswordCell的引用并删除。如下:

操作完后,xib文件从原来bundle下的路径变成了bundle下AppExtensionKit下的路径。

做完这些还不够,我们还要在ExtensionDemo和PasswordAppExtension两个target下的Copy Bundle Resources中将AppExtensionKit导入进来,否则宿主应用和应用扩展还是用不了PasswordCell.xib。如图:

ExtensionDemo的target:

那我们再次加载Password.xib文件,就需要从Bundle下的AppExtensionKit文件中加载。
加载方式代码如下:

cell = [[NSBundle mainBundle] loadNibNamed:@"AppExtensionKit.framework/ExtensionCell" owner:nil options:nil].lastObject;

Extension 与主app共享数据相关推荐

  1. iOS录屏直播(四)主App和宿主App数据共享,通信功能实现

    文章目录 CFNotificationCenterGetDarwinNotifyCenter 发送通知 接收通知 注意事项 遗留问题 补充 Morris_ 2019.06.17 上一篇总结了一下App ...

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

    tags: iOS 8,Swift,App Groups 随着 iOS 8 的发布,苹果为广大开发者很多新的 API,其中最突出显著的就非 App Extension 莫属了.这为开发者们又带来了很多 ...

  3. 【application Extension 之TodayExtension】扩展与宿主App之间共享数据有两种方式

    文章目录 前言 I .点击跳转到APP II.扩展与宿主App之间共享数据有两种方式: 2.1.通过NSUserDefaults 2.2. 通过一个扩展与App都可以访问的共享容器,来存放文件,数据( ...

  4. android 应用间共享数据,调用其他app数据资源

    在Android里面每个app都有一个唯一的linux user ID,则这样权限就被设置成该应用程序的文件只对该用户可见,只对该应用程序自身可见:而我们可以使他们对其他的应用程序可见,可以通过Sha ...

  5. Axure高保真移动端智能数据监控+用户画像+饼状图+条形图+折线图数据统计+抖音直播app用户数据统计+智慧移动端主播粉丝、评论、播放量大数据统计+套餐购买、续费套餐prd流程

    作品介绍:Axure高保真移动端智能数据监控+用户画像+饼状图+条形图+折线图数据统计+直播app用户数据统计+智慧移动端主播粉丝.评论.播放量大数据统计+套餐购买.续费套餐prd流程 原型演示及下载 ...

  6. 用matlab做app,2020-02-27 MATLAB App Designer——在用 App 设计工具创建的 App 内共享数据...

    1 访问和更新回调中的 UI 组件内的数据 app.Component.Property 2 获取并设置一个仪表的 Value 属性 x = app.PressureGauge.Value; % Ge ...

  7. Android不同APP间共享数据:sharedUserId

    Android-sharedUserId数据权限 Android给每个APK进程分配一个单独的用户空间,其manifest中的userid就是对应一个Linux用户 (Android 系统是基于Lin ...

  8. python跨文件全局变量_Python 进程之间共享数据(全局变量)的方法

    进程之间共享数据(数值型): import multiprocessing def func(num): num.value=10.78 #子进程改变数值的值,主进程跟着改变 if __name__= ...

  9. windows核心编程之进程间共享数据

    有时候我们会遇到window进程间共享数据的需求,例如说我想知道系统当前有多少某个进程的实例. 我们能够在程序中定义一个全局变量.初始化为0.每当程序启动后就加1.当然我们我们能够借助第三方介质来储存 ...

最新文章

  1. php虚拟主机和服务器吗,php虚拟主机和服务器吗
  2. monty python flying circus-巨蟒剧团之飞翔的马戏团 第1季
  3. 汇编:CF(carry flag)标志位
  4. mysql支持非关系_说下oracle、mysql、非关系型数据库中的索引结构?
  5. Spring Cloud构建微服务架构:服务消费(Feign)【Dalston版】
  6. 15_Android中任务栈
  7. Ubuntu16.04 下 Python3 虚拟环境安装 OpenCV
  8. console的高级使用
  9. 求一个数组的最长递减子序列 比如{9,4,3,2,5,4,3,2}的最长递减子序列为{9,5,4,3,2}...
  10. java 异常对象_在java中的异常处理中的异常对象是什么
  11. 【零基础学Java】—数组(五)
  12. 008-对象—— 对象$this self parent 内存方式及使用方法讲解
  13. 大学生创新创业计划-2020
  14. cs61A homework4
  15. Android uses-sdk tools:overrideLibrary
  16. 运算放大器知识体系-电流检测放大器
  17. 淘宝电商为什么转型社群团购,你知道吗?
  18. Spring-framework 5.1.8 中文版文档(Google翻译)- 001
  19. 用Python实现斐波那契数列代码
  20. 几款强大的PPT制作辅助软件

热门文章

  1. ffmpeg 中 -f <format> 字段的意义
  2. Python初学者值得拥有的3个Python优秀实践!你实践了嘛?
  3. C++之MFC制作简单计算器(VS2019实现),附带完整代码
  4. Linux下安装中文字体库
  5. 《算法笔记》4.1小节——算法初步-排序 问题 F: 小白鼠排队
  6. 计算机毕设(附源码)JAVA-SSM基于web的烟草售卖系统
  7. python解析word2003_python读取word文档的方法
  8. 好消息与坏消息应该怎么说
  9. 王者荣耀服务器维护8月23日,8月23日体验服停机更新公告
  10. Palisade Decision Tools(Risk) 7.0 1CD风险与决策分析工具套件