1. 程式人生 > >錯誤: iOS稽核被拒之 ipv6

錯誤: iOS稽核被拒之 ipv6

錯誤

最近蘋果稽核應用時, 被拒了, 才發現不支援IPv6
We discovered one or more bugs in your app when reviewed on iPad running iOS 10.3.2 on Wi-Fi connected to an IPv6 network.

解決

蘋果從iOS9開始向IPv6的網路服務過渡。2016年初開始所有提交到App Store的應用必須支援IPv6。蘋果於2016年5月4日告知開發者應用需要在6月1日前支援IPv6-only,也就是說在 6 月 1 日後釋出的新版本是需要支援 IPv6-only. 所以需要後臺伺服器進行ipv6的設定。

拓展

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的地址返回給客戶端。如圖所示:

Apple如何稽核支援IPV6-Only?

1.這裡說的支援IPV6-Only網路,其實就是說讓應用在 IPv6 DNS64/NAT64 網路環境下仍然能夠正常執行。但是考慮到我們目前的實際網路環境仍然是IPV4網路,所以應用需要能夠同時保證IPV4和IPV6環境下的可用性。從這點來說,蘋果不會去掃描IPV4的專有API來拒絕稽核通過,因為IPV4的API和IPV6的API呼叫都會同時存在於程式碼中(不過為了減小稽核被拒風險,建議將IPV4專有API通過IPV6的相容API來替換)。

2.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的相容性即可。

3.只要應用的主流程支援IPV6,通過蘋果稽核即可。對於不支援IPV6的模組,考慮到我們現實IPV6網路的部署還需要一段時間,短時間內不會影響我們使用者的使用。但隨著4G網路IPV6的部署,這部分模組還是需要逐漸安排人力進行支援。

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

不建議使用底層的網路API

下圖展示的藍色部分的這些API都是不存在相容性問題的,而我們平時自己用的包括那些第三方的網路庫大部分都是用的這些API。

其中藍色部分的高階API,其實都已經幫我們做好了IPv6的支援,我們使用的大多數第三方網路庫也都是基於這些高階API的,所以這裡我們不需要做什麼改動。 需要注意的是下面的紅色部分的底層的socket API需要做出適配支援。

不要用IP地址

確保您沒有將點號符號的IPv4地址文字傳遞給API,例如getaddrinfo和SCNetworkReachabilityCreateWithName。 相反,使用高階網路框架和地址不可知版本的API,例如getaddrinfo和getnameinfo,並傳遞它們的主機名或完全限定的域名。

注意:在iOS 9和OS X 10.11及更高版本中,NSURLSession和CFNetwork會在本地在DNS64 / NAT64網路上執行的裝置上自動從IPv4文字中綜合IPv6地址。 但是,您仍然應該刪除IP地址文字的程式碼。

檢查不相容IPv6的程式碼

搜一下工程裡有沒有下面的這些API,這些都是隻針對IPv4做處理的,有的話就刪了。

inet_addr()
inet_aton()
inet_lnaof()
inet_makeaddr()
inet_netof()
inet_network()
inet_ntoa()
inet_ntoa_r()
bindresvport()
getipv4sourcefilter()
setipv4sourcefilter()

如果用到了下面左邊的這些IPv4的型別,那麼它們相應的IPv6型別也需要做處理

搭建IPv6測試環境

首先通過Mac的共享網路共享一個IPv6的無線網,跟已往建立方式不同的是進入共享時需要按住Option鍵

需要使你的iPhone連線上分享出來的熱點即可, 通過WiFi在連線網路。
注; 手機上面的 HTTP代理必須關閉