概况:

这部分比较简单,一共有以下几个类:

  • AFHTTPResponseSerializer
  • AFJSONResponseSerializer : AFHTTPResponseSerializer
  • AFXMLParseResponseSerializer : AFHTTPResponseSerializer
  • AFXMLDocumentResponseSerializer : AFHTTPResponseSerializer
  • AFPropertyListResponseSerializer : AFHTTPResponseSerializer
  • AFImageResponseSerializer : AFHTTPResponseSerializer
  • AFCompoundResponseSerializer : AFHTTPResponseSerializer

AFHTTPResponseSerializer

这个类主要是验证response合法性,是否是有效的response

validateResponse:data:error:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
- (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

1
2
3
4
5
6
7
8
9
//只做了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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
- (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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//这个类主要是可以合并多中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];
}