概況:
這部分比較簡單,一共有以下幾個類:
- 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];
}
複製程式碼