实现断点下载和后台下载过程中,用到最多的是叫resumeData的东西,变化多端,神出鬼没,想要了解这个变化的可以参考这位大神的文章,https://www.jianshu.com/p/da565e14ef88,在仿写OC版轮子的过程中发现一个问题:上面那位大神由于采用的是swift语言,在解析resumeData过程中,用到下面这段代码
internal class func getResumeDictionary(_data:Data) ->NSMutableDictionary? {
varresumeDictionary:NSMutableDictionary?
if#available(OSX10.11,iOS9.0, *) {
letkeyedUnarchiver =NSKeyedUnarchiver(forReadingWith: data)
do{
resumeDictionary =trykeyedUnarchiver.decodeTopLevelObject(of:NSMutableDictionary.self, forKey:"NSKeyedArchiveRootObjectKey") ??nil
ifresumeDictionary ==nil{
resumeDictionary =trykeyedUnarchiver.decodeTopLevelObject(of:NSMutableDictionary.self, forKey:NSKeyedArchiveRootObjectKey)
}
}catch{}
keyedUnarchiver.finishDecoding()
}
ifresumeDictionary ==nil{
do{
resumeDictionary =try PropertyListSerialization.propertyList(from: data, options: PropertyListSerialization.ReadOptions(), format: nil) as? NSMutableDictionary
}catch{}
}
return resumeDictionary
}
注意这行代码:
keyedUnarchiver.decodeTopLevelObject(of: NSMutableDictionary.self, forKey: "NSKeyedArchiveRootObjectKey") ?? nil
点进去看看:
@available(OSX 10.11, iOS 9.0, *)
public func decodeTopLevelObject<DecodedObjectType>(of cls: DecodedObjectType.Type, forKey key: String) throws -> DecodedObjectType? where DecodedObjectType : NSObject, DecodedObjectType : NSCoding
根据传入的类型,查找NSKeyedArchiveRootObjectKey根键,解析为相应类型,最后得到一个key-value的字典,里面是这个信息:
35831BAC-A332-4538-BE99-82A1928A8F0E.png
从这里可以拿到你可能想要的信息,接收量、临时文件的名称等等信息,但在oc中蒙圈了,试了好几种方法,都无法解析出这个字典。
根据错误信息的反馈,最后找到了解决办法:
//将resumeData解析成字典
+ (NSMutableDictionary *)getResumeDictionary:(NSData *)data{
NSMutableDictionary *resumeDictionary = [NSMutableDictionary dictionary];
NSError *error;
if (@available(iOS 9.0,*)) {
id keyUnarchiver = [[NSKeyedUnarchiver alloc]initForReadingFromData:data error:&error];
@try {
NSError *decodeError1;
NSSet *typeSet = [NSSet setWithObjects:[NSDictionary class],[NSMutableData class],nil];
resumeDictionary = [keyUnarchiver decodeTopLevelObjectOfClasses:typeSet forKey:@"NSKeyedArchiveRootObjectKey" error:&decodeError1];
if (resumeDictionary == nil) {
resumeDictionary = [keyUnarchiver decodeTopLevelObjectOfClasses:typeSet forKey:NSKeyedArchiveRootObjectKey error:&decodeError1];
}
} @catch (NSException *exception) {
}
[keyUnarchiver finishDecoding];
}
return resumeDictionary;
}
resumeData根键为一个字典类型,再往里走一层为NSMutableData类型,只要将对应的解析类型传入,最后就能完整的解析出想要的结果,这是我对这个方法的理解,第一次发文,不对请指正。
网友评论