AppStore IPv6-only 解決--看我就夠了

自2016年6月1日起,蘋果要求全部提交App Store的iOS應用必須支持IPv6-only環境,背景也是衆所周知的,IPv4地址已基本分配完畢,同時IPv6比IPv4也更加高效,向IPv6過渡是大勢所趨。javascript

然而在對IPv6進行兼容適配過程當中,不少開發者在本地環境測試經過,卻在App Store審覈時被拒,這種狀況下能夠首先排查是否由DNS解析失敗引發,那麼如何驗證DNS服務器是否正確響應了IPv6地址的解析請求呢?搭建好DNS64環境後,能夠經過如下命令查詢:php

$dig dnspod.cn aaaacss

驗證DNS解析的緣由是,App訪問網絡的第一步就是進行DNS解析,App Store審覈時會先訪問DNS服務器,得到iOS應用服務器的IPv6地址,再進行訪問,若是這時DNS服務器沒法成功解析到IPv6地址,即便在本地搭建的IPv6-only環境中測試成功,仍然會出如今提交App Store審覈時被拒的狀況,因此選擇一個穩定性、兼容性俱佳的域名解析服務相當重要!html

通過全面的測試和灰度發佈,騰訊雲DNSPod域名解析已全面支持App Store IPv6-only網絡環境,已有成功經過審覈案例,而且在境內外均驗證解析成功java

附: 詳細原理分析ios

IPv6-only環境的原理

首先須要明確一點,在App Store審覈APP的IPv6-only的環境下也是能夠正常訪問IPv4的服務的,只是首先由DNS64將解析出來的IPv4地址轉成兼容的IPv6地址,而後訪問IPv4服務時經過NAT64網關對IPv4和IPv6進行NAT,並不須要客戶有實際的IPv6服務。以下圖所示:git


 

DNS64原理

客戶端在向DNS64請求一個域名的IPv6地址時,DNS64會向域名的受權DNS請求IPv6地址,若是存在IPv6地址,則直接給客戶端返回IPv6地址,若是不存在IPv6地址,則向受權請求IPv4地址,並將返回的IPv4地址轉換爲兼容的IPv6地址。github

以Google DNS64爲例說明轉換規則,分別請求dnspod.cn的A記錄(IPv4地址)和AAAA記錄(IPv6地址):sql


Paste_Image.png

從解析結果能夠看出IPv4地址對應的IPv6地址,後32位的3b25:7465實際上就是IPv4地址的16進製表示59=0x3b,37=0x25,116=0x74,101=0x65,明白該規則後也能夠本身進行IPv4向兼容的IPv6地址的轉換,如119.29.29.29的兼容IPv6地址爲64:ff9b::771d:1d1d,其中::表示爲全0。服務器

DNS64解析流程以下圖所示:


圖片 2.png

NAT64原理

在IPv6-only環境中訪問IPv4服務是須要經過NAT64進行網絡地址轉換,以下圖所示:


圖片 3.png



原文連接:http://www.jianshu.com/p/8edfdfa20b29
 
 
=======================================================

1、IPV6-Only支持是啥?

首先IPV6,是對IPV4地址空間的擴充。目前當咱們用iOS設備鏈接上Wifi、4G、3G等網絡時,設備被分配的地址均是IPV4地址,可是隨着運營商和企業逐漸部署IPV6 DNS64/NAT64網絡以後,設備被分配的地址會變成IPV6的地址,而這些網絡就是所謂的IPV6-Only網絡,而且仍然能夠經過此網絡去獲取IPV4地址提供的內容。客戶端向服務器端請求域名解析,首先經過DNS64 Server查詢IPv6的地址,若是查詢不到,再向DNS Server查詢IPv4地址,經過DNS64 Server合成一個IPV6的地址,最終將一個IPV6的地址返回給客戶端。如圖所示:


NAT64-DNS64-ResolutionOfIPv4_2x.png

在Mac OS 10.11+的雙網卡的Mac機器(以太網口+無線網卡),咱們能夠經過模擬構建這麼一個local IPv6 DNS64/NAT64 的網絡環境去測試應用是否支持IPV6-Only網絡,大概原理以下:


local_ipv6_dns64_nat64_network_2x.png

