全部產品
Search
文件中心

HTTPDNS:iOS SDK接入

更新時間:Feb 14, 2026

前言

本章節介紹HTTPDNS iOS SDK的接入方法。

  • 推薦工程使用cocoapods管理依賴。

  • 當前SDK最新版本支援iOS Deployment Target 10.0及以上。

  • 當前SDK打包方式為靜態庫。

  • 支援模擬器x86_64arm64架構以及真機arm64架構。

第一步:將SDK添加到您的應用

1 指定Master倉庫和阿里雲倉庫

HTTPDNS iOS SDK和其他EMAS產品的iOS SDK,都是發布到阿里雲EMAS官方維護的github倉庫中,因此,您需要在您的Podfile檔案中包含該倉庫地址。

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

2 添加依賴

為您需要依賴HTTPDNS iOS SDK的target添加如下依賴。

use_framework!

pod 'AlicloudHTTPDNS', 'x.x.x'
重要

樣本依賴中的SDK版本號碼請以發布說明文檔中的最新版本號碼為準。

3 安裝依賴

在您的Terminal中進入Podfile所在目錄,執行以下命令安裝依賴。

pod install --repo-update
重要

安裝完成後,注意使用.xcworkspace檔案重新開啟工程。

第二步:使用SDK

1. 引入標頭檔

在需要使用HTTPDNS的代碼檔案中引入標頭檔。

#import <AlicloudHttpDNS/AlicloudHttpDNS.h>
import AlicloudHttpDNS

2. 構造HTTPDNS執行個體並進行配置

建議在-[AppDelegate application:didFinishLaunchingWithOptions:]方法中構造HTTPDNS全域執行個體,並進行相關配置。

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

    // 使用阿里雲HTTPDNS控制台分配的AccountId構造全域執行個體
    // 全域只需要初始化一次,secretKey需要到控制台獲得鑒權密鑰並在初始化時進行配置
    HttpDnsService *httpdns = [[HttpDnsService alloc] initWithAccountID:<Your AccountId> secretKey:@"<Your SecretKey>"];

    // 開啟日誌,調試排查問題時使用
    [httpdns setLogEnabled:NO];

    // 設定httpdns網域名稱解析網路請求是否需要走HTTPS方式
    [httpdns setHTTPSRequestEnabled:YES];
    
    // 設定啟動節點,請根據使用情境選擇合適的啟動節點
    [httpdns setRegion:ALICLOUD_HTTPDNS_SINGAPORE_REGION_KEY];
    
    // 設定開啟持久化緩衝,使得APP啟動後可以複用上次活躍時緩衝在本地的IP,提高啟動後擷取網域名稱解析結果的速度
    [httpdns setPersistentCacheIPEnabled:YES];

    // 設定允許使用已經到期的IP,當網域名稱的IP配置比較穩定時可以使用,提高解析效率
    [httpdns setReuseExpiredIPEnabled:YES];

    // 設定底層HTTPDNS網路請求逾時時間,單位為秒
    [httpdns setNetworkingTimeoutInterval:2];

    return YES;
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.

    // 使用阿里雲HTTPDNS控制台分配的AccountId構造全域執行個體
    // 全域只需要初始化一次,secretKey需要到控制台獲得鑒權密鑰並在初始化時進行配置
    let httpdns = HttpDnsService(accountID: <Your AccountId>, secretKey: "<Your SecretKey>")

    // 開啟日誌,調試排查問題時使用
    httpdns.setLogEnabled(false)

    // 設定httpdns網域名稱解析網路請求是否需要走HTTPS方式
    httpdns.setHTTPSRequestEnabled(true)
    
    // 設定啟動服務節點,請根據使用情境選擇合適的啟動節點
    httpdns.setRegion(ALICLOUD_HTTPDNS_SINGAPORE_REGION_KEY)

    // 設定開啟持久化緩衝,使得APP啟動後可以複用上次活躍時緩衝在本地的IP,提高啟動後擷取網域名稱解析結果的速度
    httpdns.setPersistentCacheIPEnabled(true)

    // 設定允許使用已經到期的IP,當網域名稱的IP配置比較穩定時可以使用,提高解析效率
    httpdns.setReuseExpiredIPEnabled(true)

    // 設定是否支援IPv6位址解析,只有開啟這個開關,解析介面才有能力解析網域名稱的IPv6地址並返回
    httpdns.setIPv6Enabled(true)

    return true
}
重要
  • 通過開啟 setPersistentCacheIPEnabled:YESsetReuseExpiredIPEnabled:YES 可以實現 樂觀 DNS 緩衝,使解析結果持久化儲存並允許使用到期 IP,從而使大部分 DNS 解析可直接在本地完成,提升首屏載入和請求效能。對於解析結果 IP 不頻繁變更的業務網域名稱,建議開啟此功能。具體用法可參考是否啟用持久化緩衝是否允許使用到期IP介面說明。

  • setHTTPSRequestEnabled參數設定為true後,計費會增加,請仔細閱讀產品計費文檔。

  • 如果您對網域名稱資訊或SDNS參數有更高的安全訴求,可以通過初始化介面設定aesSecretKey 來啟用加密功能。使用內容加密後計費會增加, 請仔細閱讀產品計費文檔。

  • 使用預解析介面啟用網域名稱預解析,可顯著提升樂觀 DNS 緩衝的命中率,使大部分解析請求直接從本機快取返回,減少即時解析帶來的時延。另一方面,預解析會增加解析請求量,建議僅對核心業務網域名稱 / 高頻訪問網域名稱開啟,以獲得最佳效能與成本平衡。

  • setRegion 預設使用中國內地服務節點,如果APP需要在海外環境使用HTTPDNS,為了提升解析效率,可以主動設定本SDK的啟動服務節點。具體配置方法,請查看設定region節點

