AFN 问题
问题一
问题描述:
Error Domain=com.alamofire.error.serialization.response Code=-1016 “Request failed: unacceptable content-type: text/html
• 描述 AFN 返回的数据默认会按照 JSON 格式反序列化这就导致,当返回的数据不能转换为JSON 格式的时候(例如字符串),那么就会出错
• 源框架中只是支持了 json
原因分析:
- 在AFNetworking框架的AFURLResponseSerialization.m文件中有如下初始化方法
- (instancetype)init {
self = [super init];
if (!self) {
return nil;
}
self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", nil];
return self;
}
这里默认返回的序列化对象可接受的内容类型中没有我们可能需要的 text/html 类型,因此需要添加上.不过最好不要在框架的这个位置添加,因为框架更新后有可能导致失效.要在自己创建 manager 对象之后重新设置acceptableContentTypes ,其中添加需要识别的类型即可.
- 在AFNetworking框架的AFHTTPSessionManager.m文件中有如下初始化方法
- (instancetype)initWithBaseURL:(NSURL *)url
sessionConfiguration:(NSURLSessionConfiguration *)configuration
{
self = [super initWithSessionConfiguration:configuration];
if (!self) {
return nil;
}
// Ensure terminal slash for baseURL path, so that NSURL +URLWithString:relativeToURL: works as expected
if ([[url path] length] > 0 && ![[url absoluteString] hasSuffix:@"/"]) {
url = [url URLByAppendingPathComponent:@""];
}
self.baseURL = url;
self.requestSerializer = [AFHTTPRequestSerializer serializer];
self.responseSerializer = [AFJSONResponseSerializer serializer];
return self;
}
由上述代码可知,默认的请求序列化对象是AFHTTPRequestSerializer(单纯的二进制),默认的返回序列化对象是AFJSONResponseSerializer(针对 JSON 格式的二进制),因此为了支持解析我们需要的 text/html 类型返回值,需要把返回序列化对象更改为 AFHTTPResponseSerializer
解决方法事例:
- (void)get2
{
//1.创建管理
AFHTTPSessionManager* manager = [AFHTTPSessionManager manager];
NSDictionary* params = @{ @"username" : @"zhangsan",
@"password" : @"zhang" };
//1.1 设置默认解析方法
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
//1.2 设置解析参数
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html", nil];
//2.发送请求
[manager GET:@"http://localhost/login.html" parameters:nil success:^(NSURLSessionDataTask* _Nonnull task, id _Nonnull responseObject) {
NSLog(@"%@", [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]);
}
failure:^(NSURLSessionDataTask* _Nullable task, NSError* _Nonnull error) {
NSLog(@"%@", error);
}];
}
问题二—HTTPS 安全证书问题
问题描述
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9843)
问题解决
设置manager.securityPolicy.validatesDomainName = NO;即可
事例代码
//1.创建管理
AFHTTPSessionManager* manager = [AFHTTPSessionManager manager];
//2.设置证书--解决 https 问题
manager.securityPolicy.validatesDomainName = NO;
//2.1 设置返回解析器
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
//2.2 设置可接受的返回类型
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html", nil];
//3.
[manager GET:@"https://mail.itcast.cn" parameters:nil success:^(NSURLSessionDataTask* _Nonnull task, id _Nonnull responseObject) {
NSLog(@"%@", [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]);
}
failure:^(NSURLSessionDataTask* _Nullable task, NSError* _Nonnull error) {
NSLog(@"%@", error);
}];
附录—AFN 中请求/响应对应的序列化类
请求:
<AFURLRequestSerialization>
AFHTTPRequestSerializer //请求默认的方式,就是最普通的二进制
AFJSONRequestSerializer //JSON格式的二进制,表示发给服务器的是一个JSON格式的二进制
AFPropertyListRequestSerializer //Plist格式,开发中基本不用
响应:
<AFURLResponseSerialization>
AFHTTPResponseSerializer //最普通的二进制
AFJSONResponseSerializer //默认的处理方法,表示AFN帮我们把最普通的二进制解析成JSON了
AFXMLParserResponseSerializer //XML Sax
AFXMLDocumentResponseSerializer (Mac OS X) //DOM
AFPropertyListResponseSerializer //PList
AFImageResponseSerializer //图片
AFCompoundResponseSerializer //混合