将iOS 8文档保存到iCloud Drive

我想让我的应用程序将创build的文档保存到iCloud Drive,但是我很难跟随苹果所写的内容。 这是我到目前为止,但我不知道从哪里去。

UPDATE2

我在我的代码中有以下手动将文档保存到iCloud Drive:

- (void)initializeiCloudAccessWithCompletion:(void (^)(BOOL available)) completion { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ self.ubiquityURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]; if (self.ubiquityURL != nil) { dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"iCloud available at: %@", self.ubiquityURL); completion(TRUE); }); } else { dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"iCloud not available"); completion(FALSE); }); } }); } if (buttonIndex == 4) { [self initializeiCloudAccessWithCompletion:^(BOOL available) { _iCloudAvailable = available; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *pdfPath = [documentsDirectory stringByAppendingPathComponent:selectedCountry]; NSURL* url = [NSURL fileURLWithPath: pdfPath]; [self.manager setUbiquitous:YES itemAtURL:url destinationURL:self.ubiquityURL error:nil]; }]; } 

我拥有为App ID和Xcode本身设置的权利。 我点击button保存到iCloud Drive,没有错误popup,应用程序不会崩溃,但没有任何显示在我的Mac在iCloud驱动器。 该应用程序正在运行我的iPhone 6 Plus通过testing飞行,而使用iOS 8.1.1。

如果我在模拟器上运行它(我知道它不会工作,因为iCloud驱动器不工作与模拟器),我得到崩溃错误: 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[3]'

那么,我自己也对这个问题感兴趣,因此我在这个问题上花了很多时间,但是现在我已经有了工作,希望它也能帮助你!

在我的Mac上文件

要看看后台发生了什么,你可以看看~/Library/Mobile Documents/ ,因为这是文件最终会显示出来的文件夹。 另一个非常酷的实用程序是brctl ,用于监视将文件存储在iCloud中后,在Mac上发生的情况。 从terminal窗口运行brctl log --wait --shorten来启动日志。

在启用iCloudfunction(select了iCloud文档)之后,首先要做的是为iCloud Drive支持( 启用iCloud Drive支持 )提供信息。 我再次运行应用程序之前,必须打包我的捆绑版本; 花了一些时间来解决这个问题。 将以下内容添加到您的info.plist

 <key>NSUbiquitousContainers</key> <dict> <key>iCloud.YOUR_BUNDLE_IDENTIFIER</key> <dict> <key>NSUbiquitousContainerIsDocumentScopePublic</key> <true/> <key>NSUbiquitousContainerSupportedFolderLevels</key> <string>Any</string> <key>NSUbiquitousContainerName</key> <string>iCloudDriveDemo</string> </dict> </dict> 

