Ensembles:一个 CoreData 同步框架

Ensembles_homepage

Ensembles拓展了苹果的Core Data框架,为Mac OS和iOS添加了P2P同步。多个SQLite持久化存储可以通过类似iCloud或者Dropbox的文件同步平台耦合在一起。该框架可容易地被拓展以支持任何可在设备间移动文件的服务,包括自定义服务器。

下载

使用以下命令将 Ensembles 下载到本地

Ensemble 使用了 Git 子模块(submodules)。如果想获取子模块,首先进入 ensembles 根目录

然后 issue 下命令

将Ensembles 添加到 iOS工程中

使用CocoaPods向Xcode工程添加Ensembles

1.向Podfile中写入以下内容

手动添加Ensembles 静态库到Xcode工程中

  1. 在Finder中,将Framework目录下的 Ensembles iOS.xcodeproj 文件拖入到你的项目中。
  2. 在左侧资源列表中选择应用资源列表等根文件,然后选择 app target。
  3. 在 General 标签下,点击 Linked Frameworks and Libraries 下方的“+”。
  4. 选择添加 libensembles.a 。
  5. 切换到“Build Settings”标签下“Locate the Other Linker Flags“并添加”-ObjC“。
  6. 切换到”Build Phases“标签下,展开“Target Dependencies”后点击“+”。
  7. 找到“Ensembles Resources iOS”并添加。
  8. 在左侧资源列表中打开工程“Ensembles iOS.xcodeproj”,并展开其下的 Products 文件夹,找到 Ensembles.bundle。
  9. 将Ensembles.bundle 拖拽到你项目中的 Copy Bundle Resources 下。
  10. 在预编译头文件中,或其他任何需要使用Ensembles的文件中添加以下代码。

以模块方式使用Ensembles
  1. 在Finder中,将Framework目录下的 Ensembles iOS.xcodeproj 文件拖入到你的项目中。
  2. 在左侧资源列表中选择应用的工程根文件,然后选择应用的target。
  3. 在“General”标签下,点击“Linked Frameworks and Libraries”下方的“+”。
  4. 选择并添加 Ensebles.framework。(注意不要选成Mac framework)
  5. 在文件中导入Ensembles

 

Objective-C

Swift

向 OS X 工程中导入Ensembles

使用CocoaPods向Xcode 工程中添加 Ensembles

1.向 Podfile 中添加以下内容

2.选择项目左侧资源列表根文件,并选择应用的target。

3.在“General”标签中,点击“Linked Frameworks and Libraries” 下的“+”。

4.选择并添加Ensembles.framework。

5.如果你的app bundle中没有build phase,则按以下步骤新建:

  • 选择工程资源列表根文件,然后选择应用的target
  • 打开Build Phases标签。
  • 点击顶部的按钮。
  • 在弹出菜单中选择New Copy Files Build Phase
  • 展开新的Copy FilesDestination 改为 Frameworks
  • 点击Copy Files底部的按钮,选择并添加Ensembles.framework

6.切换到 build setting中的“Runpath Search Path”下,添加@loader_path/../Frameworks

7.在预编译头文件或需要使用Ensembles的地方,添加以下代码

导入可选的云服务

默认情况下,Ensembles 只支持 iCloud。如果需要使用其他云服务,例如 Dropbox,你需要再按以下步骤进行。

如果你使用了CocoaPods,将可选的 subspec 添加到 Podfile。例如你想使用Dropbox,那么添加

如果你没使用CocoaPods,而是手动添加的Ensembles,对于你想支持的服务,你需要找到其相关的源文件和框架。你可以在 Vendor文件夹下找到需要框架,在Framework/Extensions文件夹下找到其相关源文件。

例如,如果你想支持Dropbox,你需要将DropboxSDK Xcode项目添加为依赖,并链接到相应的产品库(product library),同时在你的项目中包含文件CDEDropboxCloudFileSystem.h 和 CDEDropboxCloudFileSystem.m。

Idiomatic App

Idiomatic 是一款使用了Ensembles开发的App,使用iCloud或者Dropbox可以在不同设备间进行同步。该应用可以帮助你记录你的想法,包括照片,并添加标签进行分组。应用的Core Data model 有三个实体,并包含多对多的关系(relationship)。

可以通过Idiomatic来理解如何在Core Data 应用中集成Ensembles。如果你想了解Idiomatic如何工作,可以从 App Store 下载安装。也可以按一下步骤进行编译安装;

  1. 在Xcode左侧资源树选择Idiomatic项目,并选择Idiomatic target。
  2. 选择Capabilities标签,并打开iCloud开关。
  3. 在你的设备和模拟器中编译安装,并登陆相同的iCloud账号。

添加一个note,并为其添加标签。当打开app时会进行同步,不过你也可以通过点击Groups表格下的按钮强制同步。

对于Dropbox,可以通过 The Mental Faculty 账号进行同步,如果要使用自己的开发者账号,需要做一下几步:

1.在developer.dropbox.com 注册Dropbox 开发者账号。

