All Products
Search
Document Center

Alibaba Cloud DNS:SDK for iOS developer guide

Last Updated:Apr 09, 2024

This topic describes Alibaba Cloud Public DNS SDK for iOS and how to use the SDK.

1. Overview

Alibaba Cloud Public DNS SDK is developed by Alibaba Cloud to provide the Domain Name System (DNS) resolution service for mobile developers.

The SDK allows mobile developers to use Alibaba Cloud Public DNS in their iOS apps. This prevents DNS resolution errors and implements precise scheduling of DNS requests at a low cost. The demo project source code provides an example on how to integrate the SDK with an iOS app and use Alibaba Cloud Public DNS in the iOS app.

Two native DNS encryption protocols are supported in the iOS 14 operating system: DNS over TLS (DoT) and DNS over HTTPS (DoH). For more information about how to configure Alibaba Cloud Public DNS as the default resolver for encrypted DNS, see Native encrypted DNS in iOS 14.

The SDK encapsulates the JSON API for DoH of Alibaba Cloud Public DNS. The SDK also provides functions for iOS apps to perform DNS resolution and supports efficient domain name caching based on time-to-live (TTL) and least recently used (LRU) policies. The SDK has the following benefits based on the features of Alibaba Cloud Public DNS:

  • Easy-to-use

    To use Alibaba Cloud Public DNS, you need to only integrate the SDK with your app. This allows you to use the DNS resolution service in an easier and more convenient manner.

  • DNS resolution without delay

    The SDK uses the LRU caching algorithm. This way, the IP addresses that are obtained from DNS resolution are cached on your on-premises server. The SDK also automatically updates the cache and deletes expired data based on TTL. This way, the cached data is always valid and DNS resolution can be effectively implemented without delay.

2. SDK integration

2.1 SDK integration

  1. Log on to the Alibaba Cloud DNS console. In the left-side navigation pane, click Public DNS. On the Public DNS page, click the Overview tab and view the account ID. The account ID is a unique ID that is automatically generated for your Alibaba Cloud account. You can use the account ID to use Alibaba Cloud Public DNS in your app.

  2. In the SDK Download section of the Traffic Access page, click Download for iOS to download the package for Alibaba Cloud Public DNS SDK for iOS.

  3. Add the pdns-sdk-ios.framework folder in the SDK package to your iOS app.

  4. Import the following system libraries to your app:

    • Foundation.framework

    • SystemConfiguration.framework

    • CoreFoundation.framework

    • CoreTelephony.framework

  5. Add -ObjC to Other Linker Flags in the Build Settings window of your Xcode project.

  6. Call the application:didFinishLaunchingWithOptions: method in your app to initialize the SDK. Use the following code in the method:

DNSResolver *resolver = [DNSResolver share];
resolver.accountId = @"Account ID that is generated when you register your app in the console";

2.2 Automatic integration (CocoaPods)

1. Specify the library location (including the master branch of the library) in Podfile.

source 'https://github.com/CocoaPods/Specs.git'
source 'https://github.com/aliyun/aliyun-specs.git'

2. Add dependencies to the target directory of your Xcode project.

pod 'AlicloudPDNS'

3. API reference

3.1 accountId

The accountId parameter specifies the account ID that is automatically generated after you register your app in the Alibaba Cloud DNS console.

3.2 Enable IPv6 access

Alibaba Cloud Public DNS supports IPv4 and IPv6 dual-stack access. By default, the SDK uses IPv4 addresses to access the DNS server.

If you want to use IPv6 addresses to access the DNS server, make sure that the current network supports IPv6 addresses and set the ipv6Enable parameter to YES to enable IPv6 access. The following section shows the sample code.

[DNSResolver share].ipv6Enable = YES;

3.3 Enable the short mode

Data that is returned by the JSON APIs for DoH of Alibaba Cloud Public DNS can be in the JSON format or an array of IP addresses. By default, the SDK uses the JSON format.

If you want the returned data to be arrays of IP addresses, configure the shortEnable parameter to enable the short mode. The following section shows the sample code.

[DNSResolver share].shortEnable = YES;

