我想让我的应用将其创建的文档保存到iCloud Drive,但我很难跟上Apple写的内容。这是我到目前为止所做的,但我不确定从哪里开始。
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本身设置了权利。我点击按钮保存到iCloud Drive,没有弹出错误,应用程序没有崩溃,但在iCloud Drive中我的Mac上没有显示任何内容。使用iOS 8.1.1时,该应用程序通过Test Flight在我的iPhone 6 Plus上运行。
如果我在Simulator上运行它(我知道由于iCloud Drive无法使用模拟器而无法运行),我收到崩溃错误:'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[3]'
答案 0 :(得分:34)
嗯,你让我对这件事感兴趣,结果我花了很多时间在这个问题上,但是现在我已经开始工作了,我希望它对你有帮助!
要查看后台实际发生的情况,您可以查看~/Library/Mobile Documents/
,因为这是文件最终会显示的文件夹。另一个非常酷的实用程序是brctl
,用于监视在iCloud中存储文件后Mac上发生的情况。从终端窗口运行brctl log --wait --shorten
以启动日志。
在启用iCloud功能(选择了iCloud文档)后,首先要做的是为iCloud Drive Support(Enabling iCloud Drive Support)提供信息。 在再次运行应用之前,我还必须提高我的捆绑版本;我花了一些时间来解决这个问题。 将以下内容添加到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上的de 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);
}
答案 1 :(得分:1)
如果您打算使用UIDocument和iCloud,Apple的这本指南非常好: https://developer.apple.com/library/ios/documentation/DataManagement/Conceptual/UsingCoreDataWithiCloudPG/Introduction/Introduction.html
<强> EDITED 强>: 不知道有什么更好的指导,所以这可能会有所帮助:
您需要使用URLForUbuiquityContainerIdentifier
上的NSFileManager
函数来获取ubiquityURL(这应该是异步完成的)。
完成后,您可以使用以下代码创建文档。
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文件,这不是Apple认为的文件&#34;文档&#34;就iCloud同步而言。无需使用UIManagedDocument。删除完成处理程序的最后3行,而只是使用NSFileManager&#39; s
setUbiquitous:itemAtURL:destinationURL:error:
功能。第一个URL应该是PDF的本地路径。第二个URL应该是ubiquiuty容器中要保存为的路径。
您可能还需要查看NSFileCoordinator。 我认为Apple的这个指南可能是最相关的: https://developer.apple.com/library/ios/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/iCloud/iCloud.html