iOS SDK开发指南
本文档介绍了阿里云公共DNS iOS SDK的接入和开发方式。
1.概述
阿里云公共DNS SDK是阿里云面向广大移动开发者提供DNS域名解析服务的开发工具包。
开发者利用本SDK,可以在自己的iOS APP中轻松接入阿里云公共DNS,解决域名解析异常的问题,低成本实现域名解析精准调度。您可以参考Demo示例工程源码了解如何使用本SDK。
iOS 14 开始系统原生支持两种标准规范的 Encrypted DNS, 分别是 DNS over TLS 与 DNS over HTTPS,您可以参考iOS14原生加密DNS方案了解如何设置阿里云公共DNS为加密DNS默认解析器。
SDK当前版本封装了阿里公共DNS的DoH JSON API,提供接口函数给iOS APP进行域名解析,并且提供了基于TTL和LRU策略的高效域名缓存功能。在公共DNS原有功能的基础上,SDK还可以为用户带来以下优势:
简单易用:
用户仅需集成我们提供的SDK,便可接入阿里云公共DNS业务。接入方法简单易用,为用户提供更为轻松便捷的解析服务。
零延迟:
SDK内部实现了LRU的缓存机制,将每次域名解析后的IP缓存到本地;并且主动更新TTL过期缓存,保证缓存及时有效,从而帮助用户达到域名解析零延迟的效果。
2.SDK集成
2.1 SDK集成
您需先在控制台注册自己的应用,获取应用的唯一标识Account ID。
通过控制台的链接获取阿里公共DNS iOS SDK。
获取到的SDK的
pdns-sdk-ios.framework
后,手动集成到自己工程中。引入系统库:
Foundation.framework
SystemConfiguration.framework
CoreFoundation.framework
CoreTelephony.framework
工程Build Settings中Other Linker Flags 加入
-ObjC
在
application:didFinishLaunchingWithOptions:
初始化SDK。
DNSResolver *resolver = [DNSResolver share];
resolver.accountId = @"您在控制台注册应用时分配的Account ID";
2.2 自动集成(Cocoapods)
1.Podfile中指定仓库位置:(Master仓库不要遗漏)
source 'https://github.com/CocoaPods/Specs.git'
source 'https://github.com/aliyun/aliyun-specs.git'
2.为工程target添加依赖:
pod 'AlicloudPDNS'
3.API介绍
3.1 accountId
必传参数,您在控制台注册自己的应用后,控制台会为此应用生成唯一标识Account ID。
3.2 设置是否使用服务端IPV6地址
阿里云公共DNS服务支持IPv4、IPv6双栈访问。SDK默认使用IPv4地址访问DNS服务器进行解析。
如果需要通过IPv6地址访问DNS服务器进行解析(当前网络需要支持IPv6),则需要通过以下代码设置:
[DNSResolver share].ipv6Enable = YES;
3.3 short模式
阿里公共DNS的DoH JSON API返回数据分为全量JSON和简要IP数组格式。SDK默认为全量JSON格式。
若要设置为简要IP数组格式,则需要通过以下代码设置:
[DNSResolver share].shortEnable = YES;
3.4 scheme
在访问DNS服务器进行解析时,是通过HTTP协议解析,还是通过HTTPS协议解析,可通过scheme
属性进行设置。
SDK默认使用HTTP协议进行解析,建议使用HTTP协议进行解析,解析速度更快。若要使用HTTPS协议进行解析,则需要如下设置:
[DNSResolver share].scheme = DNSResolverSchemeHttps;
3.5 设置是否开启缓存
SDK可设置开启缓存功能,如果缓存功能开启,在第一次解析过域名后,后续再解析时, 优先获取缓存中的数据,可大大提高解析速度。
SDK默认开启缓存。若要设置不开启缓存,则需要通过以下代码设置:
[DNSResolver share].cacheEnable=NO;
3.6 设置是否开启定时更新过期缓存
SDK在缓存功能已开启的情况下,可设置开启定时主动更新过期缓存功能,如果该功能开启,SDK每分钟会自动更新过期缓存,保障用户缓存数据及时更新,但是可能会带来域名解析次数和客户端流量消耗的增多。
该功能默认开启,若要设置关闭,则需要通过以下代码设置:
[DNSResolver share].schedulePrefetchEnable=NO;
3.7 设置缓存数量
SDK若开启了缓存功能,可以自定义缓存数量(支持范围100~500之间)。
SDK默认的缓存数量为100个域名。若要自定义缓存数量,可通过cacheCountLimit 属性进行设置:
[DNSResolver share].cacheCountLimit = 200;
3.8 设置是否开启IP测速
SDK可设置开启IP测速,如果IP测速开启,解析结果会优先返回速度最快的IP,数组会按照测速结果由快到慢的顺序排列。
SDK默认没有开启IP测速。若要设置开启IP测速,则需要通过以下代码设置:
[DNSResolver share].speedTestEnable=YES;
3.9 设置IP测速方式
SDK可设置IP测速的方式,如果IP测速开启,并且设置该参数为0,则使用ICMP探测;如果设置该参数为80、443或其它支持的端口号,则为socket指定端口探测。
SDK默认该参数为0。若要设置socket指定端口探测,则需要通过以下代码设置:
[DNSResolver share].speedPort = 80;
3.10 设置是否开启依据ISP网络区分域名缓存
SDK可设置是否开启依据ISP网络区分域名缓存。如果开启,则在不同网络环境下域名缓存数据分别存储互不影响。如果不开启,则不同网络下使用同一份域名缓存数据。
SDK默认没有开启依据ISP网络区分域名缓存功能,若要开启该功能,则需要通过以下代码设置:
[DNSResolver share].ispEnable = YES;
3.11 设置否定缓存最大TTL时间
SDK可设置否定缓存的最大TTL时间,如果设置了该时间,则会限制否定缓存的最大TTL不超过该设置时间。
SDK默认该参数为30s。若要设置否定缓存最大TTL时间,则需要通过以下代码设置:
[DNSResolver share].maxNegativeCache = 30;
3.12 设置缓存最大TTL时间
SDK可设置缓存的最大TTL时间,如果设置了该时间,则会限制缓存的最大TTL不超过该设置时间。
SDK默认该参数为3600s。若要设置缓存最大TTL时间,则需要通过以下代码设置:
[DNSResolver share].maxCacheTTL= 3600;
3.13 timeout
timeout
属性为域名解析的超时时间。默认超时时间为3s,用户可自定义超时时间,建议设置在2~5s之间。
3.14 设置开启鉴权
SDK在2.0.0版本后可设置鉴权功能来保障用户身份安全,不被第三方未授权者盗用。
如果用户不设置以下参数则不会开启鉴权功能,若要开启鉴权功能,参考产品鉴权文档在控制台创建AccessKey,并在APP中通过如下代码设置:
[DNSResolver share].accessKeyId = @"你的AccessKey ID";
[DNSResolver share].accesskeySecret = @"你的Accesskey Secret";
3.15 预解析
由于SDK自带缓存功能,在第一次解析完域名后,后续再次解析此域名可大大提高解析速度,所以建议在app启动后,可对app中可能要解析的域名进行预加载。
代码示例:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
DNSResolver *resolver = [DNSResolver share];
resolver.accountId = @"你的Accound ID";
resolver.cacheEnable = YES;
//对后续可能要解析的域名进行预加载
[resolver preloadDomains:@[@"域名1", @"域名2", @"域名3"] complete:^{
//所有域名预加载完成
}];
return YES;
}
4.服务API
代码示例:
/// 预解析域名信息,可在程序启动时调用,加快后续域名解析速度
/// 自动感知网络环境(ipv4-only、ipv6-only、ipv4和ipv6双栈)解析得到适用于当前网络环境的ip
/// @param domainArray 域名数组
/// @param complete 解析完成后回调
- (void)preloadDomains:(NSArray<NSString *> *)domainArray complete:(void(^)(void))complete;
/// 获取域名解析后的ip数组,自动感知网络环境(ipv4-only、ipv6-only、ipv4和ipv6双栈)得到适用于当前网络环境的ip
/// @param domain 域名
/// @param complete 回调(所有ip地址)
- (void)getIpsDataWithDomain:(NSString *)domain complete:(void(^)(NSArray<NSString *> *dataArray))complete;
/// 自动感知网络环境(ipv4-only、ipv6-only、ipv4和ipv6双栈)直接从缓存中获取适用于当前网络环境的ip数组,无需等待. 如无缓存,或有缓存但已过期并且enable为NO,则返回 nil
/// @param domain 域名
/// @param enable 是否允许返回过期ip
- (NSArray<NSString *> *)getIpsByCacheWithDomain:(NSString *)domain andExpiredIPEnabled:(BOOL)enable;
/// 获取域名解析后的IPv4信息数组
/// @param domain 域名
/// @param complete 回调(所有域名信息)
- (void)getIpv4InfoWithDomain:(NSString *)domain complete:(void(^)(NSArray<DNSDomainInfo *> *domainInfoArray))complete;
/// 获取域名解析后的IPv6信息数组
/// @param domain 域名
/// @param complete 回调(所有域名信息)
- (void)getIpv6InfoWithDomain:(NSString *)domain complete:(void(^)(NSArray<DNSDomainInfo *> *domainInfoArray))complete;
/// 获取域名解析后的IPv4信息
/// @param domain 域名
/// @param complete 回调(所有域名信息中随机一个)
- (void)getRandomIpv4InfoWithDomain:(NSString *)domain complete:(void(^)(DNSDomainInfo *domainInfo))complete;
/// 获取域名解析后的IPv6信息
/// @param domain 域名
/// @param complete 回调(所有域名信息中随机一个)
- (void)getRandomIpv6InfoWithDomain:(NSString *)domain complete:(void(^)(DNSDomainInfo *domainInfo))complete;
/// 获取域名解析后的IPv4地址数组
/// @param domain 域名
/// @param complete 回调(所有ip地址)
- (void)getIpv4DataWithDomain:(NSString *)domain complete:(void(^)(NSArray<NSString *> *dataArray))complete;
/// 获取域名解析后的IPv6地址数组
/// @param domain 域名
/// @param complete 回调(所有ip地址)
- (void)getIpv6DataWithDomain:(NSString *)domain complete:(void(^)(NSArray<NSString *> *dataArray))complete;
/// 获取域名解析后的IPv4地址
/// @param domain 域名
/// @param complete 回调(所有ip地址中随机一个)
- (void)getRandomIpv4DataWithDomain:(NSString *)domain complete:(void(^)(NSString *data))complete;
/// 获取域名解析后的IPv6地址
/// @param domain 域名
/// @param complete 回调(所有ip地址中随机一个)
- (void)getRandomIpv6DataWithDomain:(NSString *)domain complete:(void(^)(NSString *data))complete;
/// 预解析域名IPv4信息,可在程序启动时调用,加快后续域名解析速度
/// @param domainArray 域名数组
/// @param complete 解析完成后回调
- (void)preloadIpv4Domains:(NSArray<NSString *> *)domainArray complete:(void(^)(void))complete;
/// 预解析域名IPv6信息,可在程序启动时调用,加快后续域名解析速度
/// @param domainArray 域名数组
/// @param complete 解析完成后回调
- (void)preloadIpv6Domains:(NSArray<NSString *> *)domainArray complete:(void(^)(void))complete;
/// 直接从缓存中获取ipv4解析结果,无需等待. 如无缓存,或有缓存但已过期,并且enable为NO,则返回 nil
/// @param domain 域名
/// @param enable 是否允许返回过期ip
- (NSArray<NSString *> *)getIpv4ByCacheWithDomain:(NSString *)domain andExpiredIPEnabled:(BOOL)enable;
/// 直接从缓存中获取ipv6解析结果,无需等待. 如无缓存,或有缓存但已过期,并且enable为NO,则返回 nil
/// @param domain 域名
/// @param enable 是否允许返回过期ip
- (NSArray<NSString *> *)getIpv6ByCacheWithDomain:(NSString *)domain andExpiredIPEnabled:(BOOL)enable;
///统计信息收集
-(NSArray *)getRequestReportInfo;
5. API使用示例
5.1 设置基本信息
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
//唯一初始化方式
DNSResolver *resolver = [DNSResolver share];
//必传参数
resolver.accountId = @"您在控制台注册应用时分配的Account ID";
return YES;
}
5.2 域名解析接口
SDK提供了多种域名解析方法供用户选择和使用,可在DNSResolver.h
头文件中查看。 下面以其中一个自动区分网络环境(ipv4-only、ipv6-only、ipv4和ipv6双栈)的解析方法为例,进行说明。
接口声明:
/// 获取域名解析后的ip数组,自动区分网络环境(ipv4-only、ipv6-only、ipv4和ipv6双栈)得到适用于当前网络环境的ip
/// @param domain 域名
/// @param complete 回调(所有ip地址)
- (void)getIpsDataWithDomain:(NSString *)domain complete:(void(^)(NSArray<NSString *> *dataArray))complete;
接口调用示例:
[[DNSResolver share] getIpsDataWithDomain:@"www.taobao.com" complete:^(NSArray<NSString *> *dataArray) {
//dataArray为域名www.taobao.com所对应的IP地址数组
if (dataArray.count > 0) {
//TODO: 使用IP地址进行url连接
}
}];
5.3 直接从缓存中获取解析结果
接口声明:
/// 自动区分网络环境(ipv4-only、ipv6-only、ipv4和ipv6双栈)直接从缓存中获取适用于当前网络环境的ip数组,无需等待. 如无缓存,或有缓存但已过期,返回 nil
/// @param domain 域名
/// @param enable 是否允许返回过期ip
- (NSArray<NSString *> *)getIpsByCacheWithDomain:(NSString *)domain andExpiredIPEnabled:(BOOL)enable;
调用示例:
NSArray *result = [[DNSResolver share] getIpsByCacheWithDomain:@"域名" andExpiredIPEnabled:YES];
//拿到缓存结果
if (result.count > 0) {
//TODO: 使用ip地址进行url连接
}
注意:直接从缓存中拿缓存结果,速度较快,但无缓存、或者有缓存但缓存的解析结果已过期并且enable为NO时,返回结果会为nil。
5.4 统计信息收集
接口声明:
///统计信息收集
-(NSArray *)getRequestReportInfo;
调用示例:
NSArray *array = [[DNSResolver share] getRequestReportInfo];
数据格式:
(
{
avgRtt = "1"; // 域名平均解析时间ms
cacheDnsNum = 0; // 命中缓存次数
domain = "www.taobao.com"; // 解析的域名
gobackLocaldnsNum = 0; // 降级到LocalDNS的次数
localErro = 0; // LocalDNS解析失败次数
maxRtt = "60"; // 域名最大解析时间ms
noPermissionErro = 0; // 用户鉴权失败次数
noResponseErro = 0; // 请求超时无应答次数
requestPDnsNum = 1; // 递归查询的次数
sp = 中国移动; // 运营商名字
successNum = 1; // 解析成功次数
timeoutErro = 0; // 网络超时错误次数
type = 28; // ip类型1代表ipv4、28代表ipv6
urlParameterErro = 0; // 请求参数格式错误次数
urlPathErro = 0; // URL错误次数
}
......
);
6.注意事项
pdns-sdk-ios.framework
支持最低版本为iOS9.0。使用HTTP协议请求时,需要在
Info.plist
中设置App Transport Security Settings->Allow Arbitrary Loads
为YES
。通过阿里公共DNS获得域名的IP地址后,客户端可以使用这个IP发送业务请求,HTTP请求头的Host字段需改为原来的域名。
例如:
//ip为原域名解析后的ip地址 NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://%@", ip]]; NSMutableURLRequest *mutableReq = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval: 10]; //设置host [mutableReq setValue:@"原域名" forHTTPHeaderField:@"host"];
为帮助用户更快的使用阿里公共DNS iOS SDK,我们为开发者提供Demo程序,您可以
下载到本地作为参考。请点击这里,下载Demo程序。