错误: Invalid resume data for background download. Background downloads must use http or https and must download to an accessible file.
网上好多说这个错误在ios10中出现,如果调试的时候,点暂停下载,再重新发布到手机上,再点击开始下载,也会有这个错误。
解决办法:自定义一个NSURLSession分类,在ios10代替 - (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData;
NSURLSession+TYCorrectedResumeData.h
#import <Foundation/Foundation.h>
@interface NSURLSession (TYCorrectedResumeData)
- (NSURLSessionDownloadTask *)downloadTaskWithCorrectResumeData:(NSData *)resumeData;
@end
NSURLSession+TYCorrectedResumeData.m
//
// NSURLSession+TYCorrectedResumeData.m
// TYDownloadManagerDemo
//
// Created by tanyang on 2016/10/7.
// Copyright © 2016年 tany. All rights reserved.
//
#import "NSURLSession+TYCorrectedResumeData.h"
#import <UIKit/UIKit.h>
#define IS_IOS10ORLATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10)
@implementation NSURLSession (TYCorrectedResumeData)
- (NSURLSessionDownloadTask *)downloadTaskWithCorrectResumeData:(NSData *)resumeData {
NSString *kResumeCurrentRequest = @"NSURLSessionResumeCurrentRequest";
NSString *kResumeOriginalRequest = @"NSURLSessionResumeOriginalRequest";
NSData *cData = correctResumeData(resumeData);
cData = cData?cData:resumeData;
NSURLSessionDownloadTask *task = [self downloadTaskWithResumeData:cData];
NSMutableDictionary *resumeDic = getResumeDictionary(cData);
if (resumeDic) {
if (task.originalRequest == nil) {
NSData *originalReqData = resumeDic[kResumeOriginalRequest];
NSURLRequest *originalRequest = [NSKeyedUnarchiver unarchiveObjectWithData:originalReqData ];
if (originalRequest) {
[task setValue:originalRequest forKey:@"originalRequest"];
}
}
if (task.currentRequest == nil) {
NSData *currentReqData = resumeDic[kResumeCurrentRequest];
NSURLRequest *currentRequest = [NSKeyedUnarchiver unarchiveObjectWithData:currentReqData];
if (currentRequest) {
[task setValue:currentRequest forKey:@"currentRequest"];
}
}
}
return task;
}
#pragma mark- private
NSData * correctRequestData(NSData *data) {
if (!data) {
return nil;
}
// return the same data if it's correct
if ([NSKeyedUnarchiver unarchiveObjectWithData:data] != nil) {
return data;
}
NSMutableDictionary *archive = [[NSPropertyListSerialization propertyListWithData:data options:NSPropertyListMutableContainersAndLeaves format:nil error:nil] mutableCopy];
if (!archive) {
return nil;
}
NSInteger k = 0;
id objectss = archive[@"$objects"];
while ([objectss[1] objectForKey:[NSString stringWithFormat:@"$%ld",k]] != nil) {
k += 1;
}
NSInteger i = 0;
while ([archive[@"$objects"][1] objectForKey:[NSString stringWithFormat:@"__nsurlrequest_proto_prop_obj_%ld",i]] != nil) {
NSMutableArray *arr = archive[@"$objects"];
NSMutableDictionary *dic = arr[1];
id obj = [dic objectForKey:[NSString stringWithFormat:@"__nsurlrequest_proto_prop_obj_%ld",i]];
if (obj) {
[dic setValue:obj forKey:[NSString stringWithFormat:@"$%ld",i+k]];
[dic removeObjectForKey:[NSString stringWithFormat:@"__nsurlrequest_proto_prop_obj_%ld",i]];
[arr replaceObjectAtIndex:1 withObject:dic];
archive[@"$objects"] = arr;
}
i++;
}
if ([archive[@"$objects"][1] objectForKey:@"__nsurlrequest_proto_props"] != nil) {
NSMutableArray *arr = archive[@"$objects"];
NSMutableDictionary *dic = arr[1];
id obj = [dic objectForKey:@"__nsurlrequest_proto_props"];
if (obj) {
[dic setValue:obj forKey:[NSString stringWithFormat:@"$%ld",i+k]];
[dic removeObjectForKey:@"__nsurlrequest_proto_props"];
[arr replaceObjectAtIndex:1 withObject:dic];
archive[@"$objects"] = arr;
}
}
// Rectify weird "NSKeyedArchiveRootObjectKey" top key to NSKeyedArchiveRootObjectKey = "root"
if ([archive[@"$top"] objectForKey:@"NSKeyedArchiveRootObjectKey"] != nil) {
[archive[@"$top"] setObject:archive[@"$top"][@"NSKeyedArchiveRootObjectKey"] forKey: NSKeyedArchiveRootObjectKey];
[archive[@"$top"] removeObjectForKey:@"NSKeyedArchiveRootObjectKey"];
}
// Reencode archived object
NSData *result = [NSPropertyListSerialization dataWithPropertyList:archive format:NSPropertyListBinaryFormat_v1_0 options:0 error:nil];
return result;
}
NSMutableDictionary *getResumeDictionary(NSData *data) {
NSMutableDictionary *iresumeDictionary = nil;
if (IS_IOS10ORLATER) {
id root = nil;
id keyedUnarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
@try {
root = [keyedUnarchiver decodeTopLevelObjectForKey:@"NSKeyedArchiveRootObjectKey" error:nil];
if (root == nil) {
root = [keyedUnarchiver decodeTopLevelObjectForKey:NSKeyedArchiveRootObjectKey error:nil];
}
} @catch(NSException *exception) {
}
[keyedUnarchiver finishDecoding];
iresumeDictionary = [root mutableCopy];
}
if (iresumeDictionary == nil) {
iresumeDictionary = [NSPropertyListSerialization propertyListWithData:data options:NSPropertyListMutableContainersAndLeaves format:nil error:nil];
}
return iresumeDictionary;
}
NSData *correctResumeData(NSData *data) {
NSString *kResumeCurrentRequest = @"NSURLSessionResumeCurrentRequest";
NSString *kResumeOriginalRequest = @"NSURLSessionResumeOriginalRequest";
if (data == nil) {
return nil;
}
NSMutableDictionary *resumeDictionary = getResumeDictionary(data);
if (resumeDictionary == nil) {
return nil;
}
resumeDictionary[kResumeCurrentRequest] = correctRequestData(resumeDictionary[kResumeCurrentRequest]);
resumeDictionary[kResumeOriginalRequest] = correctRequestData(resumeDictionary[kResumeOriginalRequest]);
NSData *result = [NSPropertyListSerialization dataWithPropertyList:resumeDictionary format:NSPropertyListXMLFormat_v1_0 options:0 error:nil];
return result;
}
@end
更多有关下载方面,访问这遍文章:点击打开链接
我的业余技术微信公众号:YKJGZH,欢迎大家进入