AppStore發(fā)布之后的應用要兼容IPv6。
然而我上個星期發(fā)布的版本并沒有因為沒兼容而被拒,這次提交卻遇到IPv6兼容問題。。。
話不多說,上代碼:
+(NSString*) getIPWithHostName:(constNSString*)hostName ? {
structaddrinfo * result;
structaddrinfo * res;
charipv4[128];
charipv6[128];
int error;
BOOLIS_IPV6 =FALSE;? ?
?bzero(&ipv4,sizeof(ipv4));??
? bzero(&ipv4,sizeof(ipv6));? ??
error = getaddrinfo([hostName UTF8String],NULL,NULL, &result);
if(error !=0) {
NSLog(@"error in getaddrinfo:%d", error);
return nil;? ?
?}
for(res = result; res!=NULL; res = res->ai_next) {
charhostname[1025] ="";? ?
?error = getnameinfo(res->ai_addr, res->ai_addrlen, hostname,1025,NULL,0,0);
if(error !=0) {
NSLog(@"error in getnameifno: %s", gai_strerror(error));continue;? ?
?}else{
switch(res->ai_addr->sa_family) {
case AF_INET:? ? ? ? ? ? ? ??
memcpy(ipv4, hostname,128);
break;
case AF_INET6:? ? ? ? ??
memcpy(ipv6, hostname,128);? ? ? ? ? ? ? ??
IS_IPV6 =TRUE;
default:
break;? ? ??
? }
NSLog(@"hostname: %s ", hostname);? ?
?}? ??
}? ?
?freenaddrinfo(result);
if(IS_IPV6 ==TRUE)
return[NSStringstringWithUTF8String:ipv6];return[NSStringstringWithUTF8String:ipv4];? ? }
這段代碼即判斷了是否IPv6環(huán)境并解析域名獲得了IP地址。
測試
首先得配置IPv6網(wǎng)絡環(huán)境,至于如何配置,自行百度"如何搭建IPv6的測試環(huán)境"。
然而配置成功后,用手機連接的WiFi DNS也是正確的,運行程序測試怎么不成功呢,找了好多資料,猜測是DNS解析除了問題。
那就換另一種方法配置IPv6:拔掉網(wǎng)線,用mac連接WiFi(沒有WiFi可以用手機流量分享熱點),然后在共享中用前一種方法配置IPv6(不知道具體是共享到電腦那個端口,索性全點上),記得選中"創(chuàng)建NAT64 網(wǎng)絡"。這時直接通過模擬器測試succeed!
測試成功了。你以為就沒問題了?這里提交依然可能被拒,手機和 Mac 之間是 IPv6 沒錯,但 Mac 和你的服務器之間還是 IPv4 連接。
如果這項測試通過,可以說明:你的客戶端應用在 IPv6 網(wǎng)絡下,是(基本)沒有問題的,但是無法驗證你的服務器能夠?qū)?IPv6 網(wǎng)絡做出正確的響應。然而,蘋果審核的時候,卻是要去 DNS 服務器詢問你的服務器的 IPv6 地址,然后進行訪問。如果查詢不到 IPv6 地址,可能會進而詢問 IPv4 地址,然后進行轉(zhuǎn)換使用。蘋果明確表示服務器不需要支持 IPv6,但是有一點蘋果沒有指出來,那就是,雖然你的服務器不用支持 IPv6,但是必須正確響應 IPv6 的 DNS 查詢。
如何驗證呢??使用以下命令即可:
$?dig?+nocmd?+nostats?example.com?AAAA
如果返回的 status 為 NOERROR, 那基本就沒什么問題,但是一定要在多個網(wǎng)絡環(huán)境下測試都通過才行。如果返回的是其他的響應,尤其是 SERVFAIL 的情況,那就基本杯具了。由于你已經(jīng)驗證了客戶端沒有問題,現(xiàn)在要做的,就是催著你的運維、后臺啥的,趕緊去改 DNS 配置,直到穩(wěn)定返回 NOERROR 為止。