3.4 scheme

You can use the scheme parameter to specify whether to perform DNS resolution over HTTP or HTTPS.

By default, the SDK performs DNS resolution over HTTP. We recommend that you retain the default configuration because DNS resolution over HTTP is faster. If you want to perform DNS resolution over HTTPS, set the scheme parameter to DNSResolverSchemeHttps. The following section shows the sample code.

[DNSResolver share].scheme = DNSResolverSchemeHttps;

3.5 Enable the caching feature

You can use the SDK to specify whether to enable the caching feature. If this feature is enabled, the data that is obtained from the first resolution is saved in the cache and the cached data is preferentially returned for subsequent resolution requests. This significantly accelerates DNS resolution.

By default, the caching feature is enabled in the SDK. To disable the caching feature, set the cacheEnable parameter to NO. The following section shows the sample code.

[DNSResolver share].cacheEnable=NO;

3.6 Enable the scheduled update of expired cache data

When the caching feature is enabled, you can enable the scheduled update of expired cache data. Then, the SDK automatically replaces the expired cache data with new data every minute. This way, data in the cache can be updated in a timely manner, but the number of DNS resolutions and the consumption of client traffic may increase.

By default, this feature is enabled. If you want to disable this feature, set the schedulePrefetchEnable parameter to NO. The following section shows the sample code.

[DNSResolver share].schedulePrefetchEnable=NO;

3.7 Specify the maximum number of domain names whose DNS resolution results can be cached

If the caching feature is enabled, you can specify the maximum number of domain names whose DNS resolution results can be cached. Valid values: 100 to 500.

By default, the DNS resolution results for a maximum of 100 domain names can be cached by using the SDK. You can configure the cacheCountLimit parameter to specify the maximum cache size. The following section shows the sample code.

[DNSResolver share].cacheCountLimit = 200;

3.8 Enable connection speed testing for IP addresses

You can use the SDK to enable connection speed testing for IP addresses. If this feature is enabled, the DNS resolution result of the IP address with the highest connection speed is preferentially returned. The DNS resolution results are sorted in descending order of connection speeds.

By default, this feature is disabled in the SDK. To enable this feature, set speedTestEnable to YES. The following section shows the sample code.

[DNSResolver share].speedTestEnable=YES;

3.9 Specify the connection speed testing mode

You can specify the connection speed testing mode. If this feature is enabled and the speedPort parameter is set to 0, Internet Control Message Protocol (ICMP) packets are used to detect the connection speed. If the speedPort parameter is set to 80, 443, or another valid value, the port that is specified in the socket is used to detect the connection speed.

The default value of this parameter in the SDK is 0. To use the port that is specified in the socket for detection, you must specify the speedPort parameter. The following section shows the sample code.

[DNSResolver share].speedPort = 80;

3.10 Enable domain name caching based on ISP networks

You can use the SDK to enable domain name caching based on Internet service provider (ISP) networks. If this feature is enabled, the cached DNS resolution results are separately stored based on the network environments. If this feature is disabled, the same cached domain name data is used in different networks.

By default, this feature is disabled in the SDK. To enable this feature, set the ispEnable parameter to YES. The following section shows the sample code.

[DNSResolver share].ispEnable = YES;

3.11 Specify the maximum TTL for negative caching

You can use the SDK to specify the maximum TTL for negative caching. If you configure the maxNegativeCache parameter, the maximum TTL for negative caching cannot exceed the value of this parameter.

The default value of this parameter is 30 in the SDK, in seconds. The following section shows the sample code.

[DNSResolver share].maxNegativeCache = 30;

3.12 Specify the maximum TTL for caching

You can use the SDK to specify the maximum TTL for caching. If you configure the maxCacheTTL parameter, the maximum TTL for caching cannot exceed the value of this parameter.

The default value of this parameter is 3600 in the SDK, in seconds. The following section shows the sample code.

[DNSResolver share].maxCacheTTL= 3600;

3.13 timeout

The timeout parameter specifies the timeout period for DNS resolution. The default timeout period is 3 seconds. You can specify a custom timeout period based on your business requirements. We recommend that you set the timeout period to a value within the range of 2 to 5 seconds.

