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?
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ę
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
}
}
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:
- Sprawdź, czy dane są valid plist;
- Sprawdź plist mieć klucze jak powyżej;
- Sprawdź, czy plik temp istnieje;
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