All Products
Search
Document Center

SDK for iOS developer guide

Last Updated: Jun 28, 2021

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 a 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 queries 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.

The iOS 14 operating system natively supports two DNS encryption protocols: 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 APIs for DNS over HTTPS (DoH) of Alibaba Cloud Public DNS. The SDK provides Java interface functions for iOS apps to perform DNS resolution. The SDK also 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:

  • Ease of use:

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

  • DNS resolution without delay:

    The SDK implements the LRU caching algorithm so that the IP addresses obtained from DNS resolution are cached on your local 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, activate Alibaba Cloud Public DNS. The Overview tab displays the unique account ID that is automatically generated for your Alibaba Cloud account. You can use this account ID to use Alibaba Cloud Public DNS in your app.

  2. On the SDK Download tab, click the download link for iOS to download Alibaba Cloud Public DNS SDK for iOS.

  3. Add the pdns-sdk-ios.framework folder in the SDK 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 after you activate Alibaba Cloud Public DNS";

2.2 Auto-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 activate Alibaba Cloud Public DNS. The account ID is required each time you call a service API operation by using Alibaba Cloud Public DNS SDK.

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 need to use IPv6 addresses to access the DNS server, make sure that the current network supports IPv6 addresses and then set the ipv6Enable parameter to YES to enable IPv6 access. The following code shows an example:

[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, specify the shortEnable parameter to enable the short mode. The following code shows an example:

[DNSResolver share].shortEnable = YES;

3.4 scheme

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

By default, the SDK uses HTTP for DNS resolution. We recommend that you do not change the default configuration because DNS resolution over HTTP is faster. If you need to use HTTPS for resolution, set the scheme parameter to DNSResolverSchemeHttps. The following code shows an example:

[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, data 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 not enabled in the SDK. To enable the caching feature, set the cacheEnable parameter to YES. The following code shows an example:

[DNSResolver share].cacheEnable=YES;

3.5 Specify the maximum cache size

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

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

[DNSResolver share].cacheCountLimit = 200;

3.7 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 resolution result of the IP address with the highest connection speed is preferentially returned. The resolution results are sorted in descending order of connection speeds.

By default, this feature is not enabled in the SDK. To enable this feature, set speedTestEnable to YES. The following code shows an example:

[DNSResolver share].speedTestEnable=YES;

3.8 Specify the mode for connection speed testing

You can specify the mode for connection speed testing. 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 specified in the socket is used to detect the connection speed.

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

[DNSResolver share].speedPort = 80;

3.9 Enable domain name caching based on ISP networks

You can use the SDK to enable domain name caching based on ISP networks. If this feature is enabled, the cached domain name data is stored separately based on the network environments. If this feature is not enabled, the same cached domain name data is used under different networks.

By default, this feature is not enabled in the SDK. To enable this feature, set the ispEnable parameter to YES. The following code shows an example:

[DNSResolver share].ispEnable = YES;

3.10 Specify the maximum TTL for negative caching

You can use the SDK to specify the maximum TTL for negative caching. If you specify 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 code show an example:

[DNSResolver share].maxNegativeCache = 30;

3.11 Specify the maximum TTL for caching

You can use the SDK to specify the maximum TTL for caching. If you specify 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 code shows an example:

[DNSResolver share].maxCacheTTL= 3600;

3.12 timeout

The timeout parameter specifies the timeout period for DNS resolution. The default timeout period is 3 seconds. You can set a custom timeout period as required. We recommend that you set the timeout period in the range of 2 to 5 seconds.

3.13 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 provided in Service authentication and configure the accessKeyId and accesskeySecret parameters in your app. The following code shows an example:

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

3.14 Preload domain names

The caching feature provided by the SDK makes it quicker to resolve a domain name that has been resolved. We recommend that you preload the domain names to be resolved 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 preloadIpv4Domains:@[@"Domain name 1", @"Domain name 2", @"Domain name 3"] complete:^{
       // All the specified domain names are preloaded.
       
   }];
   
   return YES;
}

4.Service API operations

Sample code:

/// Obtain an array of information about IPv4 addresses to which a domain name is resolved.
/// @param domain           The domain name that you want to resolve.
/// @param complete       Return 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.
/// @param domain           The domain name that you want to resolve.
/// @param complete       Return information about all the IPv6 addresses to which the domain name is resolved.
- (void)getIpv6InfoWithDomain:(NSString *)domain complete:(void(^)(NSArray<DNSDomainInfo *> *domainInfoArray))complete;

/// Obtain information about an IPv4 address to which a domain name is resolved.
/// @param domain           The domain name that you want to resolve.
/// @param complete       Return information about an IPv4 address to which the domain name is resolved.
- (void)getRandomIpv4InfoWithDomain:(NSString *)domain complete:(void(^)(DNSDomainInfo *domainInfo))complete;