3.14 Enable authentication

You can use SDK 2.0.0 or later to enable authentication to protect user identities from being stolen by unauthorized third parties.

You can enable authentication only after you configure the following parameters. To enable authentication, create an AccessKey pair in the DNS console by following the instructions that are described in Service authentication and configure the accessKeyId and accesskeySecret parameters in your app. The following section shows the sample code.

[DNSResolver share].accessKeyId = @"Your AccessKey ID";
[DNSResolver share].accesskeySecret = @"Your AccessKey secret";

3.15 Preload domain names

The caching feature that is provided by the SDK accelerates the resolution of a domain name that has been resolved. We recommend that you preload the domain names that you want to resolve after you start your app.

Sample code:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
   // Override point for customization after application launch.
   
   DNSResolver *resolver = [DNSResolver share];
   resolver.accountId = @"Account ID that was generated after you activate Alibaba Cloud Public DNS";
   resolver.cacheEnable = YES;
   // Preload the domain names that you want to resolve.
   [resolver preloadDomains:@[@"Domain name 1", @"Domain name 2", @"Domain name 3"] complete:^{
       // All specified domain names are preloaded.
       
   }];
   
   return YES;
}

4. Service API operations

Sample code:

/// Pre-resolve an array of domain names. After you start your app, you can call this operation to cache DNS resolution results. This accelerates subsequent DNS resolution.
/// Automatically detect the IP address type that is supported by the current network environment, such as IPv4-only, IPv6-only, or IPv4/IPv6 dual-stack. Then, resolve the array of the domain names to the IP addresses that are supported by the current network environment.
/// @param domainArray The array of domain names that you want to resolve.
/// @param complete     Return DNS resolution results.
- (void)preloadDomains:(NSArray<NSString *> *)domainArray complete:(void(^)(void))complete;

/// Automatically detect the IP address type that is supported by the current network environment, such as IPv4-only, IPv6-only, or IPv4/IPv6 dual-stack. Then, resolve the domain name to the array of IP addresses that are supported by the current network environment. 
/// If the caching feature is enabled, the system preferentially tries to obtain cached data. If no data is cached or the cached data expires, a DNS request is sent to obtain the corresponding IP addresses. If the caching feature is not enabled, a DNS request is sent to obtain the corresponding IP addresses. 
/// @param domain           The domain name that you want to resolve.
/// @param complete       Return all IP addresses to which the domain name is resolved.
- (void)getIpsDataWithDomain:(NSString *)domain complete:(void(^)(NSArray<NSString *> *dataArray))complete;

/// Automatically detect the IP address type that is supported by the current network environment, such as IPv4-only, IPv6-only, or IPv4/IPv6 dual-stack. Then, obtain the array of IP addresses that are supported by the current network environment from the cache without delay.  
/// If no data is cached, nil is returned. If the cached data exists and the enable parameter is set to YES, the cached data is returned. If cached data expires, the domain name is asynchronously resolved to update the cached data. If the cached data exists and the enable parameter is set to NO, nil is returned when the cached data expires, and the domain name is asynchronously resolved to update the cached data. 
/// @param domain   The domain name that you want to resolve.
/// @param enable   Specify whether to return expired IP addresses.
- (NSArray<NSString *> *)getIpsByCacheWithDomain:(NSString *)domain andExpiredIPEnabled:(BOOL)enable;

/// Obtain an array of information about the IPv4 addresses to which a domain name is resolved.
/// If the caching feature is enabled, the system preferentially tries to obtain cached data. If no data is cached or the cached data expires, a DNS request is sent to obtain the corresponding IP addresses. If the caching feature is not enabled, a DNS request is sent to obtain the corresponding IP addresses. 
/// @param domain           The domain name that you want to resolve.
/// @param complete       Return the information about all the IPv4 addresses to which the domain name is resolved.
- (void)getIpv4InfoWithDomain:(NSString *)domain complete:(void(^)(NSArray<DNSDomainInfo *> *domainInfoArray))complete;