3. 擷取服務執行個體

HTTPDNS iOS SDK以全域service執行個體的方式提供網域名稱解析服務,您可以通過以下方式擷取執行個體。

HttpDnsService *httpdns = [HttpDnsService sharedInstance];
let httpdns = HttpDnsService.sharedInstance()

4. 進行網域名稱解析

HTTPDNS提供了多種網域名稱解析方式,包括預解析/同步解析/非同步解析/同步非阻塞解析。下面以同步非阻塞解析介面作為例子。

HttpDnsService *httpdns = [HttpDnsService sharedInstance];
HttpdnsResult *result = [httpdns resolveHostSyncNonBlocking:@"www.aliyun.com" byIpType:HttpdnsQueryIPTypeAuto];
if (result) {
    // 使用網域名稱解析結果
} else {
    // 同步非阻塞介面,為了最快的解析速度,若緩衝中無有效解析結果,會立即返回空值,同時在後台發起新的解析請求
    // 因此,要做好走LocalDNS解析,或者仍然直接給網路程式庫傳完整網域名稱的方式降級
    // 可以使用強同步介面、或者回調形式的介面確保獲得HTTPDNS解析的結果
}
let httpdns = HttpDnsService.sharedInstance()
if let result = httpdns.resolveHostSyncNonBlocking("www.aliyun.com", by: HttpdnsQueryIPType.auto) {
    // 使用網域名稱解析結果
} else {
    // 同步非阻塞介面,為了最快的解析速度,若緩衝中無有效解析結果,會立即返回空值,同時在後台發起新的解析請求
    // 因此,要做好走LocalDNS解析,或者仍然直接給網路程式庫傳完整網域名稱的方式降級
    // 可以使用強同步介面、或者回調形式的介面確保獲得HTTPDNS解析的結果
}

請根據您的實際使用情境選擇合適的網域名稱解析介面。

重要
  • 如果返回的result一直為nil,請檢查是否已經在阿里雲HTTPDNS控制台上添加該網域名稱。

  • 為了網路異常情況導致返回結果為nil時不影響商務程序,建議降級到LocalDNS解析作為兜底邏輯。

5. 使用網域名稱解析結果

不同情況下,網域名稱解析結果可能包含多種情況。

  • 空結果,如在使用同步非阻塞介面,或者網路異常時。

  • 只有IPv4的地址,在本網環境為IPv4單棧且指定包含IPv4的請求類型,或網域名稱只配置了IPv4的地址。

  • 只有IPv6的地址,在啟用IPv6且指定解析IPv6的地址時。考慮到當前IPv6的推廣程度,這種情況一般不會發生。

  • 同時擁有IPv4、IPv6的地址,在啟用IPv6且指定瞭解析雙棧地址,或指定了自動判斷網路類型且是雙棧環境下,同時網域名稱也配置了IPv4、IPv6地址的情況下。

