iCloud Document Sync 使开发者能够轻松地将 iCloud 文档存储 API 集成到 iOS 应用中。这正是苹果应该如何提供的 iCloud 文档存储和管理的方式。只需一行代码即可将 iCloud 集成到 iOS (OS X 即将推出) Objective-C 文档项目。只需几行代码即可在 iCloud 中同步、上传、管理、删除文档(与通常需要数百行代码和小时相比)。只需几分钟即可在 iOS 应用中启动和运行 iCloud。
如果您喜欢这个项目,请到 GitHub 上 star它!关注 GitHub 上的项目以获取更新。如果您在应用中使用 iCloud Document Sync,请发送电子邮件至 contact[at]iraremedia.com 或在 Twitter 上 @iRareMedia 上告诉我们。
iCloud Document Sync 是在 iOS 应用中使用 iCloud 文档存储的好方法。以下是该项目的一些关键特性和亮点。
iCloud.framework
)拖放到您的项目中,就可以开始使用 iCloud——无需复杂的设置了解更多关于项目需求、许可和贡献的信息。
需要 Xcode 5.0.1+ 来在任何 iOS 项目中使用。部署目标最低为 iOS 6.0。
当前构建目标 | 最早支持的构建目标 | 最早兼容的构建目标 |
---|---|---|
iOS 8.1 | iOS 7.0 | iOS 6.0 |
Xcode 6.1.1 | Xcode 5.1.1 | Xcode 5.0.1 |
LLVM 6.0 | LLVM 5.0 | LLVM 5.0 |
需求说明
支持表示库已经与此版本进行了测试。兼容表示库应该可以在该操作系统版本上运行(即它不依赖于任何不可用的SDK功能),但不再进行兼容性测试,运行时可能需要调整或修复错误。
本项目采用MIT许可协议。请参阅完整的iCloud Document Sync许可协议。
贡献者不必提供归属信息,但是如果提供了他们将感到非常高兴。我们在这个项目上花费了很多时间、精力和资源——所以一点感谢(或类似的话语)会非常感激。如果你在你的应用程序中使用了iCloud Document Sync,请发送电子邮件至[email protected]或在Twitter @iRareMedia上告知我们。
任何贡献都热烈欢迎!您可以通过GitHub上的pull请求和问题进行贡献。了解更多关于如何向项目贡献的信息,请参阅此处。
本项目包含的iOS示例应用程序展示了如何使用iCloud Document Sync中的许多功能。您可以参考示例应用程序来了解如何使用和设置iCloud Document Sync。该应用程序应与iCloud一起使用(您可能需要提供自己的Bundle ID)。
将iCloud Document Sync添加到您的项目中非常简单。有多种方法可以将iCloud Document Sync添加到您的项目中。选择以下最适合您的流程。只需几步就能使所有内容在几分钟内启动和运行。
可以通过以下两种方式检索iCloud.framework:
iCloud.framework
文件复制到项目目录中。将.framework
文件拖放到项目中。.framework
文件拖放到项目中。将iCloud-Prefix.pch
文件。
要在Swift项目中使用iCloud Document Sync,您必须创建一个桥接头。
如果您已经有了一个桥接头,只需导入iCloud.h
(在导入框架时使用#import <iCloud/iCloud.h>
语法,否则使用#import "iCloud.h"
)。
如果您还没有桥接头,可以使用上述任何一个流程在项目中安装iCloud Document Sync。在将文件添加到Xcode时,将提示您创建桥接头——创建一个。然后,导入iCloud Document Sync(见上文段落)。
安装iCloud Document Sync后,只需要几行代码就可以使其启动和运行。
<iCloudDelegate>
代表。设置代理,并可以选择启用详细日志记录
[[iCloud sharedCloud] setDelegate:self]; // Set this if you plan to use the delegate
[[iCloud sharedCloud] setVerboseLogging:YES]; // We want detailed feedback about what's going on with iCloud, this is OFF by default
当您的应用程序启动时设置iCloud。在执行任何文档处理操作之前,调用此方法非常重要。您可以传递一个特定的Ubiquity容器ID(请参阅您的权利文件),或传递nil
以使用权利文件中的第一个Ubiquity容器ID。
[[iCloud sharedCloud] setupiCloudDocumentSyncWithUbiquityContainer:nil];
iCloud
的是setDelegate
,这样所有后续的操作和方法调用都可以与代理交互,并提供适当的信息。下面记录了在iCloud类中可用的关键方法、属性、类型和代理方法。如果您使用带iCloud文档同步的Xcode 5
,文档可在Xcode中直接使用(只需Option-Click任何方法即可快速帮助)。若需更详细的文档,请安装该项目中包含的docset。这会使您能够在Xcode的Organizer窗口中查看iCloud文档同步的文档。更多文档也可以在Wiki页面上找到(包括如何注册应用程序以使用iCloud、iCloud基础知识等)。
在iCloud文档同步中有许多可用的方法。以下是重要性/突出显示的方法。其他所有方法都在docset中以及代码注释中有记录。
iCloud文档同步在执行任何与iCloud相关的操作之前检查iCloud的可用性。如果iCloud不可用,任何iCloud文档同步方法可能会提前返回,且没有警告。因此,您应该总是在执行任何iCloud操作之前检查iCloud的可用性。
BOOL cloudIsAvailable = [[iCloud sharedCloud] checkCloudAvailability];
if (cloudIsAvailable) {
//YES
}
这通过查找应用程序的ubiquity令牌来检查iCloud是否可用。它返回一个布尔值;如果iCloud可用则为YES,否则为NO。请查看日志/文档以获取原因(为什么可能不可用)。您也可以通过调用以下方法来检查iCloud ublitity 容器的可用性
BOOL cloudContainerIsAvailable = [[iCloud sharedCloud] checkCloudUbiquityContainer];
checkCloudAvailability
方法将调用iCloudAvailabilityDidChangeToState: withUbiquityToken: withUbiquityContainer:
代理方法。
要使iCloud文档同步首次初始化,并在有更改时继续更新,您需要初始化iCloud。通过初始化iCloud,它将首次与iCloud同步,并在未来。
[[iCloud sharedCloud] init];
您还可以从iCloud手动获取更改
[[iCloud sharedCloud] updateFiles];
iCloud文档同步将自动检测iCloud文档中的更改。当有东西更改时,下面的代理方法会触发,并传递存储在iCloud中所有的文件(NSMetadata Items)及其名称(NSStrings)的NSMutableArray。
- (void)iCloudFilesDidChange:(NSMutableArray *)files withNewFileNames:(NSMutableArray *)fileNames
iCloud文档同步使用UIDocument和NSData来存储和管理文件。所有关于NSData和UIDocument的繁重工作都由您来处理。您无需实际创建或管理任何文件,只需将您的数据提供给iCloud文档同步即可,其余部分将为您完成。
要创建新文档或保存和关闭现有文档,请使用以下方法。
[[iCloud sharedCloud] saveAndCloseDocumentWithName:@"Name.ext" withContent:[NSData data] completion:^(UIDocument *cloudDocument, NSData *documentData, NSError *error) {
if (error == nil) {
// Code here to use the UIDocument or NSData objects which have been passed with the completion handler
}
}];
当文档保存或创建时,会调用完成处理程序。完成处理程序有一个UIDocument和NSData参数,包含文档及其内容。第三个参数是NSError,如果发生错误,它将包含该错误;否则它将为nil
。
您还可以上传在离线或本地创建的任何文档,本地文档目录中尚未存在于iCloud中的文件将会逐个被移动到iCloud中。这个过程涉及到大量的文件操作,因此可能需要很长时间。此过程将在后台线程上执行,以避免任何延迟或内存问题。上传过程结束后,在主线程上调用完成块。
[[iCloud sharedCloud] uploadLocalOfflineDocumentsWithRepeatingHandler:^(NSString *fileName, NSError *error) {
if (error == nil) {
// This code block is called repeatedly until all files have been uploaded (or an upload has at least been attempted). Code here to use the NSString (the name of the uploaded file) which have been passed with the repeating handler
}
} completion:^{
// Completion handler could be used to tell the user that the upload has completed
}];
注意repeatingHandler
块。每次本地文件上传时都会调用此块,因此它可能在短时间内被多次调用。如果发生错误,NSError对象将包含任何错误信息,否则它将为nil。
您可以使用以下方法从iCloud中删除文档。文件成功删除时将调用完成块。
[[iCloud sharedCloud] deleteDocumentWithName:@"docName.ext" completion:^(NSError *error) {
// Completion handler could be used to update your UI and tell the user that the document was deleted
}];
您可以使用以下方法打开并检索存储在您的iCloud文档目录中的文档。此方法将尝试打开指定的文档。如果文件不存在,将创建一个新的空白文件。文件打开或创建(无论是成功还是失败)时将调用完成处理程序。完成处理程序包含一个UIDocument、NSData和一个NSError,它们都包含有关打开的文档的信息。
[[iCloud sharedCloud] retrieveCloudDocumentWithName:@"docName.ext" completion:^(UIDocument *cloudDocument, NSData *documentData, NSError *error) {
if (!error) {
NSString *fileName = [cloudDocument.fileURL lastPathComponent];
NSData *fileData = documentData;
}
}];
首先检查检索或创建文件时是否有错误,如果没有错误,您可以继续获取文件的内容和元数据。
您也可以使用以下方法检查文件是否实际存在于iCloud中。
BOOL fileExists = [[iCloud sharedCloud] doesFileExistInCloud:@"docName.ext"];
if (fileExists == YES) {
// File Exists in iCloud
}
您可以使用以下方法将iCloud文档上传到公共URL。创建公共URL时将调用完成块。
NSURL *publicURL = [[iCloud sharedCloud] shareDocumentWithName:@"docName.ext" completion:^(NSURL *sharedURL, NSDate *expirationDate, NSError *error) {
// Completion handler that passes the public URL created, the expiration date of the URL, and any errors. Could be used to update your UI and tell the user that the document was uploaded
}];
重命名存储在iCloud中的文档
[[iCloud sharedCloud] renameOriginalDocument:@"oldName.ext" withNewName:@"newName.ext" completion:^(NSError *error) {
// Called when renaming is complete
}];
复制存储在iCloud中的文档
[[iCloud sharedCloud] duplicateOriginalDocument:@"docName.ext" withNewName:@"docName copy.ext" completion:^(NSError *error) {
// Called when duplication is complete
}];
iCloud在文档存储在iCloud中时跟踪文档状态。文档状态包括:正常/打开、关闭、冲突、保存错误和编辑禁用(了解更多关于UIDocumentState)。通过此方法获取存储在iCloud中的文件的当前文档状态。
[[iCloud sharedCloud] documentStateForFile:@"oldName.ext" completion:^(UIDocumentState *documentState, NSString *userReadableDocumentState, NSError *error) {
// Completion handler that passes two parameters, an NSError and a UIDocumentState. The documentState parameter represents the document state that the specified file is currently in (may be nil if the file does not exist). The NSError parameter will contain a 404 error if the file does not exist.
}];
通过订阅特定的目标/选择器/方法来监控文档状态的更改。
BOOL success = [[iCloud sharedCloud] monitorDocumentStateForFile:@"docName.ext" onTarget:self withSelector:@selector(methodName:)];
通过移除特定目标的通知来停止监控文档状态的更改。
BOOL success = [[iCloud sharedCloud] stopMonitoringDocumentStateChangesForFile:@"docName.ext" onTarget:self];
当文档的状态变为冲突时,您的应用程序应采取适当的行动,通过解决冲突或让用户解决冲突。您可以使用monitorDocumentStateForFile:onTarget:withSelector:
方法监控文档状态的更改。iCloud文档同步提供了两个帮助处理存储在iCloud中的文档冲突的方法。第一个方法让您查找文件的所有冲突版本
NSArray *documentVersions = [[iCloud sharedCloud] findUnresolvedConflictingVersionsOfFile:documentName];
返回的数组包含指定文件的NSFileVersion对象列表。然后您可以使用此文件版本列表自动合并更改或让用户选择正确版本。使用以下方法通过提交“正确”的文件版本来解决冲突。
[[iCloud sharedCloud] resolveConflictForFile:@"docName.ext" withSelectedFileVersion:[NSFileVersion object]];
icloud 文档同步的代理方法会通知您icloud状态以及您存储在icloud中的文档的状态。要使用icloud代理,请订阅iCloudDelegate
协议,然后设置delegate
属性。要使用icloudDocument代理,请订阅iCloudDocumentDelegate
协议,然后设置delegate
属性。
当icloud的可用性改变时被调用(由iOS自动调用)。第一个参数cloudIsAvailable
是一个布尔值,如果icloud可用则为YES,不可用则为NO。第二个参数ubiquityToken
是一个icloud 属性标记,代表当前的icloud身份。可以用来确定icloud是否可用以及icloud账户是否已被更改(例如,当用户登出然后使用不同的icloud账户登录时)。如果因为任何原因icloud不可用,则该对象可能为nil。第三个参数ubiquityContainer
是当前应用程序的ubiquity容器的根URL路径。该URL可能为nil,直到ubiquity容器初始化。
- (void)iCloudAvailabilityDidChangeToState:(BOOL)cloudIsAvailable withUbiquityToken:(id)ubiquityToken withUbiquityContainer:(NSURL *)ubiquityContainer
当您应用程序的icloud文档目录中的文件发生更改时,将调用此代理方法。第一个参数files
包含一个NSMetadataItems数组,可以用来收集有关文件的信息(例如URL、名称、日期等)。第二个参数fileNames
包含一个数组,其中包含每个文件作为NSString的名称。
- (void)iCloudFilesDidChange:(NSMutableArray *)files withNewFileNames:(NSMutableArray *)fileNames
当上传多个文件到icloud时,文件可能既存在于本地又存在于icloud中,造成冲突。icloud文档同步可以处理大多数冲突情况,并将其采取的动作报告到日志中。当icloud文档同步无法确定如何解决文件冲突(这种情况发生在修改日期和内容都相同的情况下),它将通过此代理方法将文件和相关信息传递给您。代理方法包含两个NSDictionaries,一个包含有关icloud文件的信息,另一个包含有关本地文件的信息。这两个字典都包含相同的键,以相同类型的对象在每个键中存储
fileContent
包含文件的NSData。fileURL
包含指向文件的NSURL。这可能被用来收集更多关于文件的信息。modifiedDate
包含表示文件最后修改日期的NSDate。以下是需要使用的代理方法
- (void)iCloudFileConflictBetweenCloudFile:(NSDictionary *)cloudFile andLocalFile:(NSDictionary *)localFile;
在创建icloud查询过滤器之前被调用。指定要查询的文件类型。如果未实现此代理方法或返回nil,则将查询存储在文档目录中的所有文件。应返回一个格式化的单个文件扩展名(如NSString): @"txt"
- (NSString *)iCloudQueryLimitedToFileExtension
当在尝试读取、保存或还原文档时发生错误时触发此代理方法。此代理方法仅在iCloudDocumentDelegate
和iCloudDocument
类中可用。如果您实现了icloudDocument代理,则必须实现此方法——这是必需的。
- (void)iCloudDocumentErrorOccured:(NSError *)error