iOS10和Xcode8踩坑
iOS10和Xcode8的GM版放出后,iOS10适配工作就非常重要了。Xcode8下完打开项目后就陆续碰到了一些坑,本文对此这些坑做一些记录。
无法打开的xib和storyboard
由于同事们还在Xcode7.3上开发,然而你用Xcode8打开xib或storyboard后,会弹出一个选择机型的框,如果想要用Xcode8改xib或storyboard,就必须choose
然而你choose后,同事用7.3去打开这个xib或者storyboard你会发现,打不开了,这不是逗比了吗?
不过也可以通过source code去删除掉版本限制,不过建议还是不要这样做。
控制台的疯狂
控制台输出不相关信息
跑起项目后发现控制台在疯狂输出,根本无法看到自己的打印输出
需要EditScheme -> 左侧Run -> 右侧Arguments -> 下方Environment Variables -> 添加 OS_ACTIVITY_MODE = disable
真机调试打印显示不全(2016.10.24补充)
这几天调试时发现,使用Xcode8+iOS10调试时,首先是真机输出打印不输出,后面发现是因为上面设置的OS_ACTIVITY_MODE = disable
影响到了打印输出,取消这个设置后后虽然能打印了。
但是又出现一个新问题:在iOS10真机调试打印请求回调的json居然截断了(显示不全),但是Xcode8+iOS9却正常,经过一番查询,解决办法是在pch里用printf重新定义一下NSLog。
具体代码如下:
1 |
注释失效了
终端来一发sudo /usr/libexec/xpccachectl
然后重启
新增的文档注释
Xcode8里加入了喵神的文档注释,但是貌似功能没有之前插件的强,新的文档注释使用快捷键Option + Command + /
不过这个文档注释并不能像喵神的插件一样随意使用,如下图的时候就报提示没找到需要进行文档注释的东西😂
label显示不全
详见上一篇iOS10的label文字显示不全问题
权限授权
在排查上个label显示不全问题的时候,发现调相机崩了,调相册崩了,调定位又崩了,但是xcode7打的包在iOS10手机安装使用却是正常,什么👻
这次Xcode8对调用各种隐私权限做了控制,在调试的时候,需要在info.plist里声明你的权限和对应的提示文案,比如相册权限
其他权限
可以在info.plist值看到所有Private - 开头的都是
xib和storyboard布局混乱
问题详述
使用Xcode8偶然打开了项目中的storyboard文件,然后跑起项目,却发现界面全乱了
造成原因
经过一番搜索后,发现Xcode8对xib和storyboard做出了一些修改,似的在awakeFromNib
和viewDidLoad
方法中拿自己拖上去的控件的frame均变成了(0, 0, 1000, 1000)
,若直接在此使用控件frame进行二次修改,如:修改A控件的宽为B控件的一半,则B控件实际当前的宽是1000,就会造成混乱。解决办法是在使用原控件frame之前调一次layoutIfNeeded
方法。
查证实践
- 使用Xcode7建一个项目,拖一个tableview和cell,给cell上拖一个imageview和一个label,并设置约束
- 在viewController的viewDidLoad中打印调用layoutIfNeeded前后各元素的frame
- 在cell的awakeFromNib调用layoutIfNeeded方法前后打印frame,并测试给cell赋值后是否frame也需要调用
- 在Xcode7中运行,打印结果
发现原在Xcode7时,viewDidLoad和awakeFromNib中能获取正常的frame
- 使用Xcode8,并点开storyboard后
发现git修改记录中删除了很多标签的元素
在Xcode8中运行后,打印结果,发现viewDidLoad和awakeFromNib中,执行layoutIfNeeded之前拖上去的控件的frame都变成了{0, 0, 1000, 1000},执行之后的frame是正常的,给cell赋值时的frame也是正常的。
- 再次打开Xcode7, 使用source code模式删除storyboard中版本限制后,再以interface builder方式打开storyboard,发现size被设置成了inferred模式,而且各控件的值也是不对的。
结论
在更新Xcode8后,并打开了某个xib/storyboard后,最好run下看看是不是乱了。如果乱了,就去对应的controller或cell看看是不是在viewDidLoad
和awakeFromNib
中使用了控件的frame,如果使用了,请在使用前调用layoutIfNeeded
方法。
如:之前我司项目中的布局乱了,确实是在awakeFromNib
中利用控件的frame来修改某个控件的frame,于是就坑了。
然后,加上调用layoutIfNeeded
后,就恢复如初了。
swift版本兼容问题
如果工程中使用了swift,则第一次使用xcode8打开时,会弹窗提示转换,也有可能不弹窗而且是编译的时候,报错,错误如下:
1 | Use Legacy Swift Language Version” (SWIFT_VERSION) is |
如图:
实际上就是提示你去转换一下swift版本,因为在Xcode7.3.1时swift为2.2,而xcode8支持swift2.3或者swift3.0。如果是直接弹窗提示了,且你是纯swift工程或是自己写的siwft库,可以尝试转换一下,虽然可能他的修改建议不合适。如果是三方库是swift写的,可以考虑等待三方库更新。
解决方法
- 引入swift2.3/3.0的三方库 或者 自行修改之后,手动从Xcode菜单栏->Edit->Convert->To Current Swift Syntax…打开迁移引导。
- 选择符合的swift版本
- 勾选需要转换的framework或者工程
比如:我司项目使用了一个swift库Charts,使用pod引入最新支持2.3的版本后,xcode8会报错让执行迁移引导,实际上勾选并点击next后,会提示不需要转换。(此图是已经进行过迁移引导后的截图,所以下方会提示已经转换成2.3的语法了)
- 目前还有pod useFramework导致其他库.h文件找不到问题,还在尝试解决