对于苹果要求6月1日后所有的app必须支持IPv6-only网络的问题,苹果官方文档给出的说明:
https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/UnderstandingandPreparingfortheIPv6Transition/UnderstandingandPreparingfortheIPv6Transition.html#//apple_ref/doc/uid/TP40010220-CH213-SW25
一.如何确保支持IPv6-only:
1) 使用高级的网络框架(Use High-Level Networking Frameworks)
从上图可以看出,这里的高级网络框架包括三类:
- WebKit
- Cocoa URL loading system:
NSURL, NSURLSession, NSURLRequest, NSURLConnection
ps:最开始我们一直搞不清楚NSURLConnection在IPv6-only下是否可以继续使用,从这里来看,是可用的。
在stackoverflow上找到了相关的问题:
http://stackoverflow.com/questions/37067619/do-i-need-to-replace-nsurlconnection-in-order-to-achieve-mandatory-support-for-i - CFNetwork
2)不要使用硬编码的IP地址(Don’t Use IP Address Literals)
在iOS9和OS X 10.11以后,NSURLSession和CFNetwork会自动的把IPv4编码转换成IPv6地址,但是我们还是要尽量避免使用IP地址
3)无预检链接(Connect Without Preflight)
这里主要是针对Reachability APIs的使用(SCNetworkReachbility Reference)来检查网络连接状况所带来的一些问题。许多app对这些APIs有不正确的使用。比如把0.0.0.0这样一个IPv4的地址传给SCNetworkReachabilityCreateWithAddress方法去主动检查网络连接状况。这样来表明这里有一路由的存在,却并不能表示网络连接一定存在。
所以我们要避免去预检测网络可达性,而就是使用网络连接,并且优雅的处理失败的情况就可以了。如果你一定要检查网络的可达性,也要避免调用SCNetworkReachabilityCreateWithAddress方法,而改用SCNetworkReachabilityCreateWithName 方法,使用主机名来作为参数。
还有一些app会通过把自己分配的本地连接169.254.0.0这样一个IPv4的地址传个SCNetworkReachabilityCreateWithAddress方法来检查Wi-Fi的连通性。其实检查Wi-Fi的连通性,可以使用网络可达性的标志位kSCNetworkReachabilityFlagsIsWWAN来代替。
4)使用适当大小的地址存储容器(Use Appropriately Sized Storage Containers)
比如sockaddr_storage,它的大小足够用来存储IPv6的地址。
5)检查IPv6 DNS64/NAT64不兼容的源码(Check Source Code for IPv6 DNS64/NAT64 Incompatibilities)
检查并消除IPv4特定的APIs,比如:
inet_addr()
inet_aton()
inet_lnaof()
inet_makeaddr()
inet_netof()
inet_network()
inet_ntoa()
inet_ntoa_r()
bindresvport()
getipv4sourcefilter()
setipv4sourcefilter()
如果你的代码处理了IPv4类型,请确认与这些类型等价的IPv6类型也同样做了处理。
6)使用系统APIs来合成IPv6地址
主要是指可以使用getaddrinfo方法来对强制需要使用IPv4地址的情况,进行处理。
二.如何验证:
验证方式是使用Mac建立一个IPv6的无线网,通过共享网络,是iPhone连接到电脑的热点进行测试。