У меня есть базовая поддержка iCloud в моем приложении (синхронизация изменений, создание вездесущих и т.д.), но одним из основных недостатков до сих пор было отсутствие поддержки загрузки файлов, которые существуют (или имеют изменения) в облаке, но не синхронизируются с тем, что в настоящее время находится на диске.
Я добавил следующие методы в мое приложение на основе некоторого кода, предоставленного Apple, с помощью нескольких настроек:
Методы загрузки:
- (BOOL)downloadFileIfNotAvailable:(NSURL*)file {
NSNumber* isIniCloud = nil;
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])
return YES;
// Download the file.
NSFileManager* fm = [NSFileManager defaultManager];
NSError *downloadError = nil;
[fm startDownloadingUbiquitousItemAtURL:file error:&downloadError];
if (downloadError) {
NSLog(@"Error occurred starting download: %@", downloadError);
}
return NO;
}
}
}
// Return YES as long as an explicit download was not started.
return YES;
}
- (void)waitForDownloadThenLoad:(NSURL *)file {
NSLog(@"Waiting for file to download...");
id<ApplicationDelegate> appDelegate = [DataLoader applicationDelegate];
while (true) {
NSDictionary *fileAttribs = [[NSFileManager defaultManager] attributesOfItemAtPath:[file path] error:nil];
NSNumber *size = [fileAttribs objectForKey:NSFileSize];
[NSThread sleepForTimeInterval:0.1];
NSNumber* isDownloading = nil;
if ([file getResourceValue:&isDownloading forKey:NSURLUbiquitousItemIsDownloadingKey error:nil]) {
NSLog(@"iCloud download is moving: %d, size is %@", [isDownloading boolValue], size);
}
NSNumber* isDownloaded = nil;
if ([file getResourceValue:&isDownloaded forKey:NSURLUbiquitousItemIsDownloadedKey error:nil]) {
NSLog(@"iCloud download has finished: %d", [isDownloaded boolValue]);
if ([isDownloaded boolValue]) {
[self dispatchLoadToAppDelegate:file];
return;
}
}
NSNumber *downloadPercentage = nil;
if ([file getResourceValue:&downloadPercentage forKey:NSURLUbiquitousItemPercentDownloadedKey error:nil]) {
double percentage = [downloadPercentage doubleValue];
NSLog(@"Download percentage is %f", percentage);
[appDelegate updateLoadingStatusString:[NSString stringWithFormat:@"Downloading from iCloud (%2.2f%%)", percentage]];
}
}
}
И код, который запускает/проверяет загрузки:
if ([self downloadFileIfNotAvailable:urlToUse]) {
// The file is already available. Load.
[self dispatchLoadToAppDelegate:[urlToUse autorelease]];
} else {
// The file is downloading. Wait for it.
[self performSelector:@selector(waitForDownloadThenLoad:) withObject:[urlToUse autorelease] afterDelay:0];
}
Насколько я могу судить, приведенный выше код кажется прекрасным, но когда я делаю большое количество изменений на устройстве A, сохраните эти изменения, а затем откройте устройство B (чтобы запросить загрузку на устройстве B) это то, что я вижу в консоли:
2012-03-18 12:45:55.858 MyApp[12363:707] Waiting for file to download...
2012-03-18 12:45:58.041 MyApp[12363:707] iCloud download is moving: 0, size is 101575
2012-03-18 12:45:58.041 MyApp[12363:707] iCloud download has finished: 0
2012-03-18 12:45:58.041 MyApp[12363:707] Download percentage is 0.000000
2012-03-18 12:45:58.143 MyApp[12363:707] iCloud download is moving: 0, size is 101575
2012-03-18 12:45:58.143 MyApp[12363:707] iCloud download has finished: 0
2012-03-18 12:45:58.144 MyApp[12363:707] Download percentage is 0.000000
2012-03-18 12:45:58.246 MyApp[12363:707] iCloud download is moving: 0, size is 101575
2012-03-18 12:45:58.246 MyApp[12363:707] iCloud download has finished: 0
2012-03-18 12:45:58.246 MyApp[12363:707] Download percentage is 0.000000
2012-03-18 12:45:58.347 MyApp[12363:707] iCloud download is moving: 0, size is 177127
2012-03-18 12:45:58.347 MyApp[12363:707] iCloud download has finished: 0
2012-03-18 12:45:58.347 MyApp[12363:707] Download percentage is 0.000000
2012-03-18 12:45:58.449 MyApp[12363:707] iCloud download is moving: 0, size is 177127
2012-03-18 12:45:58.449 MyApp[12363:707] iCloud download has finished: 0
2012-03-18 12:45:58.450 MyApp[12363:707] Download percentage is 0.000000
Так по какой-то причине:
- Загрузка файла начинается без ошибок
- Атрибуты файла для состояния загрузки файла всегда возвращают, что он не загружается, не загружается, а прогресс составляет 0 процентов.
- Я застрял в цикле навсегда, даже если размер файла изменяется между проверками.
Что я делаю неправильно?