我们使用AFNetworking
时常用的解析器是AFJSONResponseSerializer
,这样可以在block中直接得到字典或数组对象,因为AFNetworking
已经帮我们序列化好了,我们可以直接使用。
但是在一些情况下AFN
会抛出异常,如-1016
和3840
的错误,这个时候必须对服务器响应和AFN
进行分析。
常用的AFN配置代码类似于:
@interface XLHTTPSessionManager : AFHTTPSessionManager
+(instancetype)defaultManager;
-(void)configCommonHttpHeaders:(NSDictionary *)headers;
@end
@implementation XLHTTPSessionManager
+(instancetype)defaultManager{
XLHTTPSessionManager *manager = [self manager];
if (!manager) {
return manager;
}
AFJSONResponseSerializer *response = [AFJSONResponseSerializer serializer];
response.removesKeysWithNullValues = YES;
[manager setResponseSerializer:response];
[manager setRequestSerializer:[AFJSONRequestSerializer serializer]];
manager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
return manager;
}
@end
使用时是这样的:
XLHTTPSessionManager *manager = [XLHTTPSessionManagerdefaultManager];
[managerGET:url parameters:paramDic success:^(NSURLSessionDataTask *task, id responseObject) {
NSDictionary *responseDic = responseObject;
} failure:^(NSURLSessionDataTask *task, NSError *error) {
}];
该配置会将服务器响应当作json来处理,AFNetworking
会以json
的形式去解析,将服务器返回数据解析成一个字典或数组。
如果服务器返回json
格式的数据,AFNetworking
的序列化器会解析成功;但如果服务器返回xlm或html或其它无意义字符串,AFN
无法解析得到字典或数组对象从而抛异常。实际上请求是成功的,只是用AFJSONResponseSerializer
解析器无法解析而已。
AFN抛出异常主要有以下几种情况:
1.报错-1016:
Error Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: text/html" UserInfo={com.alamofire.serialization.response.error.response=
NSLocalizedDescription=Request failed: unacceptable content-type: text/html
2.报错3840:
Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}
产生报错的原因,都是由于后台返回的不是一个有效的JSON对象,而AFN
以JSON的标准来解析,因为无法正常序列化JSON而抛出了一个error。
解决办法也比较简单,以下是解决思路:
一、AFN
默认还是以JSON解析器对服务器返回数据进行JSON序列化,确保服务器返回JSON时能正确解析;在某些接口非常确认服务器响应非JSON时,在代码中重新设置解析器为 AFHTTPResponseSerializer,亦能确保服务器响应为非JSON时可以正确解析。
二、最后回归到代码,看看代码中的具体实现:
解决方法如下:
XLHTTPSessionManager *manager = [XLHTTPSessionManager defaultManager];
manager.responseSerializer = [AFHTTPResponseSerializerserializer];
[manager POST:url parameters:nilsuccess:^(NSURLSessionDataTask *task, id responseObject) {
NSString *responseStr = [[NSStringalloc]initWithData:responseObject encoding:NSUTF8StringEncoding];
DDLogInfo(@"--------- %@",responseStr);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
}];