# backgroundDownload **Repository Path**: songfengwang/backgroundDownload ## Basic Information - **Project Name**: backgroundDownload - **Description**: 断点续传,后台下载 - **Primary Language**: Objective-C - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2019-07-03 - **Last Updated**: 2024-05-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # backgroundDownload #### 介绍 断点续传,后台下载 在iOS10上恢复NSUrlSession iOS 10将很快发布,因此值得测试应用程序与它的兼容性。在此类测试期间,我们发现我们的应用程序无法在iOS10上恢复后台下载。在以前的版本上运行良好的代码在模拟器和设备上都不适用于新版本。 下载失败。在xcode控制台中,您可以看到: 2016-09-02 16:11:24.913 HalfTunes[35205:2279228] *** -[NSKeyedUnarchiver initForReadingWithData:]: data is NULL 2016-09-02 16:11:24.913 HalfTunes[35205:2279228] *** -[NSKeyedUnarchiver initForReadingWithData:]: data is NULL 2016-09-02 16:11:24.913 HalfTunes[35205:2279228] Invalid resume data for background download. Background downloads must use http or https and must download to an accessible file. 这个问题起源于currentRequest和originalRequest NSKeyArchived编码的异常根“NSKeyedArchiveRootObjectKey”而不是NSKeyedArchiveRootObjectKey常量,它是字面上的“root”和NSURL(Mutable)Request的编码过程中的一些其他行为不端。 - (NSData *)correctRequestData:(NSData *)data { if (!data) { return nil; } if ([NSKeyedUnarchiver unarchiveObjectWithData:data]) { return data; } NSMutableDictionary *archive = [NSPropertyListSerialization propertyListWithData:data options:NSPropertyListMutableContainersAndLeaves format:nil error:nil]; if (!archive) { return nil; } int k = 0; while ([[archive[@"$objects"] objectAtIndex:1] objectForKey:[NSString stringWithFormat:@"$%d", k]]) { k += 1; } int i = 0; while ([[archive[@"$objects"] objectAtIndex:1] objectForKey:[NSString stringWithFormat:@"__nsurlrequest_proto_prop_obj_%d", i]]) { NSMutableArray *arr = archive[@"$objects"]; NSMutableDictionary *dic = [arr objectAtIndex:1]; id obj; if (dic) { obj = [dic objectForKey:[NSString stringWithFormat:@"__nsurlrequest_proto_prop_obj_%d", i]]; if (obj) { [dic setObject:obj forKey:[NSString stringWithFormat:@"$%d",i + k]]; [dic removeObjectForKey:[NSString stringWithFormat:@"__nsurlrequest_proto_prop_obj_%d", i]]; arr[1] = dic; archive[@"$objects"] = arr; } } i += 1; } if ([[archive[@"$objects"] objectAtIndex:1] objectForKey:@"__nsurlrequest_proto_props"]) { NSMutableArray *arr = archive[@"$objects"]; NSMutableDictionary *dic = [arr objectAtIndex:1]; if (dic) { id obj; obj = [dic objectForKey:@"__nsurlrequest_proto_props"]; if (obj) { [dic setObject:obj forKey:[NSString stringWithFormat:@"$%d",i + k]]; [dic removeObjectForKey:@"__nsurlrequest_proto_props"]; arr[1] = dic; archive[@"$objects"] = arr; } } } id obj = [archive[@"$top"] objectForKey:@"NSKeyedArchiveRootObjectKey"]; if (obj) { [archive[@"$top"] setObject:obj forKey:NSKeyedArchiveRootObjectKey]; [archive[@"$top"] removeObjectForKey:@"NSKeyedArchiveRootObjectKey"]; } NSData *result = [NSPropertyListSerialization dataWithPropertyList:archive format:NSPropertyListBinaryFormat_v1_0 options:0 error:nil]; return result; } - (NSMutableDictionary *)getResumDictionary:(NSData *)data { NSMutableDictionary *iresumeDictionary; if ([[NSProcessInfo processInfo] operatingSystemVersion].majorVersion >= 10) { NSMutableDictionary *root; NSKeyedUnarchiver *keyedUnarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; NSError *error = nil; root = [keyedUnarchiver decodeTopLevelObjectForKey:@"NSKeyedArchiveRootObjectKey" error:&error]; if (!root) { root = [keyedUnarchiver decodeTopLevelObjectForKey:NSKeyedArchiveRootObjectKey error:&error]; } [keyedUnarchiver finishDecoding]; iresumeDictionary = root; } if (!iresumeDictionary) { iresumeDictionary = [NSPropertyListSerialization propertyListWithData:data options:0 format:nil error:nil]; } return iresumeDictionary; } static NSString * kResumeCurrentRequest = @"NSURLSessionResumeCurrentRequest"; static NSString * kResumeOriginalRequest = @"NSURLSessionResumeOriginalRequest"; - (NSData *)correctResumData:(NSData *)data { NSMutableDictionary *resumeDictionary = [self getResumDictionary:data]; if (!data || !resumeDictionary) { return nil; } resumeDictionary[kResumeCurrentRequest] = [self correctRequestData:[resumeDictionary objectForKey:kResumeCurrentRequest]]; resumeDictionary[kResumeOriginalRequest] = [self correctRequestData:[resumeDictionary objectForKey:kResumeOriginalRequest]]; NSData *result = [NSPropertyListSerialization dataWithPropertyList:resumeDictionary format:NSPropertyListXMLFormat_v1_0 options:0 error:nil]; return result; } NSData *cData = [self correctResumData:self.resumeData]; if (!cData) { cData = self.resumeData; } self.downloadTask = [self.session downloadTaskWithResumeData:cData]; if ([self getResumDictionary:cData]) { NSDictionary *dict = [self getResumDictionary:cData]; if (!self.downloadTask.originalRequest) { NSData *originalData = dict[kResumeOriginalRequest]; [self.downloadTask setValue:[NSKeyedUnarchiver unarchiveObjectWithData:originalData] forKey:@"originalRequest"]; } if (!self.downloadTask.currentRequest) { NSData *currentData = dict[kResumeCurrentRequest]; [self.downloadTask setValue:[NSKeyedUnarchiver unarchiveObjectWithData:currentData] forKey:@"currentRequest"]; } } 如何解决error: failed to push some refs to 'xxx(远程库)' 出现错误的主要原因是的README.md文件不在本地代码目录中 可以通过如下命令进行代码合并【注:pull=fetch+merge] git pull --rebase origin master 此时再执行语句 git push -u origin master即可完成代码上传