背景
最近开发水印相机,遇到了用户网络正常,但是上传超时、上传失败的问题。通过听云后台看到接口错误记录中,用户的 localDNS 为空,于是就有了接入 HTTPDNS 的需求。
实践
由于项目中网络请求使用的 AFNetworking 框架,接入第三方 HTTPDNS 后,需要修改 AFNetworking 中的内容,才能让请求走IP。
大致流程是接入 SDK——>注册 SDK——>获取 IP——>存储——>使用。这里可依据个人情况,在启动时进行 SDK注册,获取 IP 有两种方式,一是只在 APP 启动时获取一次,然后存储起来,APP使用过程中不需要更新。二是在 每次某个接口使用时都获取。
下面详细来看看接入的过程
阿里 HTTPDNS
- 按照快速入门中的步骤进行配置
- 添加域名,注意阿里的添加域名,可以添加全匹配和二级域名的方式
- 参考iOS SDK 接入进行接入
- 使用 CocoaPods 接入
这里到要骂人的地方了,按照阿里自己的官方文档上面写的 CocoaPod 安装的SDK不是最新的1
2
3
4
5
source 'https://github.com/CocoaPods/Specs.git'
source 'https://github.com/aliyun/aliyun-specs.git'
pod 'AlicloudHTTPDNS' # 注意,不能按照官方文档上的写法,后面不要加指定版本 - 项目中使用
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- (void)registerAliDNS{
HttpDnsService *httpdns = [[HttpDnsService alloc]initWithAccountID:@"Your Account ID" secretKey:@"Your Secret Key"];
[httpdns setCachedIPEnabled:NO];
// [httpdns cleanHostCache:nil];
[httpdns setHTTPSRequestEnabled:YES];
[httpdns setPreResolveHosts:@[
@"baidu.com",
]];
[httpdns setLogEnabled:YES];
[httpdns setPreResolveAfterNetworkChanged:YES];
// [httpdns setExpiredIPEnabled:YES];
// [httpdns setDelegateForDegradationFilter:self];
self.httpdns = httpdns;
NSUInteger delaySeconds = 1;
dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delaySeconds * NSEC_PER_SEC));
dispatch_after(when, dispatch_get_main_queue(), ^{
[self getUpFileHostIp];
});
}
- (void)getUpFileHostIp {
NSString *originalUrl = @"https://www.baidu.com";
NSURL *url = [NSURL URLWithString:originalUrl];
NSArray *ipsArray = [self.httpdns getIpsByHostAsync:url.host];
if (!IsNilArray(ipsArray)) {
self.hostIpStr = ipsArray.firstObject;
}
}
- 使用 CocoaPods 接入
腾讯云 HTTPDNS
- 按照入门指南中的步骤进行配置
- 注册/登录账号
- 开通服务
- 在开发配置中申请应用
- 在域名管理中添加域名,注意添加腾讯设置域名,只能添加 xxx.com,不能添加 xxx.yyy.com 这种
- 参考iOS SDK 文档进行接入
- 使用 CocoaPods 接入
1
pod 'MSDKDns'
- 项目中使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- (void)registerMSDKDns {
// 注意下面的使用方法,采用的是字典的方法来初始化,因为使用类的方法编译不通过。。。。
[[MSDKDns sharedInstance] initConfigWithDictionary:@{
@"dnsIp": @"119.29.29.98",
@"dnsId": @"Your AppID",
@"dnsKey": @"Your SecretKey", // 注意不同加密方式的 SecretKey 不同
@"encryptType": @0, // 加密方式
@"debug": @1,
// @"routeIp": @"",
}];
NSString *hostStr = @"baidu.com";
[[MSDKDns sharedInstance] WGGetHostByNameAsync:hostStr returnIps:^(NSArray *ipsArray) {
NSLog(@"解析 IP:%@", ipsArray);
if (ipsArray) {
self.hostIpStr = ipsArray.firstObject;
}
}];
}
- 使用 CocoaPods 接入
使用
检测本地是否使用 HTTP、HTTPS 的代理,如果有代理,建议不要使用 HTTPDNS —— iOS SDK 文档
1 |
|
用 HTTPDNS 返回的 IP 替换掉 URL 中的域名,指定下 HTTP 头的 host 字段。
1 |
|
项目中使用的是 AFNetworking,修改 AFNetworking 中 AFURLSessionMananger.m
类:
- 添加
evaluateServerTrust:forDmain:
方法 - 修改
URLSession:task:didReceiveChallenge:completionHandler:
方法
1 |
|
测试
按照上面的接入步骤接入完成后进行测试,上传图片出现了:首次失败、再次成功的情况,失败的原因是,疑似不受信任服务器xxx.xx.xxx.xx,还需要再修改AFSecurityPolicy
类
1 |
|
加入后再次测试,完美运行
总结
- 接入前,先考虑考虑要接入的方式,即:刷新 HTTPDNS 的逻辑
- 接入时:
- 阿里 HTTPDNS 需要注意 Pod 中依赖不要按照官方文档设置版本;
- 腾讯的 HTTPDNS 则要注意初始化的方法;
- 注意两家平台上设置域名时的不同;
- 接入后:
- 修改AFNetworking 中
AFURLSessionMananger.m
类 - 修改
AFSecurityPolicy
类
- 修改AFNetworking 中