Jak mogę sprawdzić, czy obiekt blob NSData jest ważny jako resumeData dla zadania nsurlsessiondownloadtask?

Mam aplikację, która używa pobierania w tle z nowymi API NSURLSession. Gdy pobieranie anuluje się lub nie powiedzie się w taki sposób, że NSURLSessionDownloadTaskResumeData jest dostarczony, przechowuję obiekt blob danych, aby mógł zostać wznowiony później. Bardzo malo czasu zauwazam wypadek w dziczy:

Fatal Exception: NSInvalidArgumentException
Invalid resume data for background download. Background downloads must use http or https and must download to an accessible file.

Błąd występuje tutaj, gdzie resumeData jest blobem NSData, a session jest instancją NSURLSession:

if (resumeData) {
    downloadTask = [session downloadTaskWithResumeData:resumeData];
    ...
Dane są dostarczane przez API Apple, są serializowane, a następnie deserializowane w późniejszym czasie. Może być uszkodzona, ale nigdy nie jest zerowa(jak sprawdza Instrukcja if).

Jak mogę sprawdzić z wyprzedzeniem, że resumeData jest nieprawidłowy, aby nie dopuścić do awarii aplikacji?

Author: Ian Terrell, 2014-02-20

3 answers

To jest obejście zaproponowane przez Apple:

- (BOOL)__isValidResumeData:(NSData *)data{
    if (!data || [data length] < 1) return NO;

    NSError *error;
    NSDictionary *resumeDictionary = [NSPropertyListSerialization propertyListWithData:data options:NSPropertyListImmutable format:NULL error:&error];
    if (!resumeDictionary || error) return NO;

    NSString *localFilePath = [resumeDictionary objectForKey:@"NSURLSessionResumeInfoLocalPath"];
    if ([localFilePath length] < 1) return NO;

    return [[NSFileManager defaultManager] fileExistsAtPath:localFilePath];
}

Edit (iOS 7.1 nie jest już NDA ' d): dostałem to z wymiany na Twitterze z inżynierem Apple, zasugerował, co zrobić, a ja napisałem powyższą implementację

 25
Author: rustyshelf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-17 11:03:03

Nie znalazłem odpowiedzi, Jak sprawdzić, czy dane są ważne z wyprzedzeniem.

Jednak obecnie pracuję nad tym problemem tak:

NSData *resumeData = ...;
NSURLRequest *originalURLRequest = ...;
NSURLSessionDownloadTask *downloadTask = nil;

@try {
    downloadTask = [session downloadTaskWithResumeData:resumeData];
}
@catch (NSException *exception) {
    if ([NSInvalidArgumentException isEqualToString:exception.name]) {
        downloadTask = [session downloadTaskWithRequest:originalURLRequest];
    } else {
        @throw exception; // only swallow NSInvalidArgumentException for resumeData
    }
}
 2
Author: Ian Terrell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-24 17:58:46

W rzeczywistości dane CV to plik plist. zawiera on następujący klucz:

  • NSURLSessionDownloadURL
  • NSURLSessionResumeBytesReceived
  • NSURLSessionResumeCurrentRequest
  • NSURLSessionResumeEntityTag
  • NSURLSessionResumeInfoTempFileName
  • NSURLSessionResumeInfoVersion
  • NSURLSessionResumeOriginalRequest
  • NSURLSessionResumeServerDownloaddate więc kroki, które musisz wykonać to:

    1. Sprawdź, czy dane są valid plist;
    2. Sprawdź plist mieć klucze jak powyżej;
    3. Sprawdź, czy plik temp istnieje;
 1
Author: user1939383,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-20 02:13:37