我正在使用UIDocumentPicker选择一个文件,但如果它很大,可能需要一段时间才能打开,这对用户来说不是特别好的体验。
我查看了Apple的iCloud编程指南,我似乎无法弄清楚如何实际下载文件并获得一些进度反馈,文档太模糊了。我知道我应该对NSMetadataItems做一些事情,但实际上并没有解释如何获得并使用它。
有人可以向我解释一下吗?
P.S。有没有比我更高代表的人用UIDocumentPicker和iCloudDrive标记这篇文章?
答案 0 :(得分:7)
据我所知,您只能使用以下方式检索进度反馈 Ubiquitous Item Downloading Status Constants仅提供3种状态:
因此,您无法获得量化的进度反馈,只有部分也可以下载。
为此,您需要准备并启动NSMetadataQuery,添加一些观察者并使用 NSURLUbiquitousItemDownloadingStatusKey 键检查NSMetadataItem的下载状态。
self.query = [NSMetadataQuery new];
self.query.searchScopes = @[ NSMetadataQueryUbiquitousDocumentsScope ];
self.query.predicate = [NSPredicate predicateWithFormat:@"%K like '*.yourextension'", NSMetadataItemFSNameKey];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidUpdate:) name:NSMetadataQueryDidUpdateNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidFinishGathering:) name:NSMetadataQueryDidFinishGatheringNotification object:nil];
[self.query startQuery];
然后,
- (void)queryDidUpdate:(NSNotification *)notification
{
[self.query disableUpdates];
for (NSMetadataItem *item in [self.query results]) {
NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];
NSError *error = nil;
NSString *downloadingStatus = nil;
if ([url getResourceValue:&downloadingStatus forKey:NSURLUbiquitousItemDownloadingStatusKey error:&error] == YES) {
if ([downloadingStatus isEqualToString:NSURLUbiquitousItemDownloadingStatusNotDownloaded] == YES) {
// Download
}
// etc.
}
}
[self.query enableUpdates];
}
答案 1 :(得分:2)
来自NSMetadataQuery
的进度反馈通过通知发生。更新频率默认为每秒一次(可以通过设置notificationBatchingInterval
来更改)。更新的对象封装在通知的userInfo
dict中,作为NSMetadataItem
的数组。下载反馈已包含在每个项目的密钥NSMetadataUbiquitousItemPercentDownloadedKey
中。由于数组是内部可变的,我们需要告诉NSMetadataQuery
在我们枚举结果时禁用更新。这很重要,否则会发生奇怪的崩溃。
典型的实现可能如下所示:
- (void) queryDidUpdate:(NSNotification *)notification {
[self.mdQuery disableUpdates];// we don't want to receive a new update while we still process the old one
NSArray *addedItems = notification.userInfo[NSMetadataQueryUpdateAddedItemsKey];
NSArray *remItems = notification.userInfo[NSMetadataQueryUpdateRemovedItemsKey];
NSArray *changedItems = notification.userInfo[NSMetadataQueryUpdateChangedItemsKey];
// add
for (NSMetadataItem *mdItem in addedItems) {
NSURL *url = [mdItem valueForKey:NSMetadataUbiquitousItemURLInLocalContainerKey];
// do something...
}
// remove
for (NSMetadataItem *mdItem in remItems) {
NSURL *url = [mdItem valueForKey:NSMetadataUbiquitousItemURLInLocalContainerKey];
// do something...
}
// change
for (NSMetadataItem *mdItem in changedItems) {
NSURL *url = [mdItem valueForKey:NSMetadataUbiquitousItemURLInLocalContainerKey];
// uploading
BOOL uploading = [(NSNumber *)[mdItem valueForKey:NSMetadataUbiquitousItemIsUploadingKey] boolValue];
if (uploading) {
NSNumber *percent = [mdItem valueForKey:NSMetadataUbiquitousItemPercentUploadedKey];
cell.progressView.progress = percent.floatValue;
// do something...
}
// downloading
BOOL downloading = [(NSNumber *)[mdItem valueForKey:NSMetadataUbiquitousItemIsDownloadingKey] boolValue];
if (downloading) {
NSNumber *percent = [mdItem valueForKey:NSMetadataUbiquitousItemPercentDownloadedKey];
cell.progressView.progress = percent.floatValue;
// do something...
}
}
[self.mdQuery enableUpdates];
}