iOS9適配總結

http://www.mamicode.com/info-detail-1158873.htmljavascript

 

每一年iOS升級,都會帶來一些坑,此次iOS9也不例外。本文總結了微信在適配iOS9上遇到的問題和解決方案。css

 

1、iOS9問題彙總html

 

1. 編譯問題(Bitcode)java

大部分人升級到Xcode7後,首先遇到的問題是編譯不過,錯誤提示大體是windows

xxx does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target.

這是由於Xcode7默認啓用Bitcode,可是若是咱們用到的第三方庫編譯時還沒啓用Bitcode,主工程就會編譯不過。安全

最簡單的解決辦法是先把Bitcode關掉:把Build settings - Build Options - Enable Bitcode 改成NO。不過,這只是權宜之計。Bitcode是蘋果App Thinning的機制之一,能夠減小安裝包的大小,等咱們把全部庫都替換成支持Bitcode以後,主工程就能夠啓用Bitcode了。微信

 

二、HTTP請求失敗網絡

解決了編譯問題後,程序跑起來了,卻發現不少網絡請求失敗。這是由於iOS9默認不支持HTTP請求,須要改用更安全的HTTPS(默認用TLS 1.2)。app

但事實上,有些地方用HTTP比HTTPS更適合,並且把服務端升級到TLS 1.2也不是一時半會可以搞定的。幸虧蘋果還提供了配置,使得全部安全性更低的網絡請求也能使用,解決方案就是在info.plist裏面增長如下配置:函數

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

若是複雜一些,還能夠指定白名單域名,聲明所支持TLS的最低版本,這裏就再也不詳細描述了。

 

另外須要注意的是,即便寫了上述配置,在HTTPS頁面中,HTTP的javascript或css不會被加載,由於蘋果認爲這下降了頁面的安全性。

 

三、canOpenUrl限制

canOpenUrl能夠用來判斷用戶是否安裝了某個APP。也許是出於用戶隱私的考慮,iOS9上對canOpenUrl作了限制,最多隻能對50個scheme作判斷。

若是是用Xcode7編譯,須要在plist裏面聲明這些scheme,沒有聲明的會直接返回NO:

 

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>weixin</string>
    <string>wechat</string>
</array>

若是是用Xcode6編譯,系統會在用戶手機上記住APP每次調用canOpenUrl的scheme,若是累計達到50種,剩下的其它調用,也會直接返回NO。因此在iOS9beta剛出來的時候,有些用戶沒法從微信跳轉到第三方app,就是由於已經達到了限制數量,系統直接返回NO,程序覺得用戶沒有安裝該APP,就沒有去跳轉。

 

解決辦法是加白名單,而且儘可能減小沒必要要的canOpenUrl調用,以避免超過50個名額的限制。

例如,openUrl函數是不受限制的(在iOS9的某beta版上,openUrl也受一樣限制,但跟蘋果溝通後確認是iOS的bug,後面的版本也已經更正過來了),因此對於

if (canOpenUrl(scheme)) then openUrl(scheme);
else xxx;

這種只須要改寫成

if (!openUrl(scheme)) then xxx;

就不用佔用白名單了。

 

四、systemName

[[UIDevice currentDevice] systemName]在過去版本中一直返回"iPhone OS",但在iOS9.1 beta中,這個函數返回值變成了"iOS"。

這個看似不起眼的改動,卻使得微信出現了不少問題。刷了9.1beta的用戶會發現,全部的公衆號消息、小視頻、紅包等消息都沒法查看,登錄驗證也會失敗。這是由於後臺依賴systemName來判斷設備類型,未知類型會使得後臺覺得該設備不支持某些功能,致使該功能失效。

解決方法是後臺修改判斷條件,並吸收教訓支持可配置,上線後解決了這個問題。

然而,在iOS9.1正式版上,蘋果又把systemName改回"iPhone OS"了。或許蘋果也發現這個小小的改動會引發一些致命問題,因此又改了回來。

 

五、preferredLanguages

[NSLocale preferredLanguages]會返回用戶的首選語言。在以前的版本,系統用"zh-Hans"來表示簡體中文,這個常量在iOS9.0beta上也是如此。然而到了iOS9.0正式版,蘋果忽然在後面加了國家碼後綴,變成了"zh-Hans-CN"。可是,對於臺灣繁體中文,卻沒有變化,依然是"zh-TW"。

這個變更致使部分用戶升級到iOS9,微信語言變成了英文。這是由於程序在用戶首選語言中沒匹配到簡體中文的選項。

目前咱們解決辦法是改用前綴匹配。

 

六、API更新

iOS9照例淘汰了一些舊接口,其中有一些舊接口雖然還能用,但或多或少都會有些問題:

 

6.1 AddressBookUI.framework在iOS9上已經被淘汰,須要改用ContactsUI.framework