本樣本中,配置開啟了IPv6解析,且請求IP類型設定為Both,若網域名稱同時配置了IPv4、IPv6地址,則解析結果也會同時包含。因此,若需要優先選擇IPv4地址,則可以按如下代碼處理解析結果。

HttpDnsService *httpdns = [HttpDnsService sharedInstance];
HttpdnsResult *result = [httpdns resolveHostSyncNonBlocking:@"www.aliyun.com" byIpType:HttpdnsQueryIPTypeAuto];
if (!result) {
    // 無有效ip,走兜底邏輯
}

if (result.hasIpv4Address) {
    NSString *ip = result.firstIpv4Address;
    // 使用ip

    NSArray<NSString *> *ips = result.ips;
    // 使用ip列表
} else if (result.hasIpv6Address) {
    NSString *ip = result.firstIpv6Address;
    // 使用ip

    NSArray<NSString *> *ips = result.ipv6s;
    // 使用ip列表
} else {
    // 無有效ip,走兜底邏輯
}
let httpdns = HttpDnsService.sharedInstance()
if let result = httpdns.resolveHostSyncNonBlocking("www.aliyun.com", by: HttpdnsQueryIPType.auto) {
    if (result.hasIpv4Address()) {
        let ip = result.firstIpv4Address()
        // 使用ip

        let ipList = result.ips
        // 使用ip列表
    } else if (result.hasIpv6Address()) {
        let ip = result.firstIpv6Address()
        // 使用ip

        let ipList = result.ipv6s
        // 使用ip列表
    } else {
        // 無有效ip,走兜底邏輯
    }
} else {
    // 無有效ip,走兜底邏輯
}

範例代碼

HTTPDNS iOS SDK接入工程範例參見HTTPDNS iOS Demo

