概况:
这部分比较简单,一共有以下几个类:
- 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 (idserializer 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];}复制代码