私にとって「機能する」のは単純です。
NSFileManager *fm = [NSFileManager defaultManager];
NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
if (ubiq == nil) {
return NO;
}
NSError *theError = nil;
[fm setUbiquitous:true itemAtURL:backupUrl destinationURL:[[ubiq URLByAppendingPathComponent:@"Documents" isDirectory:true] URLByAppendingPathComponent:backupName] error:&theError];
Appleは非UIスレッドを呼び出すように言っています。ファイルを「移動」させる。NSMetaDataQuery
次のようにクエリを実行できます。
self.query = [[NSMetadataQuery alloc] init];
[self.query setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];
NSPredicate *pred = [NSPredicate predicateWithFormat: @"%K like '*.db'", NSMetadataItemFSNameKey];
[self.query setPredicate:pred];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(queryDidFinishGathering:)
name:NSMetadataQueryDidFinishGatheringNotification
object:self.query];
[self.query startQuery];
- (void)queryDidFinishGathering:(NSNotification *)notification {
NSMetadataQuery *query = [notification object];
[query disableUpdates];
[query stopQuery];
[self loadData:query];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:query];
self.query = nil;
}
クエリ結果による列挙のサンプル:
- (void)loadData:(NSMetadataQuery *)query {
[self.backups removeAllObjects];
for (NSMetadataItem *item in [query results]) {
NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];
[self.backups addObject:url.lastPathComponent];
}
[_table reloadData];
[self.loadingBackupIndicator stopAnimating];
self.loadingIndicatorLabel.text = [NSString stringWithFormat: @"%d backups found", [self.backups count]];
}
そして、具体的なファイルの「ダウンロード」を開始するには:
NSFileManager *fm = [NSFileManager defaultManager];
NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
if (ubiq == nil) {
return NO;
}
NSError *theError = nil;
bool started = [fm startDownloadingUbiquitousItemAtURL:[[ubiq URLByAppendingPathComponent:@"Documents" isDirectory:true] URLByAppendingPathComponent:backupName] error:&theError];
NSLog(@"started download for %@ %d", backupName, started);
if (theError != nil) {
NSLog(@"iCloud error: %@", [theError localizedDescription]);
}
「ダウンロード中」のファイルをチェックします。
- (BOOL)downloadFileIfNotAvailable {
NSNumber *isIniCloud = nil;
NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
NSURL *file = [[ubiq URLByAppendingPathComponent:@"Documents" isDirectory:true] URLByAppendingPathComponent:self.backupName];
if ([file getResourceValue:&isIniCloud forKey:NSURLIsUbiquitousItemKey error:nil]) {
// If the item is in iCloud, see if it is downloaded.
if ([isIniCloud boolValue]) {
NSNumber* isDownloaded = nil;
if ([file getResourceValue:&isDownloaded forKey:NSURLUbiquitousItemIsDownloadedKey error:nil]) {
if ([isDownloaded boolValue]) {
[self.loadingBackupIndicator stopAnimating];
self.loadingIndicatorLabel.text = @"Downloaded";
....
[[NSFileManager defaultManager] copyItemAtPath:[file path] toPath:restorePath error:&theError ];
....
return YES;
}
self.loadingCheckTimer = [NSTimer timerWithTimeInterval:3.0f target:self selector:@selector(downloadFileIfNotAvailable) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:self.loadingCheckTimer forMode:NSDefaultRunLoopMode];
return NO;
}
}
}
return YES;
}
コードがそれほど長くなるとは思っていませんでした。ここで非常に生のスニペットを提供して申し訳ありません。上記は、概念を共有するだけで、コードの本番品質になる可能性があると言うつもりはありません。
私はまだそれを私のアプリ内でAppleに提出していないので、それがアプリストアに「承認」されるとは言えません(彼らが見つけたり気にかけたりした場合...)