AFNetwork 3.0 源码解读(四)AFURLResponseSerialization
来源:互联网 发布:js中的offsettop 编辑:程序博客网 时间:2024/04/30 04:36
AFURLResponseSerialization相对于AFURLRequestSerialization,一个是网络请求的序列化,一个是网络响应的序列化。AFURLResponseSerialization是将网络请求回来的数据解析,检查数据是否合法,把NSData数据转成相应的对象
在AFURLResponseSerialization类中包含了:
AFURLResponseSerialization协议
AFHTTPResponseSerializer
和AFHTTPResponseSerializer的子类们
AFJSONResponseSerializer
AFXMLParserResponseSerializer
AFImageResponseSerializer
主要的检测方法:
/// 解析response为对应的数据类型(JSON、XML、plist、Image)
- (nullableid)responseObjectForResponse:(nullableNSURLResponse *)response
data:(nullableNSData *)data
error:(NSError *_Nullable__autoreleasing *)error;
/// 使用此方法来检测当前的response是否有限
- (BOOL)validateResponse:(nullableNSHTTPURLResponse *)response
data:(nullableNSData *)data
error:(NSError *_Nullable __autoreleasing *)error;
– validateResponse:data:error:方法主要是通过验证
MIMEType(数据类型),StatusCode(状态码:2xx为成功状态)是否满足条件来判断网络返回的数据是否有效,
– responseObjectForResponse:data:error: 方法主要作用是对返回的数据进行解析,
AFHTTPResponseSerializer的子类会重写这个方法,根据不同的需要解析成不同的结果,如
AFJSONResponseSerializer会将数据解析成为JSON数据,以AFJSONResponseSerializer的解析为例如下:
Data转JSON的顺序: data -> string -> data -> JSON
- (id)responseObjectForResponse:(NSURLResponse *)response
data:(NSData *)data
error:(NSError *__autoreleasing *)error
data:(NSData *)data
error:(NSError *__autoreleasing *)error
{
/// 判断返回的数据是否成功
if (![selfvalidateResponse:(NSHTTPURLResponse *)responsedata:dataerror:error]) {
if (!error ||AFErrorOrUnderlyingErrorHasCodeInDomain(*error,NSURLErrorCannotDecodeContentData,AFURLResponseSerializationErrorDomain)) {
returnnil;
}
}
if (!error ||AFErrorOrUnderlyingErrorHasCodeInDomain(*error,NSURLErrorCannotDecodeContentData,AFURLResponseSerializationErrorDomain)) {
returnnil;
}
}
NSStringEncoding stringEncoding =self.stringEncoding;
if (response.textEncodingName) {
CFStringEncoding encoding =CFStringConvertIANACharSetNameToEncoding((CFStringRef)response.textEncodingName);
if (encoding !=kCFStringEncodingInvalidId) {
stringEncoding = CFStringConvertEncodingToNSStringEncoding(encoding);
}
}
id responseObject =nil;
NSError *serializationError =nil;
if (response.textEncodingName) {
CFStringEncoding encoding =CFStringConvertIANACharSetNameToEncoding((CFStringRef)response.textEncodingName);
if (encoding !=kCFStringEncodingInvalidId) {
stringEncoding = CFStringConvertEncodingToNSStringEncoding(encoding);
}
}
id responseObject =nil;
NSError *serializationError =nil;
@autoreleasepool {
/// 根据自己设置的stringEncoding将data先转换成NSString
NSString *responseString = [[NSStringalloc]initWithData:dataencoding:stringEncoding];
if (responseString && ![responseString isEqualToString:@" "]) {
/// 再将string使用UTF8编码转换成Data
data = [responseStringdataUsingEncoding:NSUTF8StringEncoding];
if (data) {
if (data) {
if ([data length] > 0) {
/// 有效的data数据,使用系统自带的NSJSONSerialization转换成JSON
responseObject = [NSJSONSerializationJSONObjectWithData:dataoptions:self.readingOptionserror:&serializationError];
} else {
returnnil;
}
} else {
returnnil;
}
} else {
/// 错误信息
NSDictionary *userInfo =@{
NSLocalizedDescriptionKey:NSLocalizedStringFromTable(@"Data failed decoding as a UTF-8 string",@"AFNetworking",nil),
NSLocalizedFailureReasonErrorKey: [NSStringstringWithFormat:NSLocalizedStringFromTable(@"Could not decode string: %@", @"AFNetworking",nil), responseString]
};
serializationError = [NSErrorerrorWithDomain:AFURLResponseSerializationErrorDomaincode:NSURLErrorCannotDecodeContentDatauserInfo:userInfo];
}
}
}
if (self.removesKeysWithNullValues && responseObject) {
responseObject = AFJSONObjectByRemovingKeysWithNullValues(responseObject,self.readingOptions);
}
if (error) {
*error = AFErrorWithUnderlyingError(serializationError, *error);
}
return responseObject;
NSLocalizedDescriptionKey:NSLocalizedStringFromTable(@"Data failed decoding as a UTF-8 string",@"AFNetworking",nil),
NSLocalizedFailureReasonErrorKey: [NSStringstringWithFormat:NSLocalizedStringFromTable(@"Could not decode string: %@", @"AFNetworking",nil), responseString]
};
serializationError = [NSErrorerrorWithDomain:AFURLResponseSerializationErrorDomaincode:NSURLErrorCannotDecodeContentDatauserInfo:userInfo];
}
}
}
if (self.removesKeysWithNullValues && responseObject) {
responseObject = AFJSONObjectByRemovingKeysWithNullValues(responseObject,self.readingOptions);
}
if (error) {
*error = AFErrorWithUnderlyingError(serializationError, *error);
}
return responseObject;
}
AFJSONResponseSerializer使用系统内置的NSJSONSerialization解析json,NSJSON只支持解析UTF8编码的数据(还有UTF-16LE之类的,都不常用),所以要先把返回的数据转成UTF8格式。这里会尝试用HTTP返回的编码类型和自己设置的stringEncoding去把数据解码转成字符串NSString,再把NSString用UTF8编码转成NSData,再用NSJSONSerialization解析成对象返回。
同时AFJSONResponseSerializer会使用AFJSONObjectByRemovingKeysWithNullValues(responseObject,self.readingOptions)方法;递归会将返回的数据中值为nil或者为NSNull的键移除。。
0 0
- AFNetwork 3.0 源码解读(四)AFURLResponseSerialization
- AFNetworking 3.0 源码解读(四)之 AFURLResponseSerialization
- AFNetworking 3.0 源码解读(四)之 AFURLResponseSerialization
- AFNetwork 3.0 源码解读(三)AFURLRequestSerialization
- AFNetwork 3.0 源码解读(五)AFSecurityPolicy
- AFNetwork 3.0 源码解读(六)AFURLSessionManager
- AFNetwork 3.0 源码解读(二)网络情况监听
- AFNetwork 3.0 源码解读 (一) 新版本的变化
- 解读 AFNetwork 3.x源码 与 AFNetwork 2.x
- AFNetworking2.0源码解析AFURLResponseSerialization
- MPAndroidChart系列源码解读(四)
- jquery3.0源码解读(四)Callbacks
- THUCTC源码解读(四)
- AFNetworking3.1.0源码分析(十二)AFURLResponseSerialization
- AFNetworking源码 - Multipart协议,AFURLRequestSerialization和AFURLResponseSerialization
- jieba分词源码解读四
- 比特币源码解读四
- jemalloc源码解读(四)长度对齐算法
- Python模块,glob 文件路径查找之删除过期日志
- 学习字符串后的感受
- 链表
- [Android实例] 波浪动画效果,正弦曲线绘制
- Zoho Survey功能更新
- AFNetwork 3.0 源码解读(四)AFURLResponseSerialization
- linux内核开发(一)linux体系结构与内核结构
- Node.js TODO
- linux下编译,运行java文件
- 如何编写Android.mk 文件
- Local Notification not working since updating to IOS 8 and Xcode 6
- HttpClient使用详解
- ubuntu 网络设置
- javascript语法