我有一个使用新NSURLSession
API后台下载的应用。当下载以提供NSURLSessionDownloadTaskResumeData
的方式取消或失败时,我存储数据blob以便以后可以恢复。我注意到野外崩溃的时间非常少:
Fatal Exception: NSInvalidArgumentException
Invalid resume data for background download. Background downloads must use http or https and must download to an accessible file.
此处发生错误,其中resumeData
为NSData
blob,session
为NSURLSession
的实例:
if (resumeData) {
downloadTask = [session downloadTaskWithResumeData:resumeData];
...
数据由Apple API提供,序列化,然后在以后进行反序列化。它可能已损坏,但它永远不会为零(如if语句检查)。
如何提前检查resumeData
是否无效,以免我的应用程序崩溃?
答案 0 :(得分:25)
这是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];
}
编辑(iOS 7.1不再是NDA了):我从与苹果工程师的Twitter交流中得到了这个,他建议做什么,并且我写了上面的实现
答案 1 :(得分:1)
我还没有找到如何判断数据是否有效的答案。
但是,我现在正在解决这个问题:
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 :(得分:1)
实际上,简历数据是一个plist文件。 它包含以下键:
NSURLSessionResumeServerDownloadDate 所以你需要做的步骤是: