日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

iOS SDK接入

更新時(shí)間:

前言

本章節(jié)介紹HTTPDNS iOS SDK的接入方法。

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

  • 當(dāng)前SDK最新版本支持iOS Deployment Target 10.0及以上。

  • 當(dāng)前SDK打包方式為靜態(tài)庫(kù)。

  • 支持模擬器x86_64arm64架構(gòu)以及真機(jī)arm64架構(gòu)。

準(zhǔn)備工作

第一步:將SDK添加到您的應(yīng)用

我們提供了cocoapods引入依賴和本地依賴兩種集成方式,方便您根據(jù)需要將SDK添加到您的應(yīng)用中。

1. cocoapods引入依賴

1.1 指定Master倉(cāng)庫(kù)和阿里云倉(cāng)庫(kù)

HTTPDNS iOS SDK和其他EMAS產(chǎn)品的iOS SDK,都是發(fā)布到阿里云EMAS官方維護(hù)的github倉(cāng)庫(kù)中,因此,您需要在您的Podfile文件中包含該倉(cāng)庫(kù)地址。

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

1.2 添加依賴

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

use_framework!

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

示例依賴中的SDK版本號(hào)請(qǐng)以發(fā)布說明文檔中的最新版本號(hào)為準(zhǔn)。

1.3 安裝依賴

在您的Terminal中進(jìn)入Podfile所在目錄,執(zhí)行以下命令安裝依賴。

pod install --repo-update
重要

安裝完成后,注意使用.xcworkspace文件重新打開工程。

2. 本地手動(dòng)集成依賴

2.1 下載依賴文件

EMAS SDK列表選擇HTTPDNS iOS版本進(jìn)行下載,解壓得到多個(gè)framework文件,如圖示。

image

2.2 將framework文件添加到工程中

Finder中選中上述xcframework文件,拖入需要使用HTTPDNS iOS SDK的target下,并在彈出框中勾選Copy items if needed

image

2.3 添加系統(tǒng)庫(kù)依賴

在工程項(xiàng)目中(Build Phases -> Link Binary With Libraries)添加以下庫(kù)依賴。

libsqlite3.0.tbd
libresolv.tbd
CoreTelephony.framework
SystemConfiguration.framework

最終效果如圖示。

image

2.4 ObjC配置

iOS端集成SDK時(shí)需要做-ObjC配置,即應(yīng)用的 TARGETS -> Build Settings -> Linking -> Other Linker Flags ,需添加上 -ObjC 這個(gè)屬性,如圖示。

image

第二步:使用SDK

1. 引入頭文件

在需要使用HTTPDNS的代碼文件中引入頭文件。

#import <AlicloudHttpDNS/AlicloudHttpDNS.h>
import AlicloudHttpDNS

2. 構(gòu)造HTTPDNS實(shí)例并進(jìn)行配置

建議在-[AppDelegate application:didFinishLaunchingWithOptions:]方法中構(gòu)造HTTPDNS全局實(shí)例,并進(jìn)行相關(guān)配置。

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

    // 使用阿里云HTTPDN控制臺(tái)分配的AccountId構(gòu)造全局實(shí)例
    // 全局只需要初始化一次
    HttpDnsService *httpdns = [[HttpDnsService alloc] initWithAccountID:xxxxxx];

    // 若開啟了鑒權(quán)訪問,則需要到控制臺(tái)獲得鑒權(quán)密鑰并在初始化時(shí)進(jìn)行配置
    // HttpDnsService *httpdns = [[HttpDnsService alloc] initWithAccountID:xxxxxx secretKey:@"your secret key"];

    // 打開日志,調(diào)試排查問題時(shí)使用
    [httpdns setLogEnabled:NO];

    // 設(shè)置httpdns域名解析網(wǎng)絡(luò)請(qǐng)求是否需要走HTTPS方式
    [httpdns setHTTPSRequestEnabled:YES];

    // 設(shè)置開啟持久化緩存,使得APP啟動(dòng)后可以復(fù)用上次活躍時(shí)緩存在本地的IP,提高啟動(dòng)后獲取域名解析結(jié)果的速度
    [httpdns setPersistentCacheIPEnabled:YES];

    // 設(shè)置允許使用已經(jīng)過期的IP,當(dāng)域名的IP配置比較穩(wěn)定時(shí)可以使用,提高解析效率
    [httpdns setReuseExpiredIPEnabled:YES];

    // 設(shè)置底層HTTPDNS網(wǎng)絡(luò)請(qǐng)求超時(shí)時(shí)間,單位為秒
    [httpdns setTimeoutInterval:2];

    // 設(shè)置是否支持IPv6地址解析,只有開啟這個(gè)開關(guān),解析接口才有能力解析域名的IPv6地址并返回
    [httpdns setIPv6Enabled:YES];

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

    // 使用HTTPDNS阿里云控制臺(tái)分配的AccountId構(gòu)造全局實(shí)例
    // 全局只需要初始化一次
    let httpdns = HttpDnsService(accountID: xxxxxx)!

    // 若開啟了鑒權(quán)訪問,則需要到控制臺(tái)獲得鑒權(quán)密鑰并在初始化時(shí)進(jìn)行配置
    // let httpdns = HttpDnsService(accountID: xxxxxx, secretKey: "your secret key")!

    // 打開日志,調(diào)試排查問題時(shí)使用
    httpdns.setLogEnabled(false)

    // 設(shè)置httpdns域名解析網(wǎng)絡(luò)請(qǐng)求是否需要走HTTPS方式
    httpdns.setHTTPSRequestEnabled(true)

    // 設(shè)置開啟持久化緩存,使得APP啟動(dòng)后可以復(fù)用上次活躍時(shí)緩存在本地的IP,提高啟動(dòng)后獲取域名解析結(jié)果的速度
    httpdns.setPersistentCacheIPEnabled(true)

    // 設(shè)置允許使用已經(jīng)過期的IP,當(dāng)域名的IP配置比較穩(wěn)定時(shí)可以使用,提高解析效率
    httpdns.setReuseExpiredIPEnabled(true)

    // 設(shè)置是否支持IPv6地址解析,只有開啟這個(gè)開關(guān),解析接口才有能力解析域名的IPv6地址并返回
    httpdns.setIPv6Enabled(true)

    return true
}

3. 獲取服務(wù)實(shí)例

HTTPDNS iOS SDK以全局service實(shí)例的方式提供域名解析服務(wù),您可以通過以下方式獲取實(shí)例。

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

4. 進(jìn)行域名解析

HTTPDNS提供了多種域名解析方式,包括預(yù)解析/同步解析/異步解析/同步非阻塞解析。下面以同步非阻塞解析接口作為例子。

HttpDnsService *httpdns = [HttpDnsService sharedInstance];
HttpdnsResult *result = [httpdns resolveHostSyncNonBlocking:@"www.aliyun.com" byIpType:HttpdnsQueryIPTypeAuto];
if (result) {
    // 使用域名解析結(jié)果
} else {
    // 同步非阻塞接口,為了最快的解析速度,若緩存中無有效解析結(jié)果,會(huì)立即返回空值,同時(shí)在后臺(tái)發(fā)起新的解析請(qǐng)求
    // 因此,要做好走LocalDNS解析,或者仍然直接給網(wǎng)絡(luò)庫(kù)傳完整域名的方式降級(jí)
    // 可以使用強(qiáng)同步接口、或者回調(diào)形式的接口確保獲得HTTPDNS解析的結(jié)果
}
let httpdns = HttpDnsService.sharedInstance()!
if let result = httpdns.resolveHostSyncNonBlocking("www.aliyun.com", by: HttpdnsQueryIPType.auto) {
    // 使用域名解析結(jié)果
} else {
    // 同步非阻塞接口,為了最快的解析速度,若緩存中無有效解析結(jié)果,會(huì)立即返回空值,同時(shí)在后臺(tái)發(fā)起新的解析請(qǐng)求
    // 因此,要做好走LocalDNS解析,或者仍然直接給網(wǎng)絡(luò)庫(kù)傳完整域名的方式降級(jí)
    // 可以使用強(qiáng)同步接口、或者回調(diào)形式的接口確保獲得HTTPDNS解析的結(jié)果
}

請(qǐng)根據(jù)您的實(shí)際使用場(chǎng)景選擇合適的域名解析接口。

重要
  • 如果返回的result一直為nil,請(qǐng)檢查是否已經(jīng)在阿里云HTTPDNS控制臺(tái)上添加該域名。

  • 為了網(wǎng)絡(luò)異常情況導(dǎo)致返回結(jié)果為nil時(shí)不影響業(yè)務(wù)流程,建議降級(jí)到LocalDNS解析作為兜底邏輯。

5. 使用域名解析結(jié)果

不同情況下,域名解析結(jié)果可能包含多種情況。

  • 空結(jié)果,如在使用同步非阻塞接口,或者網(wǎng)絡(luò)異常時(shí)。

  • 只有ipv4的地址,在本地網(wǎng)絡(luò)環(huán)境為ipv4單棧且指定包含ipv4的請(qǐng)求類型,或域名只配置了ipv4的地址。

  • 只有ipv6的地址,在啟用ipv6且指定解析ipv6的地址時(shí)。考慮當(dāng)前ipv6的推廣程度,這種情況一般不會(huì)發(fā)生。

  • 同時(shí)擁有ipv4、ipv6的地址,在啟用ipv6且指定解析雙棧地址,或指定了自動(dòng)判斷網(wǎng)絡(luò)類型且是雙棧環(huán)境下,同時(shí)域名也配置了ipv4、ipv6地址的情況下。

本示例中,配置開啟了ipv6解析,且請(qǐng)求IP類型設(shè)置為Both,若域名同時(shí)配置了ipv4、ipv6地址,則解析結(jié)果也會(huì)同時(shí)包含。因此,若需要優(yōu)先選擇ipv4地址,則可以按如下代碼處理解析結(jié)果。

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