2.在App Console中点击 Create app 按钮。

3.API类型选择Dropbox API。

4.选择保存类型 ‘Files and Datastores’。

5.选择‘Yes — My app only needs access to files it creates’。

6.输入应用名称(例如Idiomatic)。

7.点击创建应用。

8.找到Idiomatic项目中的IDMSyncManager类,找到以下代码,并将AppKey 和 AppSecret 内容替换为刚刚在Dropbox网站创建的应用。

9.在Xcode中选择Idiomatic project,再选择Idiomatic iOS target。

10.切换到 Info 标签。

11.打开URL Types 小节,并将 URL Schemes 入口更改为

Idiomatic还支持另一个同步服务:IdioSync。IdioSync是一个基于Node.js服务器定制服务,利用 Amazon S3存储。在ensembles.io 购买 Priority Support Package 即可获取服务器源码。

初步了解Ensembles

在使用Ensembles之前,需要现在预编译头文件或代码源文件中导入库的头文件。

CDEPersistentStoreEnsemble 是Ensembles框架中最重要的类。你需要为每个需要同步的NSPersistentStore实例化一个CDEPersistentStoreEnsemble对象。这个类将监听SQLite保存操作,并与其他设备进行同步。

一般情况下,当你创建Core Data栈(stack)时就要初始化CDEPersistentStoreEnsemble实例。在数据保存前初始化ensemble非常必要。

同时你还要注意遵从CDECloudFileSystem协议的类。任何遵从该协议的类,都可以将ensemble进行后端同步,在不同设备之间传输数据。你可以使用现有的类(如 CDEICloudFileSystem),也可以自己开发。

初始化ensemble只需要以下几行代码:

在 cloud file system 初始化后,它将和饱含NSManagedObjectModel文件的URL、NSPersistentStore的路径(path),一同传入到 CDEPersistentStoreEnsemble的初始化方法中。ensemble的identifier用来在不同设备间匹配相同存储文件,因此它尤为重要。

一旦CDEPersistentStoreEnsemble完成初始化,就可以与其绑定。创建一个ensemble实例并使用本地持久化存储进行初始化,只要一次就够了。一旦绑定完成,除非你明确的解绑、或者云文件系统出现严重问题(如切换账户),即使重启都不会影响ensemble。

可以通过isLeeched属性来查询ensemble对象是否绑定成功,leechPersistentStoreWithCompletion:方法查看初始化进程(如果尝试绑定一个已经绑定过的ensemble对象,将出错)

因为Ensembles包含大量网络操作和长时间操作,所以大部分方法均为异步方法,这些方法拥有错误参数(error parameter)的回调块(block)。如果error 为 nil,那么任务执行成功。这些方法需要在主线程(main thread)中调用,同时回调方法也将在主队列(main queue)中执行。

当ensemble对象绑定完成后,可以使用mergeWithCompletion方法进行同步操作:

一次合并包括从云端下载其他设备中的最新数据,后台的NSManagedObjectedContenxt 读取数据后与本地最新数据进行合并,再通过NSPersistentStore保存。

当执行合并操作时,将更改的数据合并到NSManagedObjectedContenxt是非常重要的一步。此操作可以在代理方法persistentStoreEnsemble:didSaveMergeChangesWithNotification:中进行。

要注意此处调用的上下文为后台执行的上下文(context)。你需要确保调用mergeChangesFromContextDidSaveNotification:方法的线程与主上下文(main context)进行通信。

你可以通过下面的代理方法来为managed objects 提供全局标示(identifiers)。

这个方法同样在后台线程中调用,注意只能访问在此线程中传递的对象。

并不强制提供全局标识符(global identifier),如果提供了,框架将自动确保对象不会因为不同设备中多次导入而重复。如果不提供全局标识符,那么框架将自动为对象提供一个新的唯一标识符。

如果你决定提供全局标识符,它们如何生成、如何保存都有你决定。一个常见的选择是对数据模型(data model)的实体(entity)添加一个额外的属性(attribute),将其设为UUID进行保存。

排除错误

Ensembles 有内置的日志系统,默认只记录错误。开发过程中,使用详细日志记录,可以看到框架做了什么。只需要在启动过程中调用以下方法:

单元测试

每个平台的Ensembles框架都饱含单元测试,运行测试:打开Xcode工作空间,在顶部工具栏选择 Ensembles Mac 或者Ensembles iOS target,选择菜单项 Product > Test。

开源地址:https://github.com/drewmccormack/ensembles

1 收藏

资源整理者简介:张发白

简介还没来得及写 :) 个人主页 · 贡献了6个资源 · 1


直接登录

推荐关注

按分类快速查找

关于资源导航
  • 伯乐在线资源导航收录优秀的工具资源。内容覆盖开发、设计、产品和管理等IT互联网行业相关的领域。目前已经收录 1439 项工具资源。
    推送伯乐头条热点内容微信号:jobbole 分享干货的技术类微信号:iProgrammer