/// Obtain an array of information about the IPv6 addresses to which a domain name is resolved.
/// If the caching feature is enabled, the system preferentially tries to obtain cached data. If no data is cached or the cached data expires, a DNS request is sent to obtain the corresponding IP addresses. If the caching feature is not enabled, a DNS request is sent to obtain the corresponding IP addresses. 
/// @param domain           The domain name that you want to resolve.
/// @param complete       Return the information about all the IPv6 addresses to which the domain name is resolved.
- (void)getIpv6InfoWithDomain:(NSString *)domain complete:(void(^)(NSArray<DNSDomainInfo *> *domainInfoArray))complete;

/// Obtain the information about an IPv4 address to which a domain name is resolved.
/// If the caching feature is enabled, the system preferentially tries to obtain cached data. If no data is cached or the cached data expires, a DNS request is sent to obtain the corresponding IP address. If the caching feature is not enabled, a DNS request is sent to obtain the corresponding IP address. 
/// @param domain           The domain name that you want to resolve.
/// @param complete       Return the information about an IPv4 address to which the domain name is resolved.
- (void)getRandomIpv4InfoWithDomain:(NSString *)domain complete:(void(^)(DNSDomainInfo *domainInfo))complete;

/// Obtain the information about an IPv6 address to which a domain name is resolved.
/// If the caching feature is enabled, the system preferentially tries to obtain cached data. If no data is cached or the cached data expires, a DNS request is sent to obtain the corresponding IP address. If the caching feature is not enabled, a DNS request is sent to obtain the corresponding IP address. 
/// @param domain           The domain name that you want to resolve.
/// @param complete       Return the information about an IPv6 address to which the domain name is resolved.
- (void)getRandomIpv6InfoWithDomain:(NSString *)domain complete:(void(^)(DNSDomainInfo *domainInfo))complete;

/// Obtain the array of IPv4 addresses to which a domain name is resolved.
/// If the caching feature is enabled, the system preferentially tries to obtain cached data. If no data is cached or the cached data expires, a DNS request is sent to obtain the corresponding IP addresses. If the caching feature is not enabled, a DNS request is sent to obtain the corresponding IP addresses. 
/// @param domain           The domain name that you want to resolve.
/// @param complete       Return all IPv4 addresses to which the domain name is resolved.
- (void)getIpv4DataWithDomain:(NSString *)domain complete:(void(^)(NSArray<NSString *> *dataArray))complete;

/// Obtain the array of IPv6 addresses to which a domain name is resolved.
/// If the caching feature is enabled, the system preferentially tries to obtain cached data. If no data is cached or the cached data expires, a DNS request is sent to obtain the corresponding IP addresses. If the caching feature is not enabled, a DNS request is sent to obtain the corresponding IP addresses. 
/// @param domain           The domain name that you want to resolve.
/// @param complete       Return all IPv6 addresses to which the domain name is resolved.
- (void)getIpv6DataWithDomain:(NSString *)domain complete:(void(^)(NSArray<NSString *> *dataArray))complete;

/// Obtain an IPv4 address to which a domain name is resolved.
/// If the caching feature is enabled, the system preferentially tries to obtain cached data. If no data is cached or the cached data expires, a DNS request is sent to obtain the corresponding IP address. If the caching feature is not enabled, a DNS request is sent to obtain the corresponding IP address. 
/// @param domain           The domain name that you want to resolve.
/// @param complete       Return one of the IPv6 addresses to which the domain name is resolved.
- (void)getRandomIpv4DataWithDomain:(NSString *)domain complete:(void(^)(NSString *data))complete;

/// Obtain an IPv6 address to which a domain name is resolved.
/// If the caching feature is enabled, the system preferentially tries to obtain cached data. If no data is cached or the cached data expires, a DNS request is sent to obtain the corresponding IP address. If the caching feature is not enabled, a DNS request is sent to obtain the corresponding IP address. 
/// @param domain           The domain name that you want to resolve.
/// @param complete       Return one of the IPv6 addresses to which the domain name is resolved.
- (void)getRandomIpv6DataWithDomain:(NSString *)domain complete:(void(^)(NSString *data))complete;