2、Apple如何審覈支持IPV6-Only?

首先第一點:這裏說的支持IPV6-Only網絡,其實就是說讓應用在 IPv6 DNS64/NAT64 網絡環境下仍然可以正常運行。可是考慮到咱們目前的實際網絡環境仍然是IPV4網絡,因此應用須要可以同時保證IPV4和IPV6環境下的可用性。從這點來講,蘋果不會去掃描IPV4的專有API來拒絕審覈經過,由於IPV4的API和IPV6的API調用都會同時存在於代碼中(不過爲了減少審覈被拒風險,建議將IPV4專有API經過IPV6的兼容API來替換)。

其次第二點:Apple官方聲明iOS9開始向IPV6支持過渡,在iOS9.2+支持經過getaddrInfo方法將IPV4地址合成IPV6地址(The ability to synthesize IPv6 addresses was added to getaddrinfo in iOS 9.2 and OS X 10.11.2)。其提供的Reachability庫在iOS8系統下,當從IPV4切換到IPV6網絡,或者從IPV6網絡切換到IPV4,是沒法監控到網絡狀態的變化。也有一些開發者針對這些Bug詢問Apple的審覈部門,給予的答覆是隻須要在蘋果最新的系統上保證IPV6的兼容性便可

最後第三點:只要應用的主流程支持IPV6,經過蘋果審覈便可。對於不支持IPV6的模塊,考慮到咱們現實IPV6網絡的部署還須要一段時間,短期內不會影響咱們用戶的使用。但隨着4G網絡IPV6的部署,這部分模塊仍是須要逐漸安排人力進行支持。

追加第四點:若是應用一直直接使用IPV4地址經過NSURLConenction或者NSURLSession進行網絡請求(通常須要服務器容許,且客戶端須要在header中假裝host);經測試,IPV6網絡環境下,直接使用IPV4地址在iOS9及以上的系統仍然可以正常訪問;在iOS8.4及如下不能正常訪問;這一點蘋果的解釋和建議是這樣的:


Note: In iOS 9 and OS X 10.11 and later, NSURLSession and CFNetwork automatically synthesize IPv6 addresses from IPv4 literals locally on devices operating on DNS64/NAT64 networks. However, you should still work to rid your code of IP address literals.


3、應用如何支持IPV6-Only?

對於如何支持IPV6-Only,官方給出了以下幾點標準:(這裏就不對其進行解釋了,你們看上面的參考連接便可)

1. Use High-Level Networking Frameworks; 2. Don’t Use IP Address Literals; 3. Check Source Code for IPv6 DNS64/NAT64 Incompatibilities; 4. Use System APIs to Synthesize IPv6 Addresses;

3.1 NSURLConnection是否支持IPV6?

官方的這句話讓咱們疑惑頓生:
using high-level networking APIs such as NSURLSession and the CFNetwork frameworks and you connect by name, you should not need to change anything for your app to work with IPv6 addresses

只說了NSURLSession和CFNetwork的API不須要改變,可是並無說起到NSURLConnection。 從上文的參考資料中,咱們看到NSURLSession、NSURLConnection同屬於Cocoa的url loading system,能夠猜想出NSURLConnection在ios9上是支持IPV6的。 

應用裏面的API網絡請求,你們通常都會選擇AFNetworking進行請求發送,因爲歷史緣由,應用的代碼基本上都深度引用了AFHTTPRequestOperation類,因此目前API網絡請求均須要經過NSURLConnection發送出去,因此必須確認NSURLConnection是否支持IPV6. 通過測試,NSURLConnection在最新的iOS9系統上是支持IPV6的。

3.2 Cocoa的URL Loading System從iOS哪一個版本開始支持IPV6?

目前咱們的應用最低版本還須要支持iOS7,雖然蘋果只要求最新版本支持IPV6-Only,可是出於對用戶負責的態度,咱們仍然須要搞清楚在低版本上URL Loading System的API是否支持IPV6.

(to fix me, make some experiments)待續~~~

3.3 Reachability是否須要修改支持IPV6?

咱們能夠查到應用中大量使用了Reachability進行網絡狀態判斷,可是在裏面卻使用了IPV4的專用API。

Pods:Reachability中 AF_INET Files:Reachability.m struct sockaddr_in Files:Reachability.h , Reachability.m

那Reachability應該如何支持IPV6呢?
(1)目前Github的開源庫Reachability的最新版本是3.2,蘋果也出了一個Support IPV6 的Reachability的官方樣例,咱們比較了一下源碼,跟Github上的Reachability沒有什麼差別。
(2)咱們一般都是經過一個0.0.0.0 (ZeroAddress)去開啓網絡狀態監控,通過咱們測試,在iOS9以上的系統上IPV4和IPV6網絡環境均可以正常使用;可是在iOS8上IPV4和IPV6相互切換的時候沒法監控到網絡狀態的變化,多是由於蘋果在iOS8上還並無對IPV6進行相關支持相關。(可是這仍然知足蘋果要求在最新系統版本上支持IPV6的網絡)。
(3)當你們都在要求Reachability添加對於IPV6的支持,其實蘋果在iOS9以上對Zero Address進行了特別處理,官方發言是這樣的:


reachabilityForInternetConnection: This monitors the address 0.0.0.0,
which reachability treats as a special token that causes it to actually
monitor the general routing status of the device, both IPv4 and IPv6.


+ (instancetype)reachabilityForInternetConnection { struct sockaddr_in zeroAddress; bzero(&zeroAddress, sizeof(zeroAddress)); zeroAddress.sin_len = sizeof(zeroAddress); zeroAddress.sin_family = AF_INET; return [self reachabilityWithAddress: (const struct sockaddr *) &zeroAddress]; }

綜上所述,Reachability不須要作任何修改,在iOS9上就能夠支持IPV6和IPV4,可是在iOS9如下會存在bug,可是蘋果審覈並不關心。

4、底層的socket API如何同時支持IPV4和IPV6?

因爲在應用中使用了網絡診斷的組件,大量使用了底層的 socket API,因此對於IPV6支持,這塊是個重頭戲。若是你的應用中使用了長鏈接,其必然會使用底層socket API,這一塊也是須要支持IPV6的。 對於Socket如何同時支持IPV4和IPV6,能夠參考谷歌的開源庫CocoaAsyncSocket.

下面我針對咱們的開源 網絡診斷組件, 說一下是如何同時支持IPV4和IPV6的。
開源地址:https://github.com/Lede-Inc/LDNetDiagnoService_IOS.git
這個網絡診斷組件的主要功能以下:

  • 本地網絡環境的監測(本機IP+本地網關+本地DNS+域名解析);
  • 經過TCP Connect監測到域名的連通性;
  • 經過Ping 監測到目標主機的連通耗時;
  • 經過traceRoute監測設備到目標主機中間每個路由器節點的ICMP耗時;

4.1 IP地址從二進制到符號的轉化

以前咱們都是經過inet_ntoa()進行二進制到符號,這個API只能轉化IPV4地址。而inet_ntop()可以兼容轉化IPV4和IPV6地址。 寫了一個公用的in6_addr的轉化方法以下:

//for IPV6 +(NSString *)formatIPV6Address:(struct in6_addr)ipv6Addr{ NSString *address = nil; char dstStr[INET6_ADDRSTRLEN]; char srcStr[INET6_ADDRSTRLEN]; memcpy(srcStr, &ipv6Addr, sizeof(struct in6_addr)); if(inet_ntop(AF_INET6, srcStr, dstStr, INET6_ADDRSTRLEN) != NULL){ address = [NSString stringWithUTF8String:dstStr]; } return address; } //for IPV4 +(NSString *)formatIPV4Address:(struct in_addr)ipv4Addr{ NSString *address = nil; char dstStr[INET_ADDRSTRLEN]; char srcStr[INET_ADDRSTRLEN]; memcpy(srcStr, &ipv4Addr, sizeof(struct in_addr)); if(inet_ntop(AF_INET, srcStr, dstStr, INET_ADDRSTRLEN) != NULL){ address = [NSString stringWithUTF8String:dstStr]; } return address; }

4.2 本機IP獲取支持IPV6

至關於咱們在終端中輸入ifconfig命令獲取字符串,而後對ifconfig結果字符串進行解析,獲取其中en0(Wifi)、pdp_ip0(移動網絡)的ip地址。