舊接口還可以讀取通信錄,可是添加信息到通信錄時,系統界面會卡住。

 

6.2 UIAlertView須要改爲UIAlertController

舊接口還可以使用,只是在有鍵盤的狀況下彈UIAlertView,可能會有鍵盤閃現等體驗問題。

 

6.3 UIPopoverController須要改用普通的UIViewController,設置modalPresentationStyle=UIModalPresentationPopover,而後present出來

舊接口也可以使用,但在iPad分屏下會有問題。

 

七、windowLevel問題

以下圖所示,當鍵盤已經彈起的時候,再顯示咱們本身寫的確認窗口等window,會發現window被鍵盤擋住了。

技術分享



這是由於iOS9下系統鍵盤的windowLevel是很高的,達到10^7。並且進一步發現,這個值是系統容許的最大值。若是把某個window的windowLevel改爲比10^7大的值,系統只會設爲10^7。

解決這個問題有兩種方法:

一個是把咱們本身window的level調大,一樣設爲10^7,由於比系統鍵盤晚出現,因此仍是可以把系統鍵盤蓋住。這種方法的缺點是使得window的層次結構很差管理,且依賴於系統鍵盤的level。並且window上也沒法再顯示UIAlertView等系統窗口了。

另外一種方法是在顯示window時先調用[mainWindow endEditing:YES],把主window的鍵盤收起來,而後再顯示window。這種方法的缺點是,有些場景下用戶是正在輸入的,收起鍵盤對用戶的體驗很差。

兩種方法各有優缺點,能夠根據使用場景來選擇。

 

8. 啓動crash(window.rootViewController問題)

crash信息爲:Application windows are expected to have a root view controller at the end of application launch

緣由是啓動完的時候,若是現有的window沒有rootViewController,就會crash。

解決辦法就是按要求設置rootViewController。

注:啓動完後再生成的window,能夠不設rootViewController,但仍是建議之後全部window都要設。

 

2、iPad分屏

 

一、如何啓用iPad分屏

a. 用Xcode7 iOS9 SDK編譯

b. 用Launch StoryBoard作啓動界面

c. 支持全部的旋轉方向

 

須要注意的是,支持分屏後,iPad上全部界面都須要支持轉屏。若是之前經過supportedInterfaceOrientations等函數來限制某些界面在iPad上不能轉屏,在啓用分屏後這個限制將失效。

 

若是不支持分屏,須要在項目設置中的General - Deployment Info中勾選Requires full screen

 

二、如何適配iPad分屏

分屏和轉屏本質上都是改變了屏幕的尺寸。正常來講,若是界面適配了iPad轉屏(不論是用哪一種方式,例如AutoLayout,或者AutoResizing,或者是在viewDidLayoutSubviews裏面從新排版,等等),那在iPad分屏下也可以正常顯示。(除了一些特殊狀況,例如hardcode了屏幕尺寸等,見後面第3點。)

若是界面在不一樣尺寸的屏幕下有不一樣的排版設計,官方的建議是根據系統回調在Regular模式和Compact模式之間切換。微信由於是使用了配置文件來處理不一樣設備的排版差別的,因此根據本身的實際狀況,採用如下原則:在320屏幕下按照iPhone5的排版;438屏幕下按照iPhone6的排版,其它分屏下按照iPad的排版。

 

三、分屏後的幾個問題

3.1 有了分屏後,APP當前屏幕的大小不能再用[UIScreen mainScreen].bound來獲取了,這個取到的是整個設備的屏幕大小,不是分屏後的屏幕大小。

解決辦法是,啓動時初始化window,不須要initWithFrame,直接用init就能夠了。系統知道當前屏幕的大小,會幫咱們正確地設置frame。而後取這個frame就能拿到實際屏幕大小了。

 

3.2 之前適配iPad轉屏時,有些地方會使用willRotateToInterfaceOrientation等轉屏回調來處理屏幕尺寸變化。從iOS8開始,系統新增了viewWillTransitionToSize:withTransitionCoordinator回調來代替它。新的回調能夠用來處理轉屏和分屏引發的屏幕尺寸變化。

 

3.3 分屏狀態下,系統的視頻錄製功能不可用。若是某個功能用到了視頻錄製功能,建議像系統照相機同樣,在分屏時給用戶提示一下。

 

3.4 避免hardcode。要注意iPad的屏幕再也不是1024*768,並且在運行中屏幕的尺寸是會隨時變化的(分屏或轉屏時),因此若是之前有些代碼作了hardcode,會致使分屏後有bug。

 

3、總結

本文總結了微信在適配iOS9中遇到的常見問題,相信iOS9還有其它深坑有待挖掘,歡迎你們補充。

iOS9適配總結

相關文章
相關標籤/搜索