注意事項(xiàng)

  1. 務(wù)必編寫降級(jí)代碼

    降級(jí)代碼指的是HTTPDNS未獲取到期望結(jié)果時(shí)的處理代碼。通常您可以降級(jí)到使用LocalDNS進(jìn)行解析,即,為網(wǎng)絡(luò)庫(kù)傳入原始域名,讓網(wǎng)絡(luò)庫(kù)自行走本地LocalDNS解析。

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

    我們提供了用于解析問題排查的解決方案,需要您將從HTTPDNS獲取的IP及sessionId記錄到日志中,詳情請(qǐng)參考如何使用“會(huì)話追蹤方案”排查解析異常

  3. 設(shè)置HTTP請(qǐng)求頭HOST字段

    標(biāo)準(zhǔn)的HTTP協(xié)議中服務(wù)端會(huì)將HTTP請(qǐng)求頭HOST字段的值作為請(qǐng)求的域名信息進(jìn)行解析。使用HTTPDNS后,您可能需要將HTTP請(qǐng)求URL中的HOST字段替換為HTTPDNS解析獲得的IP,這時(shí)標(biāo)準(zhǔn)的網(wǎng)絡(luò)庫(kù)會(huì)將您的IP賦值給HTTP請(qǐng)求頭的HOST字段,進(jìn)而導(dǎo)致服務(wù)端的解析異常(服務(wù)端認(rèn)可的是您的域名信息,而非IP信息)。

    為了解決這個(gè)問題,您可以主動(dòng)設(shè)置HTTP請(qǐng)求HOST字段的值,如以下這個(gè)簡(jiǎn)單示例:

    - (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成功,進(jìn)行URL替換和HOST頭設(shè)置
            NSRange hostFirstRange = [originalUrlStr rangeOfString:url.host];
            NSString* newUrl = [originalUrlStr stringByReplacingCharactersInRange:hostFirstRange withString:validIp];
            request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:newUrl]];
            // 設(shè)置請(qǐng)求HOST字段
            [request setValue:url.host forHTTPHeaderField:@"host"];
        } else {
            // 本處演示如何做好降級(jí)處理
            // 通過HTTPDNS無法獲取IP,直接使用原有的URL進(jìn)行網(wǎng)絡(luò)請(qǐng)求
            request = [[NSMutableURLRequest alloc] initWithURL:url];
        }
    
        // 發(fā)送請(qǐng)求
        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成功,進(jìn)行URL替換和HOST頭設(shè)置
            let hostFirstRange = originalUrlStr.firstRange(of: url.host!)!
            let newUrl = originalUrlStr.replacingCharacters(in: hostFirstRange, with: validIp)
            request = URLRequest(url: URL(string: newUrl)!)
            // 設(shè)置請(qǐng)求HOST字段
            request.setValue(url.host!, forHTTPHeaderField: "host")
        } else {
            // 本處演示如何做好降級(jí)處理
            // 通過HTTPDNS無法獲取IP,直接使用原有的URL進(jìn)行網(wǎng)絡(luò)請(qǐng)求
            request = URLRequest(url: url)
        }
    
        // 發(fā)送請(qǐng)求
        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()
    }
    重要

    這個(gè)簡(jiǎn)單示例中,也要注意這些細(xì)節(jié):

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

    • 簡(jiǎn)單起見,該示例請(qǐng)求的是HTTP的地址,因此要在plist.info中配置NSAllowsArbitraryLoads才能訪問。

    • 如果請(qǐng)求地址為HTTPS類型,則需要參考后文的HTTPS場(chǎng)景指導(dǎo)。

  4. Cookie字段

    部分網(wǎng)絡(luò)庫(kù)支持COOKIE的自動(dòng)存儲(chǔ)管理,當(dāng)您使用HTTPDNS進(jìn)行IP URL請(qǐng)求時(shí),部分網(wǎng)絡(luò)庫(kù)會(huì)將您URL中的IP信息作為COOKIE對(duì)應(yīng)的域名信息進(jìn)行存儲(chǔ)管理(而非HTTP請(qǐng)求頭HOST字段信息),進(jìn)而造成COOKIE管理與使用上的困擾,因此您需要關(guān)閉COOKIE的自動(dòng)管理功能(默認(rèn)關(guān)閉)。

  5. HTTPS/WebView/SNI場(chǎng)景

    HTTPS場(chǎng)景,請(qǐng)參考iOS端HTTPS場(chǎng)景使用HTTPDNS

    WebView場(chǎng)景,請(qǐng)參考iOS端WebView " IP直連 " 如何處理 Cookie

  6. 代理情況下的使用

    當(dāng)存在中間HTTP代理時(shí),客戶端發(fā)起的請(qǐng)求中請(qǐng)求行會(huì)使用絕對(duì)路徑的URL,在您開啟HTTPDNS并采用IP URL進(jìn)行訪問時(shí),中間代理將識(shí)別您的IP信息并將其作為真實(shí)訪問的HOST信息傳遞給目標(biāo)服務(wù)器,這時(shí)目標(biāo)服務(wù)器將無法處理這類無真實(shí)HOST信息的HTTP請(qǐng)求。移動(dòng)網(wǎng)關(guān)提供了X-Online-Host的私有協(xié)議字段來解決這個(gè)問題,比如:

    目標(biāo) URL:http://www.aliyun.com/product/oss/
    通過 HTTPDNS 解析出來的www.aliyun.com的IP:X.X.X.X
    代理:10.0.0.172:80
    
    您的HTTP請(qǐng)求頭:
    
    GET http://X.X.X.X/product/oss/ HTTP/1.1     # 通過代理發(fā)起的HTTP請(qǐng)求頭,請(qǐng)求行是一個(gè)絕對(duì)路徑
    Host: www.aliyun.com   # 這個(gè)Header會(huì)被代理網(wǎng)關(guān)忽略,代理網(wǎng)關(guān)會(huì)使用請(qǐng)求行絕對(duì)路徑中的host字段作為源站的host,即1.1.X.X
    X-Online-Host: www.aliyun.com    # 這個(gè)Header就是移動(dòng)網(wǎng)關(guān)為了傳遞真實(shí)Host添加的私有頭部,源站需要配置識(shí)別該私有頭部以獲取真實(shí)的Host信息

    同樣您可以通過下述方法進(jìn)行X-Online-Host請(qǐng)求頭域的設(shè)置,并在服務(wù)端設(shè)置對(duì)該私有頭域的解析。

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

    在絕大多數(shù)場(chǎng)景下,我們建議您檢測(cè)當(dāng)前設(shè)備是否開啟了網(wǎng)絡(luò)代理,然后在代理模式下不使用HTTPDNS進(jìn)行域名解析。

集成常見問題

UTDID沖突,可參考:阿里云-云產(chǎn)品SDK UTDID沖突解決方案