如何检查NSData blob是否有效作为NSURLSessionDownloadTask的resumeData?

时间:2014-02-20 00:46:10

标签: ios ios7 nsurlsession nsurlsessiondownloadtask

我有一个使用新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.

此处发生错误,其中resumeDataNSData blob,sessionNSURLSession的实例:

if (resumeData) {
    downloadTask = [session downloadTaskWithResumeData:resumeData];
    ...

数据由Apple API提供,序列化,然后在以后进行反序列化。它可能已损坏,但它永远不会为零(如if语句检查)。

如何提前检查resumeData是否无效,以免我的应用程序崩溃?

3 个答案:

答案 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文件。 它包含以下键:

  • NSURLSessionDownloadURL
  • NSURLSessionResumeBytesReceived
  • NSURLSessionResumeCurrentRequest
  • NSURLSessionResumeEntityTag
  • NSURLSessionResumeInfoTempFileName
  • NSURLSessionResumeInfoVersion
  • NSURLSessionResumeOriginalRequest
  • NSURLSessionResumeServerDownloadDate 所以你需要做的步骤是:

    1. 检查数据是否有效;
    2. 检查plist是否有上述键;
    3. 检查临时文件是否存在;