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适配总结

相关文章
相关标签/搜索