注意:
(1)在模擬器和真機上都會出現以FE80開頭的IPV6單播地址影響咱們判斷,因此在這裏進行特殊的處理(當第一次遇到不是單播地址的IP地址即爲本機IP地址)。
(2)在IPV6環境下,真機測試的時候,第一個出現的是一個IPV4地址,因此在IPV4條件下第一次遇到單播地址不退出。

+ (NSString *)deviceIPAdress
{
        while (temp_addr != NULL) { NSLog(@"ifa_name===%@",[NSString stringWithUTF8String:temp_addr->ifa_name]); // Check if interface is en0 which is the wifi connection on the iPhone if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"] || [[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"pdp_ip0"]) { //若是是IPV4地址,直接轉化 if (temp_addr->ifa_addr->sa_family == AF_INET){ // Get NSString from C String address = [self formatIPV4Address:((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr]; } //若是是IPV6地址 else if (temp_addr->ifa_addr->sa_family == AF_INET6){ address = [self formatIPV6Address:((struct sockaddr_in6 *)temp_addr->ifa_addr)->sin6_addr]; if (address && ![address isEqualToString:@""] && ![address.uppercaseString hasPrefix:@"FE80"]) break; } } temp_addr = temp_addr->ifa_next; } } }

4.3 設備網關地址獲取獲取支持IPV6

實際上是在IPV4獲取網關地址的源碼的基礎上進行了修改,初開把AF_INET->AF_INET6, sockaddr -> sockaddr_in6以外,還須要注意以下修改,就是拷貝的地址字節數。去掉了ROUNDUP的處理。 (解析出來的地址總是少了4個字節,結果是偏移量搞錯了,糾結了半天),具體參考源碼庫。

/* net.route.0.inet.flags.gateway */ int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET6, NET_RT_FLAGS, RTF_GATEWAY}; if (sysctl(mib, sizeof(mib) / sizeof(int), buf, &l, 0, 0) < 0) { address = @"192.168.0.1"; } .... //for IPV4 for (i = 0; i < RTAX_MAX; i++) { if (rt->rtm_addrs & (1 << i)) { sa_tab[i] = sa; sa = (struct sockaddr *)((char *)sa + ROUNDUP(sa->sa_len)); } else { sa_tab[i] = NULL; } } //for IPV6 for (i = 0; i < RTAX_MAX; i++) { if (rt->rtm_addrs & (1 << i)) { sa_tab[i] = sa; sa = (struct sockaddr_in6 *)((char *)sa + sa->sin6_len); } else { sa_tab[i] = NULL; } }

4.4 設備DNS地址獲取支持IPV6

IPV4時只須要經過res_ninit進行初始化就能夠獲取,可是在IPV6環境下須要經過res_getservers()接口才能獲取。

+(NSArray *)outPutDNSServers{ res_state res = malloc(sizeof(struct __res_state)); int result = res_ninit(res); NSMutableArray *servers = [[NSMutableArray alloc] init]; if (result == 0) { union res_9_sockaddr_union *addr_union = malloc(res->nscount * sizeof(union res_9_sockaddr_union)); res_getservers(res, addr_union, res->nscount); for (int i = 0; i < res->nscount; i++) { if (addr_union[i].sin.sin_family == AF_INET) { char ip[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &(addr_union[i].sin.sin_addr), ip, INET_ADDRSTRLEN); NSString *dnsIP = [NSString stringWithUTF8String:ip]; [servers addObject:dnsIP]; NSLog(@"IPv4 DNS IP: %@", dnsIP); } else if (addr_union[i].sin6.sin6_family == AF_INET6) { char ip[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, &(addr_union[i].sin6.sin6_addr), ip, INET6_ADDRSTRLEN); NSString *dnsIP = [NSString stringWithUTF8String:ip]; [servers addObject:dnsIP]; NSLog(@"IPv6 DNS IP: %@", dnsIP); } else { NSLog(@"Undefined family."); } } } res_nclose(res); free(res); return [NSArray arrayWithArray:servers]; }

4.4 域名DNS地址獲取支持IPV6

在IPV4網絡下咱們經過gethostname獲取,而在IPV6環境下,經過新的gethostbyname2函數獲取。

//ipv4 phot = gethostbyname(hostN); //ipv6 phot = gethostbyname2(hostN, AF_INET6);

4.5 ping方案支持IPV6

Apple的官方提供了最新的支持IPV6的ping方案,參考地址以下:
https://developer.apple.com/library/mac/samplecode/SimplePing/Introduction/Intro.html

只是須要注意的是:
(1)返回的packet去掉了IPHeader部分,IPV6的header部分也不返回TTL(Time to Live)字段;
(2)IPV6的ICMP報文不進行checkSum的處理;

4.6 traceRoute方案支持IPV6

實際上是經過建立socket套接字模擬ICMP報文的發送,以計算耗時;
兩個關鍵的地方須要注意:
(1)IPV6中去掉IP_TTL字段,改用跳數IPV6_UNICAST_HOPS來表示;
(2)sendto方法能夠兼容支持IPV4和IPV6,可是須要最後一個參數,制定目標IP地址的大小;由於前一個參數只是指明瞭IP地址的開始地址。千萬不要用統一的sizeof(struct sockaddr), 由於sockaddr_in 和 sockaddr都是16個字節,二者能夠通用,可是sockaddr_in6的數據結構是28個字節,若是不顯式指定,sendto方法就會一直返回-1,erroNo報22 Invalid argument的錯誤。

關鍵代碼以下:(完整代碼參考開源組件)

//構造通用的IP地址結構stuck sockaddr NSString *ipAddr0 = [serverDNSs objectAtIndex:0]; //設置server主機的套接口地址 NSData *addrData = nil; BOOL isIPV6 = NO; if ([ipAddr0 rangeOfString:@":"].location == NSNotFound) { isIPV6 = NO; struct sockaddr_in nativeAddr4; memset(&nativeAddr4, 0, sizeof(nativeAddr4)); nativeAddr4.sin_len = sizeof(nativeAddr4); nativeAddr4.sin_family = AF_INET; nativeAddr4.sin_port = htons(udpPort); inet_pton(AF_INET, ipAddr0.UTF8String, &nativeAddr4.sin_addr.s_addr); addrData = [NSData dataWithBytes:&nativeAddr4 length:sizeof(nativeAddr4)]; } else { isIPV6 = YES; struct sockaddr_in6 nativeAddr6; memset(&nativeAddr6, 0, sizeof(nativeAddr6)); nativeAddr6.sin6_len = sizeof(nativeAddr6); nativeAddr6.sin6_family = AF_INET6; nativeAddr6.sin6_port = htons(udpPort); inet_pton(AF_INET6, ipAddr0.UTF8String, &nativeAddr6.sin6_addr); addrData = [NSData dataWithBytes:&nativeAddr6 length:sizeof(nativeAddr6)]; } struct sockaddr *destination; destination = (struct sockaddr *)[addrData bytes]; //建立socket if ((recv_sock = socket(destination->sa_family, SOCK_DGRAM, isIPV6?IPPROTO_ICMPV6:IPPROTO_ICMP)) < 0) if ((send_sock = socket(destination->sa_family, SOCK_DGRAM, 0)) < 0) //設置sender 套接字的ttl if ((isIPV6? setsockopt(send_sock,IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)): setsockopt(send_sock, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl))) < 0) //發送成功返回值等於發送消息的長度 ssize_t sentLen = sendto(send_sock, cmsg, sizeof(cmsg), 0, (struct sockaddr *)destination, isIPV6?sizeof(struct sockaddr_in6):sizeof(struct sockaddr_in));

 http://www.jianshu.com/p/a6bab07c4062  是 原文地址

 

==================================================

網上好多關於ipv6的資料,說半天ipv6是什麼,怎麼創建測試環境,但是沒有看到具體的操做和解決的方案,這裏,爲你們提供一種方案,但願給你們帶來幫助吧。

總的來講有三個方面須要進行檢查和修改:

一、項目裏面涉及和網絡有關的網絡請求是否支持ipv6。

二、項目裏面涉及和網絡有關的sdk是否支持ipv6。

三、項目的服務器是否支持ipv6。

 

IPv6的簡介

IPv4 和 IPv6的區別就是 IP 地址前者是 .(dot)分割,後者是以 :(冒號)分割的(更多詳細信息自行搜索)。

PS:在使用 IPv6 的熱點時候,記得手機開飛行模式哦,保證手機只在 Wi-Fi 下上網,以避免手機在鏈接不到網絡時候,會默認跳轉到使用 蜂窩移動網絡(即2G、3G、4G流量) 上網。

IPV6,是對IPV4地址空間的擴充。目前當咱們用iOS設備鏈接上Wifi、4G、3G等網絡時,設備被分配的地址均是IPV4地址,可是隨着運營商和企業逐漸部署IPV6 DNS64/NAT64網絡以後,設備被分配的地址會變成IPV6的地址,而這些網絡就是所謂的IPV6-Only網絡,而且仍然能夠經過此網絡去獲取IPV4地址提供的內容。客戶端向服務器端請求域名解析,首先經過DNS64 Server查詢IPv6的地址,若是查詢不到,再向DNS Server查詢IPv4地址,經過DNS64 Server合成一個IPV6的地址,最終將一個IPV6的地址返回給客戶端。參考最上面那張圖。

 

網上對於蘋果官網上ipv6的文章翻譯不少,附上連接,這篇介紹的不錯:iOS應用支持IPV6,就那點事兒

本地 Mac 搭建 IPv6 測試環境

附上連接:本地如何搭建IPv6環境測試你的APP

上邊這些幾乎沒什麼用,網上一搜有不少。。。

如何判斷本身的項目裏面是不是ipv六、ipv4呢,咱們用的方法,就是本身項目裏面涉及和網絡有關的進行一一排查

文章最後會提到ipv6解決的方案除了上述兩點還有一個關於服務器的緣由。

咱們的app自己支持ipv6是由於咱們使用的網絡請求是asihttpRequest請求,而asihttpRequest是基於CFNetwork的,蘋果有說明CFNetwork庫是支持IPV6的。而除了自身的網絡請求外,咱們項目中涉及網絡的就是三方庫了,因此歸根到底咱們作的只是第三方庫的替換,即:哪些三方庫和網絡有關,那麼挨個查看最新的sdk文檔解釋是否描述支持ipv6,若是支持,那就替換。若是沒說支持,那就不換。

(固然,還能夠用cocoadpods替換三方庫,關於cocoadpods的學習能夠參考本人這篇文章Cocoapods安裝

這種方案須要驗證,估計須要幾天的時間才能知道上線是否被拒。若是僥倖上線了,我會第一時間在本文裏面續寫一下。若是被拒,我也會第一時間排查緣由,進行本文的更新。謝謝你們的支持。

已經上線了,該方案可行。

那麼咱們替換了哪些三方庫呢,下邊一一列舉。(文章下部會有各個三方庫的連接)

一、Reachability

按照蘋果開發者中心提示,這個必須換。

 


 

新的sdk包將這個方法幹掉了:reachabilityForLocalWiFi,只要本身的代碼中幹掉就好了,沒什麼影響。

緣由以下介紹:

#pragma mark reachabilityForLocalWiFi

//reachabilityForLocalWiFi has been removed from the sample.  See ReadMe.md for more information.

//+ (instancetype)reachabilityForLocalWiFi;

二、新浪微博

根據官網提示,這個新的sdk支持了ipv6,因此進行替換。

 


 

替換後:

根據比較,新舊sdk只有上述變化,替換後command+B編譯無錯誤提示。應該沒事。

三、連連支付

按照連連支付官方文檔

最新的sdk包是支持ipv6的,可是舊包也是支持的。項目中用的是2.4.0,官網上最新包是2.4.7,最後咱們作了替換。

 


 

替換後報錯了:

 


 

緣由是在新的sdk包裏將報錯的這兩個方法合成了一個。

 


 

在新的方法裏面添加了一個判斷支付類型的參數。

根據項目中報錯的兩個地方,第一個是快捷支付,第二個是認證支付。按照以前的進行了修改。command+B編譯無錯誤提示。應該沒事。

可是實際上仍是遇到了崩潰的bug。而後咱們換回了2.4.0版本,應爲連連支付官網上說以前的版本也支持ipv6,咱們以前的版本沒有問題,因此換了回來,看看上線能成功不。

四、友盟

按照友盟官方sdk文檔描述,須要更換新的sdk包。

 


 

按照須要,勾選了以下:

md,搞錯了,項目裏面的友盟是友盟分析,上邊那個是友盟分享。。。

 


 

可是根據官方文檔,好像咱們的不用替換,由於涉及到什麼IDFA,咱們項目好像不涉及這個。

五、微信

按照微信最新sdk包1.7版本里面的README.txt,最新的sdk包支持ipv6

 


 

而咱們項目中的微信是1.5版本的。應該進行替換。command+B編譯無錯誤提示。應該沒事。

比較好笑的是微信的sdk包是支持ipv6的,可是微信自己並不支持ipv6,因此說,即使你替換了最新的sdk包,在ipv6網絡下仍是不能用微信分享,由於你的app應用在ipv6網絡環境下調不起微信,也就分享不了了,這個問題微信應該意識到了,估計後邊的版本應該也是支持ipv6的吧。

六、QQ

官方文檔好像也沒有說ipv6的事啊

 


 

七、次奧!支付寶sdk支持了ipv6,上午下載的時候沒看見!!!

 


 

但是下載的時候老是打不開.zip的壓縮包。。。叫別人幫忙下載了一份

command+B編譯無錯誤提示。應該沒事。

八、百度地圖

 


 

根據比較,新的sdk包沒有了bundle文件。須要將舊包的bundle文件拷貝進來。

各個sdk下載地址:

reachability

新浪微博

連連支付

友盟統計分析

微信

QQ

支付寶

百度地圖

總之,對於ipv6_Only的處理就是這樣辦的,從兩大方面進行本身審覈:自身網絡請求和三方涉及網絡請求。

關於AFNetworking是否支持ipv-6,有網友如是說:

 


 

可見,AFNetworking是支持ipv-6的。可是,關於支持ipv6的afn版本有以下說明:

 


 

另外有網友遇到這樣一個問題:這裏還遇到一個坑,內網的訪問下是不可能鏈接到本身的服務器,後面測試一下公網阿里雲的服務器,可以正常鏈接,這個多是DNS64在搜索ipv6的過程當中,並無搜索內網的網絡,致使內網鏈接失敗(這裏卡了半天, 切記)(這個問題筆者並無遇到,也沒有親測,你們注意一下這個問題,若是遇到了,知道是怎麼回事。)

最後,有的網友上線被拒了,多是由於app的服務器端沒有支持ipv6,就此問題,我諮詢了咱們的技術經理,技術經理說「後臺(即服務器)是要作ipv6的支持工做的」。可是具體是誰管,具體怎麼操做的我就不得而知了,這裏你們注意一下吧:不只僅是客戶端這邊支持ipv6,上線以前最好問一下後臺端是否是作了相應的ipv6的支持。

這裏關於本身的服務器是否支持ipv6,有網友提供了一個方法,你們能夠試一下。(謝謝杭州-托兒索被拒6次的ipv6,爭得托兒索的贊成,進行轉發)


 

前兩條說的就是咱們的方案:項目裏面涉及和網絡有關的進行一一排查

第三條是在本身電腦上判斷是否服務器支持ipv6的。親測,在終端獲得下圖:


 

按照托兒索的說法,上圖的位置那裏顯示NOERROR說明服務器沒有問題,也是支持ipv6的。若是有錯的話,能夠按照下邊提供的表格進行對照。


 

再看託兒所的結論,咱們會獲得下邊的結論,涉及支持ipv6的實際上是包括三個方面的:

一、項目裏面涉及和網絡有關的網絡請求是否支持ipv6。

二、項目裏面涉及和網絡有關的sdk是否支持ipv6。

三、項目的服務器是否支持ipv6。

最後,說一下關於托兒索的命令行:終端  dig +nocmd + nostats 你的域名 AAAA,我在網上查了一下發現有這麼個命令行:


 

爲了方便複製:digwww.isc.orgAAAA +short 


 

獲得的結果直接就是一個ipv6格式的,不知道不支持ipv6服務器的是否是打印出來的是否是ip地址(有待驗證)。若是誰驗證了,但願告知我一聲。在此謝謝了。因此也能夠用這個命令行側面驗證服務器是否支持ipv6。

相關文章
相關標籤/搜索