注意事項

  1. 務必編寫降級代碼

    降級代碼指的是HTTPDNS未擷取到期望結果時的處理代碼。通常您可以降級到使用LocalDNS進行解析,即,為網路程式庫傳入原始網域名稱,讓網路程式庫自行走本地LocalDNS解析。

  2. 記錄從HTTPDNS擷取的IP及sessinId

    我們提供了用於解析問題排查的解決方案,需要您將從HTTPDNS擷取的IP及sessionId記錄到日誌中,詳情請參考如何使用“會話追蹤方案”排查解析異常

  3. 設定HTTP要求標頭HOST欄位

    標準的HTTP協議中服務端會將HTTP要求標頭HOST欄位的值作為請求的網域名稱資訊進行解析。使用HTTPDNS後,您可能需要將HTTP請求URL中的HOST欄位替換為HTTPDNS解析獲得的IP,這時標準的網路程式庫會將您的IP賦值給HTTP要求標頭的HOST欄位,進而導致服務端的解析異常(服務端認可的是您的網域名稱資訊,而非IP資訊)。

    為瞭解決這個問題,您可以主動設定HTTP請求HOST欄位的值,如以下這個簡單樣本:

    - (void)sampleRequestUsingHttpdns {
        HttpDnsService *httpdns = [HttpDnsService sharedInstance];
    
        NSString *originalUrlStr = @"http://www.aliyun.com/";
        NSURL* url = [NSURL URLWithString:originalUrlStr];
    
        // 同步介面擷取IP
        HttpdnsResult* result = [httpdns resolveHostSyncNonBlocking:url.host byIpType:HttpdnsQueryIPTypeAuto];
        NSLog(@"resolve result: %@", result);
        NSString *validIp = nil;
        if (result) {
            if (result.hasIpv4Address) {
                validIp = result.firstIpv4Address;
            }
        }
    
        NSMutableURLRequest *request;
    
        if (validIp) {
            // 通過HTTPDNS擷取IP成功,進行URL替換和HOST頭設定
            NSRange hostFirstRange = [originalUrlStr rangeOfString:url.host];
            NSString* newUrl = [originalUrlStr stringByReplacingCharactersInRange:hostFirstRange withString:validIp];
            request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:newUrl]];
            // 佈建要求HOST欄位
            [request setValue:url.host forHTTPHeaderField:@"host"];
        } else {
            // 本處示範如何做好降級處理
            // 通過HTTPDNS無法擷取IP,直接使用原有的URL進行網路請求
            request = [[NSMutableURLRequest alloc] initWithURL:url];
        }
    
        // 發送請求
        NSURLSession *session = [NSURLSession sharedSession];
        NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            if (error) {
                NSLog(@"error: %@", error);
            } else {
                NSLog(@"response: %@", response);
            }
        }];
        [task resume];
    }
    func sampleRequestUsingHttpdns() {
        let httpdns = HttpDnsService.sharedInstance()
        let originalUrlStr = "http://www.aliyun.com/"
        let url = URL(string: originalUrlStr)!
    
        // 同步介面擷取IP
        let result = httpdns.resolveHostSyncNonBlocking(url.host!, by: HttpdnsQueryIPType.auto)
        print("resolve result: \(result?.description ?? "")")
    
        var validIp: String?
        if let result = result {
            if result.hasIpv4Address() {
                validIp = result.firstIpv4Address()
            }
        }
    
        var request: URLRequest
    
        if let validIp = validIp {
            // 通過HTTPDNS擷取IP成功,進行URL替換和HOST頭設定
            let hostFirstRange = originalUrlStr.firstRange(of: url.host!)!
            let newUrl = originalUrlStr.replacingCharacters(in: hostFirstRange, with: validIp)
            request = URLRequest(url: URL(string: newUrl)!)
            // 佈建要求HOST欄位
            request.setValue(url.host!, forHTTPHeaderField: "host")
        } else {
            // 本處示範如何做好降級處理
            // 通過HTTPDNS無法擷取IP,直接使用原有的URL進行網路請求
            request = URLRequest(url: url)
        }
    
        // 發送請求
        let session = URLSession.shared
        let task = session.dataTask(with: request) { (data, response, error) in
            if let error = error {
                print("error: \(error)")
            } else {
                print("response: \(response?.description ?? "")")
            }
        }
        task.resume()
    }
    重要

    這個簡單樣本中,也要注意這些細節:

    • 該樣本僅展示了一定解析成功的情況,未考慮兜底邏輯。

    • 簡單起見,該樣本請求的是HTTP的地址,因此要在plist.info中配置NSAllowsArbitraryLoads才能訪問。

    • 如果請求地址為HTTPS類型,則需要參考後文的HTTPS情境指導。

  4. Cookie欄位

    部分網路程式庫支援Cookie的自動儲存管理,當您使用HTTPDNS進行IP URL請求時,部分網路程式庫會將您URL中的IP資訊作為Cookie對應的網域名稱資訊進行儲存管理(而非HTTP要求標頭HOST欄位資訊),進而造成Cookie管理與使用上的困擾,因此您需要關閉Cookie的自動管理功能(預設關閉)。

  5. HTTPS/WebView/SNI情境

    HTTPS情境,請參考iOS端Native情境使用HTTPDNS

  6. 代理情況下的使用

    當存在中間HTTP代理時,用戶端發起的請求中請求行會使用絕對路徑的URL,在您開啟HTTPDNS並採用IP URL進行訪問時,中間代理將識別您的IP資訊並將其作為真實訪問的HOST資訊傳遞給目標伺服器,這時目標伺服器將無法處理這類無真實HOST資訊的HTTP請求。移動網關提供了X-Online-Host的私人協議欄位來解決這個問題,比如:

    目標 URL:http://www.aliyun.com/product/oss/
    通過 HTTPDNS 解析出來的www.aliyun.com的IP:X.X.X.X
    代理:10.0.0.172:80
    
    您的HTTP要求標頭:
    
    GET http://X.X.X.X/product/oss/ HTTP/1.1     # 通過代理髮起的HTTP要求標頭,請求行是一個絕對路徑
    Host: www.aliyun.com   # 這個Header會被代理網關忽略,代理網關會使用請求行絕對路徑中的host欄位作為來源站點的host,即1.1.X.X
    X-Online-Host: www.aliyun.com    # 這個Header就是移動網關為了傳遞真實Host添加的私人頭部,來源站點需要配置識別該私人頭部以擷取真實的Host資訊

    同樣您可以通過下述方法進行X-Online-Host要求標頭域的設定,並在服務端設定對該私人頭域的解析。

    [request setValue:url.host forHTTPHeaderField:@"X-Online-Host"];
    說明

    在絕大多數情境下,我們建議您檢測當前裝置是否開啟了網路代理程式,然後在代理模式下不使用HTTPDNS進行網域名稱解析。