參考鏈接:
蘋果新聞:Supporting IPv6-only Networks
適配參考:Supporting IPv6 DNS64/NAT64 Networks
蘋果的Reachability:About Reachability
適配的工作多集中在 Reachability 和 SCNetworkReachability 兩個地方.疑問也大多出自于此;
Connect Without Preflight
The Reachability APIs (see SCNetworkReachability Reference) are intended for diagnostic purposes after identifying a connectivity issue. Many apps incorrectly use these APIs to proactively check for an Internet connection by calling the SCNetworkReachabilityCreateWithAddress
method and passing it an IPv4 address of 0.0.0.0
, which indicates that there is a router on the network. However, the presence of a router doesn’t guarantee that an Internet connection exists. In general, avoid preflighting network reachability. Just try to make a connection and gracefully handle failures. If you must check for network availability, avoid calling the SCNetworkReachabilityCreateWithAddress
method. Call the SCNetworkReachabilityCreateWithName
method and pass it a hostname instead.
Some apps also pass the SCNetworkReachabilityCreateWithAddress
method an IPv4 address of 169.254.0.0
, a self-assigned link-local address, to check for an active Wi-Fi connection. To check for Wi-Fi or cellular connectivity, look for the network reachability flagkSCNetworkReachabilityFlagsIsWWAN
instead.
根據上文所述,蘋果應該是禁止使用
SCNetworkReachabilityCreateWithAddress
方法,而是應該用SCNetworkReachabilityCreateWithName
代替,但是再看蘋果官方的 Reachability 最新適配 IPv6 的版本發現,依然在使用 SCNetworkReachabilityCreateWithAddress.
而且已經適配了 IPv6 的 AFNetWorking 也使用了此方法,所以至少可以確定,使用SCNetworkReachabilityCreateWithAddress是不會存在問題,如下圖,參考Reachability 與 AF,至少使用 sockaddr_in
結合 SCNetworkReachabilityCreateWithAddress 是不會有問題的。我猜測蘋果所說可能是禁止使用 169.254.0.0 這樣的 ip 地址吧.
此處有個疑問是為什么AF做兩部判斷,而 Reachability 不做判斷,這個問題在 issue 中也可以找到,下面自己可能需要對不同設備不同版本進行測試,確認下.
總結下我最終適配方案:
AF首先更新到最新;
Reachability 更換為蘋果最新的適配 IPv6 的版本;
判斷網絡使用 Reachability 中的 reachabilityWithHostName 方法;
此方法我是針對非 iOS9 和 iOS8 的設備在 IPv6 網和正常網絡下都進行了測試可以正常使用的;
而對于 Reachability 中 reachabilityForInternetConnection 方法在非 iOS9 下有bug的問題,我就參考了AF的處理方法,進行系統版本判斷,經過測試,可以正常使用;
相關鏈接:
preflight check with SCNetworkReachabilityCreateWithAddress using a zero IPv6 address
[轉自GeekerProbe]-Support for IPv6