/// Obtain information about an IPv6 address to which a domain name is resolved.
/// @param domain           The domain name that you want to resolve.
/// @param complete       Return 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.
/// @param domain           The domain name that you want to resolve.
/// @param complete       Return all the 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.
/// @param domain           The domain name that you want to resolve.
/// @param complete       Return all the 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.
/// @param domain           The domain name that you want to resolve.
/// @param complete       Return one of the IPv4 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.
/// @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. Call this operation after you start your app. This accelerates subsequent DNS resolution.
/// @param domainArray  The array of domain names that you want to resolve.
/// @param complete         Return resolution results.
- (void)preloadIpv4Domains:(NSArray<NSString *> *)domainArray complete:(void(^)(void))complete;

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

/// Query the cache to obtain an IPv4 address that maps the domain name to be resolved.  If the domain name has not been resolved before or its resolution result has expired in the cache, nil is returned.
/// @param domain   The domain name that you want to resolve.
- (NSArray<NSString *> *)getIpv4ByCacheWithDomain:(NSString *)domain;

/// Query the cache to obtain an IPv6 address that maps the domain name to be resolved.  If the domain name has not been resolved before or its resolution result has expired in the cache, nil is returned.
/// @param domain   The domain name that you want to resolve.
- (NSArray<NSString *> *)getIpv6ByCacheWithDomain:(NSString *)domain;

/// Collect statistics.
-(NSArray *)getRequestReportInfo;

5. API call examples

5.1 Initialize the SDK in your app

- (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 was generated after you activate Alibaba Cloud Public DNS";
   
   return YES;
}

5.2 Resolve a domain name by calling an operation

Alibaba Cloud Public DNS SDK supports resolving domain names to IPv4 and IPv6 addresses. All the preceding service API operations are described in the header file DNSResolver.h in the SDK. In this example, the getRandomIpv4DataWithDomain operation is called to resolve a domain name to an IPv4 address.

The following code shows the declarations of the getRandomIpv4DataWithDomain operation:

/// Obtain an IPv4 address to which a domain name is resolved.
/// @param domain           The domain name that you want to resolve.
/// @param complete       Return an IPv4 address to which the domain name is resolved.
- (void)getRandomIpv4DataWithDomain:(NSString *)domain complete:(void(^)(NSString *data))complete;

The following code shows an example of calling the operation:

[[DNSResolver share] getRandomIpv4DataWithDomain:@"www.taobao.com" complete:^(NSString *data) {
   // The data string is the returned IPv4 address that maps the domain name www.taobao.com.
   if (data.length > 0) {
       //TODO: Use the IP address to send a request.
       
   }
}];

5.3 Query the cache to obtain an IP address that maps the domain name to be resolved

The following code shows the declarations of the getIpv4ByCacheWithDomain and getIpv6ByCacheWithDomain operations:

/// Query the cache to obtain an IPv4 address that maps the domain name to be resolved.  If the domain name has not been resolved before or its resolution result has expired in the cache, nil is returned.
/// @param domain   The domain name that you want to resolve.
- (NSArray<NSString *> *)getIpv4ByCacheWithDomain:(NSString *)domain;
​
/// Query the cache to obtain an IPv6 address that maps the domain name to be resolved.  If the domain name has not been resolved before or its resolution result has expired in the cache, nil is returned.
/// @param domain   The domain name that you want to resolve.
- (NSArray<NSString *> *)getIpv6ByCacheWithDomain:(NSString *)domain;
​

The following code shows an example of calling the operation:

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

Note: It is faster to query resolution results from the cache than to perform DNS resolution. If the domain name that you want to resolve has not been resolved before or its resolution result has expired in the cache, nil is returned.

5.4 Collect statistics

The following code shows the declarations of the getRequestReportInfo operation:

/// Collect statistics.
-(NSArray *)getRequestReportInfo;

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

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

Data format:

 (
      {
         avgRrt = "1";                                // Average DNS resolution duration, in milliseconds.
         cacheDnsNum = 0;                             // Number of cache hits.                       
         domain = "www.taobao.com"; // The domain name to resolve.
         gobackLocaldnsNum = 0;                       // Number of times DNS resolution is downgraded to the local DNS server.
         localErro = 0;                               // Number of resolution failures on the local DNS server.
         maxRrt = "60";                               // Maximum DNS resolution duration, in milliseconds.
         noPermissionErro = 0;                        // Number of authentication failures.
         noResponseErro = 0;                          // Number of times no response is returned.          
         requestPDnsNum = 1;                          // Number of recursive queries.
         sp = China Mobile;                                // Name of the Internet service provider (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 use HTTP for DNS resolution, 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 set the host field in the HTTP request header to 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. A demo project helps you learn how to use Alibaba Cloud Public DNS SDK.

    You can download the demo project for reference. For more information, download the demo project.