2014-10-29 4 views
6

Używam identyfikatora UIDocumentPicker do wybrania pliku, ale jeśli jest duży, może trochę potrwać, a to nie jest szczególnie dobre doświadczenie dla użytkowników.W jaki sposób powiedzieć systemowi iOS, aby pobrać plik z dysku iCloud i uzyskać opinię o postępie

Przyjrzałem się przewodnikowi do programowania iCloud firmy Apple i nie potrafię wymyślić, jak faktycznie pobrać plik i uzyskać informację o postępie, dokumentacja jest zbyt ogólnikowa. Wiem, że mam coś zrobić z NSMetadataItems, ale nie ma wiele wyjaśnień, jak je zdobyć i użyć.

Czy ktoś może mi to wyjaśnić?

P.S. czy ktoś z wyższym numerem seryjnym niż ja taguje ten post za pomocą UIDocumentPicker i iCloudDrive?

+1

http://stackoverflow.com/a/23593943/4034301 może ona przydatna –

Odpowiedz

7

Według mojej wiedzy, można tylko pobierać informacje zwrotne postępu pomocą Ubiquitous Item Downloading Status Constants który przewiduje jedynie 3 stany:

  • NSURLUbiquitousItemDownloadingStatusCurrent
  • NSURLUbiquitousItemDownloadingStatusDownloaded
  • NSURLUbiquitousItemDownloadingStatusNotDownloaded

więc nie można mieć określone ilościowo informacje zwrotne dotyczące postępu, tylko częściowe aka pobrane lub nie.

Aby to zrobić, trzeba przygotować i rozpocząć NSMetadataQuery, dodać kilka obserwatorów i sprawdzić stan pobierania swoimi NSMetadataItem pomocą NSURLUbiquitousItemDownloadingStatusKey klucz.

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]; 

Następnie

- (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]; 
} 
+0

więc, jeśli chcę znaleźć konkretny plik, czy po prostu użyć tego w predykacie? – Weston

+0

Tak, możesz wyszukać konkretną nazwę, wszystkie pliki z rozszerzeniem, ścieżką, rozmiarem, datą utworzenia lub dowolnymi elementami zdefiniowanymi w [kluczach atrybutów] (https://developer.apple.com/library/ios/documentation/Cocoa /Reference/Foundation/Classes/NSMetadataItem_Class/index.html#//apple_ref/doc/constant_group/Attribute_Keys) z NSMetadataItem. Poprawiłem moją odpowiedź, aby dodać przykład. – HiDeo

+0

Jeszcze jedno pytanie, dlaczego wyłączasz aktualizacje, a potem je włączasz? – Weston

1

zwrotnego Postęp z NSMetadataQuery odbywa się poprzez powiadomień. Częstotliwość aktualizacji wynosi raz na sekundę na wartość domyślną (można ją zmienić, ustawiając wartość notificationBatchingInterval). Zaktualizowane obiekty są enkapsulowane w powiadomieniu jako tablice z NSMetadataItem. Pobierz opinię jest zawarta w kluczu NSMetadataUbiquitousItemPercentDownloadedKey każdego elementu. Ponieważ tablice są wewnętrznie modyfikowalne, musimy powiedzieć NSMetadataQuery, aby wyłączyć aktualizacje, podczas gdy my wyliczamy wyniki. Jest to ważne, w przeciwnym razie wystąpią dziwne awarie.

Typowa implementacja może wyglądać następująco:

- (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]; 
} 
Powiązane problemy