/// Pre-resolve an array of domain names to IPv4 addresses. After you start your app, you can call this operation to cache the DNS resolution results. This accelerates subsequent DNS resolution.
/// @param domainArray  The array of domain names that you want to resolve.
/// @param complete         Return DNS resolution results.
- (void)preloadIpv4Domains:(NSArray<NSString *> *)domainArray complete:(void(^)(void))complete;

/// Pre-resolve an array of domain names to IPv6 addresses. After you start your app, you can call this operation to cache the DNS resolution results. This accelerates subsequent DNS resolution.
/// @param domainArray  The array of domain names that you want to resolve.
/// @param complete         Return DNS resolution results.
- (void)preloadIpv6Domains:(NSArray<NSString *> *)domainArray complete:(void(^)(void))complete;

/// Query the cache to obtain an IPv4 address to which the domain name is mapped.  
/// If no cached data exists, nil is returned. If the cached data exists and the enable parameter is set to YES, the cached data is returned. If cached data expires, the domain name is asynchronously resolved to update the cached data. If the cached data exists and the enable parameter is set to NO, nil is returned when the cached data expires, and the domain name is asynchronously resolved to update the cached data. 
/// @param domain   The domain name that you want to resolve.
/// @param enable   Specify whether to return expired IP addresses.
- (NSArray<NSString *> *)getIpv4ByCacheWithDomain:(NSString *)domain andExpiredIPEnabled:(BOOL)enable;

/// Query the cache to obtain an IPv6 address to which the domain name is mapped.  
/// If no cached data exists, nil is returned. If the cached data exists and the enable parameter is set to YES, the cached data is returned. If cached data expires, the domain name is asynchronously resolved to update the cached data. If the cached data exists and the enable parameter is set to NO, nil is returned when the cached data expires, and the domain name is asynchronously resolved to update the cached data. 
/// @param domain   The domain name that you want to resolve.
/// @param enable   Specify whether to return expired IP addresses.
- (NSArray<NSString *> *)getIpv6ByCacheWithDomain:(NSString *)domain andExpiredIPEnabled:(BOOL)enable;

/// Collect statistical information.
-(NSArray *)getRequestReportInfo;

5. Sample API calls

5.1 Configure basic information

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
   // Override point for customization after application launch.

   // The only method for initialization.
   DNSResolver *resolver = [DNSResolver share];
   // The required parameter.
   resolver.accountId = @"Account ID that is generated after you activate Alibaba Cloud Public DNS";
   
   return YES;
}

5.2 Resolve a domain name by calling an operation

The SDK provides various DNS resolution methods. For more information, see the header file DNSResolver.h. The following section describes a DNS resolution method that automatically detects the IP address type supported by the network environment, such as IPv4-only, IPv6-only, or IPv4/IPv6 dual-stack.

Operation declaration:

/// Automatically detect the IP address type that is supported by the current network environment, such as IPv4-only, IPv6-only, or IPv4/IPv6 dual-stack. Then, resolve the domain name to the array of the IP addresses that are supported by the current network environment.
/// If the caching feature is enabled, the system preferentially tries to obtain cached data. If no data is cached or the cached data expires, a DNS request is sent to obtain the corresponding IP addresses. If the caching feature is not enabled, a DNS request is sent to obtain the corresponding IP addresses. 
/// @param domain           The domain name that you want to resolve.
/// @param complete       Return all IP addresses to which the domain name is resolved.
- (void)getIpsDataWithDomain:(NSString *)domain complete:(void(^)(NSArray<NSString *> *dataArray))complete;

The following sample code provides an example on how to call the operation:

[[DNSResolver share] getIpsDataWithDomain:@"www.taobao.com" complete:^(NSArray<NSString *> *dataArray) {
    // dataArray is an array of IP addresses that correspond to the domain name www.taobao.com.
   if (dataArray.count > 0) {
       // TODO: Use the IP address to send a business request.
   }    
}];

5.3 Obtain the DNS resolution results from the cache

Operation declaration:

/// Automatically detect the IP address type that is supported by the current network environment, such as IPv4-only, IPv6-only, or IPv4/IPv6 dual-stack. Then, obtain the array of IP addresses that are supported by the current network environment from the cache without delay.  
/// If no cached data exists, nil is returned. If the cached data exists and the enable parameter is set to YES, the cached data is returned. If cached data expires, the domain name is asynchronously resolved to update the cached data. If the cached data exists and the enable parameter is set to NO, nil is returned when the cached data expires, and the domain name is asynchronously resolved to update the cached data. 
/// @param domain   The domain name that you want to resolve.
/// @param enable   Specify whether to return expired IP addresses.
- (NSArray<NSString *> *)getIpsByCacheWithDomain:(NSString *)domain andExpiredIPEnabled:(BOOL)enable;

Sample code:

NSArray *result = [[DNSResolver share] getIpsByCacheWithDomain:@"Domain name" andExpiredIPEnabled:YES];
// Obtain an IP address that maps the domain name from the cache.
if (result.count > 0) {
   // TODO: Use the IP address to send a business request.
   
}

Note: You can quickly obtain DNS resolution results from the cache without the need to perform DNS resolution. If the domain name that you want to resolve has not been resolved before, or its DNS resolution result in the cache has expired and the enable parameter is set to NO, nil is returned.

5.4 Collect statistical information

Operation declaration:

/// Collect statistical information.
-(NSArray *)getRequestReportInfo;

Sample code:

NSArray *array = [[DNSResolver share] getRequestReportInfo];

Data format:

 (
      {
         avgRtt = "1";                                // Average DNS resolution duration. Unit: milliseconds.
         cacheDnsNum = 0;                             // Number of cache hits.                       
         domain = "www.taobao.com"; // The domain name that you want to resolve.
         gobackLocaldnsNum = 0;                       // Number of times DNS resolution is downgraded to the on-premises DNS server.
         localErro = 0;                               // Number of resolution failures on the on-premises DNS server.
         maxRtt = "60";                               // Maximum DNS resolution duration. Unit: milliseconds.
         noPermissionErro = 0;                        // Number of authentication failures.
         noResponseErro = 0;                          // Number of times that no response is returned.          
         requestPDnsNum = 1;                          // Number of recursive queries.
         sp = China Mobile;                                // Name of the ISP.
         successNum = 1;                              // Number of successful resolutions.
         timeoutErro = 0;                             // Number of network timeout errors.
         type = 28;                                   // If the value of the type parameter is 1, IPv4 addresses are used. If the value of the type parameter is 28, IPv6 addresses are used.
         urlParameterErro = 0;                        // Number of errors that are returned because the request parameter is invalid.
         urlPathErro = 0;                             // Number of errors that are returned because the URL is invalid.
      }
         ......
 );

6. Precautions

  1. The pdns-sdk-ios.framework folder supports only iOS 9.0 or later.

  2. If you perform DNS resolution over HTTP, you must set Allow Arbitrary Loads in App Transport Security Settings to YES in the Info.plist file.

  3. After you use Alibaba Cloud Public DNS to resolve a domain name to an IP address, you can use the IP address to send business requests. You must specify the hostname field in the HTTP request header as the domain name that has been resolved.

    Example:

    // Set the ip parameter to an IP address to which a domain name is resolved.
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://%@", ip]];
    NSMutableURLRequest *mutableReq = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval: 10];
    // Set the host field to the domain name.
    [mutableReq setValue:@"Domain name" forHTTPHeaderField:@"host"];
  4. To ensure the normal running of your business, if you do not obtain the IP address to which a domain name is mapped by using the SDK, you need to use the URL of the original domain name to send requests. The following section shows the sample code.

    NSArray *array = [[DNSResolver share] getIpsByCacheWithDomain:@"Original domain name" andExpiredIPEnabled:YES];
    NSString *ip = array.firstObject;
    if (ip.length > 0) {
        // Replace the hostname in the URL with the IP address to send requests.
        
    }else{
        // Use the original URL to send requests.
    }
  5. A demo project helps you learn how to use Alibaba Cloud Public DNS SDK.

    You can download the demo project for reference.