AFURLResponseSerialization相对于AFURLRequestSerialization,一个是网络请求的序列化,一个是网络响应的序列化。AFURLResponseSerialization是将网络请求回来的数据
解析,
检查数据是否合法,把NSData数据转成相应的对象
在AFURLResponseSerialization类中包含了:
AFURLResponseSerialization协议
AFHTTPResponseSerializer
和
AFHTTPResponseSerializer的子类们
AFJSONResponseSerializer
AFXMLParserResponseSerializer
AFImageResponseSerializer
主要的检测方法:
/// 解析
response为对应的数据类型(JSON、XML、plist、Image)
- (
nullable
id
)responseObjectForResponse:(
nullable
NSURLResponse
*)response
data:(
nullable
NSData
*)data
error:(NSError * _Nullable __autoreleasing *)error;
/// 使用此方法来检测当前的
response是否有限
- (BOOL)validateResponse:(nullable NSHTTPURLResponse *)response
data:(nullable NSData *)data
error:(NSError * _Nullable __autoreleasing *)error;
– 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 (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) {
if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) {
return nil;
}
}
if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) {
return nil;
}
}
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 = [[NSString alloc] initWithData:data encoding:stringEncoding];
if (responseString && ![responseString isEqualToString:@" "]) {
/// 再将string使用UTF8编码转换成Data
data = [responseString dataUsingEncoding:NSUTF8StringEncoding];
if (data) {
if (data) {
if ([data length] > 0) {
/// 有效的data数据,使用系统自带的
NSJSONSerialization
转换成JSON
responseObject = [NSJSONSerialization JSONObjectWithData:data options:self.readingOptions error:&serializationError];
} else {
return nil;
}
} else {
return nil;
}
} else {
/// 错误信息
NSDictionary *userInfo = @{
NSLocalizedDescriptionKey: NSLocalizedStringFromTable(@"Data failed decoding as a UTF-8 string", @"AFNetworking", nil),
NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Could not decode string: %@", @"AFNetworking", nil), responseString]
};
serializationError = [NSError errorWithDomain:AFURLResponseSerializationErrorDomain code:NSURLErrorCannotDecodeContentData userInfo: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: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Could not decode string: %@", @"AFNetworking", nil), responseString]
};
serializationError = [NSError errorWithDomain:AFURLResponseSerializationErrorDomain code:NSURLErrorCannotDecodeContentData userInfo: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的键移除。。