概况:
这部分比较简单,一共有以下几个类:
- AFHTTPResponseSerializer
- AFJSONResponseSerializer : AFHTTPResponseSerializer
- AFXMLParseResponseSerializer : AFHTTPResponseSerializer
- AFXMLDocumentResponseSerializer : AFHTTPResponseSerializer
- AFPropertyListResponseSerializer : AFHTTPResponseSerializer
- AFImageResponseSerializer : AFHTTPResponseSerializer
- AFCompoundResponseSerializer : AFHTTPResponseSerializer
AFHTTPResponseSerializer
这个类主要是验证response合法性,是否是有效的response
validateResponse:data:error:
- (BOOL)validateResponse:(NSHTTPURLResponse *)response
data:(NSData *)data
error:(NSError * __autoreleasing *)error
{
BOOL responseIsValid = YES;
NSError *validationError = nil;
if (response && [response isKindOfClass:[NSHTTPURLResponse class]]) {
//acceptableContentTypes里存储了当前serializer支持的content-type,
//可以在不同的子类init方法中指定。有时候,通过charlse去mock请求的response,
//没有通过rewrite功能重写content-type(默认是text/plain)为application/
//json就会被afnetworking显示请求失败,not accept content-type 错误。
if (self.acceptableContentTypes && ![self.acceptableContentTypes
containsObject:[response MIMEType]]) {
if ([data length] > 0 && [response URL]) {
NSMutableDictionary *mutableUserInfo = [@{
NSLocalizedDescriptio
nKey: [NSString
stringWithFormat:NSLo
calizedStringFromTable(
@"Request failed:
unacceptable
content-type: %@", @"
AFNetworking", nil),
[response MIMEType]],
NSURLErrorFailingURLE
rrorKey:[response URL
],
AFNetworkingOperation
FailingURLResponseErr
orKey: response,
} mutableCopy];
if (data) {
mutableUserInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] = data;
}
validationError = AFErrorWithUnderlyingError([NSError
errorWithDomain:AFURLResponseSerializationErrorDomain code:
NSURLErrorCannotDecodeContentData userInfo:mutableUserInfo]
, validationError);
}
responseIsValid = NO;
}
//acceptableStatusCodes存储了当前serializer支持的返回码,里面的值是在
//AFHTTPResponseSerializer基类
调用init方法中指定的。
if (self.acceptableStatusCodes && ![self.acceptableStatusCodes
containsIndex:(NSUInteger)response.statusCode] && [response URL]) {
NSMutableDictionary *mutableUserInfo = [@{
NSLocalizedDescriptionKey: [
NSString stringWithFormat:
NSLocalizedStringFromTable(@"
Request failed: %@ (%ld)", @"
AFNetworking", nil), [
NSHTTPURLResponse
localizedStringForStatusCode:
response.statusCode], (long)
response.statusCode],
NSURLErrorFailingURLErrorKey:[
response URL],
AFNetworkingOperationFailingURLR
esponseErrorKey: response,
} mutableCopy];
if (data) {
mutableUserInfo[
AFNetworkingOperationFailingURLResponseDataErrorKey] = data;
}
validationError = AFErrorWithUnderlyingError([NSError
errorWithDomain:AFURLResponseSerializationErrorDomain code:
NSURLErrorBadServerResponse userInfo:mutableUserInfo],
validationError);
responseIsValid = NO;
}
}
if (error && !responseIsValid) {
*error = validationError;
}
return responseIsValid;
}
AFHTTPResponseSerializer
//只做了response的验证逻辑,具体的反序列化在各个子类中实现。
//所有的serializer都要实现这个方法,在网络请求成功返回数据之后,AFNetworking就会调用serializer这个方法来反序列化。
- (id)responseObjectForResponse:(NSURLResponse *)response
data:(NSData *)data
error:(NSError *__autoreleasing *)error
{
[self validateResponse:(NSHTTPURLResponse *)response data:data error:error];
return data;
}
AFJSONResponseSerializer
responseObjectForResponse:data:error
- (id)responseObjectForResponse:(NSURLResponse *)response
data:(NSData *)data
error:(NSError *__autoreleasing *)error
{
if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:
error]) {
if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error,
NSURLErrorCannotDecodeContentData,
AFURLResponseSerializationErrorDomain)) {
return nil;
}
}
// Workaround for behavior of Rails to return a single space for `head
//:ok` (a workaround for a bug in Safari), which is not interpreted as
//valid input by NSJSONSerialization.
// See https://github.com/rails/rails/issues/1742
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;
@autoreleasepool {
NSString *responseString = [[NSString alloc] initWithData:data encoding
:stringEncoding];
if (responseString && ![responseString isEqualToString:@" "]) {
// Workaround for a bug in NSJSONSerialization when Unicode
//character escape codes are used instead of the actual character
// See http://stackoverflow.com/a/12843465/157142
data = [responseString dataUsingEncoding:NSUTF8StringEncoding];
if (data) {
if ([data length] > 0) {
responseObject = [NSJSONSerialization JSONObjectWithData:
data options:self.readingOptions error:&serializationError];
} 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];
}
}
}
//1.removesKeysWithNullValues表示当返回的数据dictionary的value为NSNULL的情况的时候,是
//否移除对应键值对。不处理会导致前端crash,如果不设置这个属性,默认是false
//2.self.readingOptions可以根据需求用来设置最后反序列化出字典是否未可变类型(
//NSJSONReadingMutableContainers),默认是不可变类型
if (self.removesKeysWithNullValues && responseObject) {
responseObject = AFJSONObjectByRemovingKeysWithNullValues(
responseObject, self.readingOptions);
}
if (error) {
*error = AFErrorWithUnderlyingError(serializationError, *error);
}
return responseObject;
}
AFCompoundResponseSerializer
responseObjectForResponse:data:error:
//这个类主要是可以合并多中Serializer的功能,存储在self.responseSerializers集合中。
- (id)responseObjectForResponse:(NSURLResponse *)response
data:(NSData *)data
error:(NSError *__autoreleasing *)error
{
//这里没有调用validateResponse方法,因为这个类处理的不是某一个具体的response类型
for (id <AFURLResponseSerialization> serializer in self.responseSerializers) {
if (![serializer isKindOfClass:[AFHTTPResponseSerializer class]]) {
continue;
}
NSError *serializerError = nil;
id responseObject = [serializer responseObjectForResponse:response data:data error:&serializerError];
if (responseObject) {
if (error) {
*error = AFErrorWithUnderlyingError(serializerError, *error);
}
return responseObject;
}
}
return [super responseObjectForResponse:response data:data error:error];
}