接下来,代码:

 - (IBAction)btnStoreTapped:(id)sender { // Let's get the root directory for storing the file on iCloud Drive [self rootDirectoryForICloud:^(NSURL *ubiquityURL) { NSLog(@"1. ubiquityURL = %@", ubiquityURL); if (ubiquityURL) { // We also need the 'local' URL to the file we want to store NSURL *localURL = [self localPathForResource:@"demo" ofType:@"pdf"]; NSLog(@"2. localURL = %@", localURL); // Now, append the local filename to the ubiquityURL ubiquityURL = [ubiquityURL URLByAppendingPathComponent:localURL.lastPathComponent]; NSLog(@"3. ubiquityURL = %@", ubiquityURL); // And finish up the 'store' action NSError *error; if (![[NSFileManager defaultManager] setUbiquitous:YES itemAtURL:localURL destinationURL:ubiquityURL error:&error]) { NSLog(@"Error occurred: %@", error); } } else { NSLog(@"Could not retrieve a ubiquityURL"); } }]; } - (void)rootDirectoryForICloud:(void (^)(NSURL *))completionHandler { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSURL *rootDirectory = [[[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]URLByAppendingPathComponent:@"Documents"]; if (rootDirectory) { if (![[NSFileManager defaultManager] fileExistsAtPath:rootDirectory.path isDirectory:nil]) { NSLog(@"Create directory"); [[NSFileManager defaultManager] createDirectoryAtURL:rootDirectory withIntermediateDirectories:YES attributes:nil error:nil]; } } dispatch_async(dispatch_get_main_queue(), ^{ completionHandler(rootDirectory); }); }); } - (NSURL *)localPathForResource:(NSString *)resource ofType:(NSString *)type { NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; NSString *resourcePath = [[documentsDirectory stringByAppendingPathComponent:resource] stringByAppendingPathExtension:type]; return [NSURL fileURLWithPath:resourcePath]; } 

我有一个名为demo.pdf的文件存储在Documents文件夹中,我将“上传”。

我将重点介绍一些部分:

URLForUbiquityContainerIdentifier:提供存储文件的根目录,如果你想让它们在Mac上的iCloud Drive中显示,那么你需要将它们存储在Documents文件夹中,所以在这里我们将该文件夹添加到根目录:

 NSURL *rootDirectory = [[[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]URLByAppendingPathComponent:@"Documents"]; 

您还需要将文件名添加到URL,在这里我复制localURL的文件名(这是demo.pdf):

 // Now, append the local filename to the ubiquityURL ubiquityURL = [ubiquityURL URLByAppendingPathComponent:localURL.lastPathComponent]; 

而这基本上是…

作为奖励,请查看如何提供NSError指针以获取潜在的错误信息:

 // And finish up the 'store' action NSError *error; if (![[NSFileManager defaultManager] setUbiquitous:YES itemAtURL:localURL destinationURL:ubiquityURL error:&error]) { NSLog(@"Error occurred: %@", error); } 

如果您打算使用UIDocument和iCloud,Apple的这个指南相当不错: https : //developer.apple.com/library/ios/documentation/DataManagement/Conceptual/UsingCoreDataWithiCloudPG/Introduction/Introduction.html

编辑 :不知道任何更好的指导手,所以这可能有所帮助:

您将需要使用URLForUbuiquityContainerIdentifier上的URLForUbuiquityContainerIdentifier函数(这应该asynchronous完成)来获取ubiquityURL。 一旦完成,您可以使用类似下面的代码来创build您的文档。

 NSString* fileName = @"sampledoc"; NSURL* fileURL = [[self.ubiquityURL URLByAppendingPathComponent:@"Documents" isDirectory:YES] URLByAppendingPathComponent:fileName isDirectory:NO]; UIManagedDocument* document = [[UIManagedDocument alloc] initWithFileURL:fileURL]; document.persistentStoreOptions = @{ NSMigratePersistentStoresAutomaticallyOption : @(YES), NSInferMappingModelAutomaticallyOption: @(YES), NSPersistentStoreUbiquitousContentNameKey: fileName, NSPersistentStoreUbiquitousContentURLKey: [self.ubiquityURL URLByAppendingPathComponent:@"TransactionLogs" isDirectory:YES] }; [document saveToURL:fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) { }]; 

您还需要考虑使用NSMetadataQuery来检测从其他设备上传的文档,并有可能将它们排队等待下载,并观察NSPersistentStoreDidImportUbiquitousContentChangesNotification以查找通过iCloud所做的更改等。

**编辑2 **

看起来你正在试图保存一个PDF文件,这与苹果公司认为iCloud同步的“文档”不太一样。 不需要使用UIManagedDocument。 删除完成处理程序的最后3行,而是使用NSFileManager的setUbiquitous:itemAtURL:destinationURL:error:函数。 第一个URL应该是PDF的本地path。 第二个URL应该是ubiquiuty容器中保存的path。

您可能还需要查看NSFileCoordinator。 我认为苹果的这个指南可能是最相关的: https : //developer.apple.com/library/ios/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/iCloud/iCloud.html