在2016年9月14日凌晨iOS10系统准时推送过来了,作为懒人之前的beta版一直没有升级试用。今天果断手机和Xcode一起升级了,新系统新面貌带来新bug。记录一下升级iOS10和Xcode8.0后遇到的问题。
开发者证书不能使用
General里面Signing变成如下样子,Automatically manage signing 自动签名管理。报错了,之前一直使用的企业级开发者证书不可用了。

Build Settings 里面的 Code Signing Identity 清一色选择为企业级开发者证书。还是报错


解决办法:
取消Automatically manage signing的选择,会出现两个Signing,分别对应Debug和Release,选择该项目对应使用的Provisioning Profiles即可

注释快捷键command+/失效
Xcode8.0的注释// 生成快捷键 command+/失效了
解决办法:
终端运行命令:sudo /usr/libexec/xpccachectl
Password:输入开机密码
重启Mac生效
生效后空行快捷键,只在代码行能产生/解除注释,空行不能产生注释。记得之前可以来这….
Xcode控制台输出问题
无用log打印
升级Xcode8.0之后运行项目,控制台疯狂打印了N多东西,完全看不懂啊,完犊子了,这么多需要适配的…
眼不见心不烦,下面就提供去掉这些乱七八糟打印内容的方法。
解决办法:
在Edit Scheme...下的Run -> Arguments -> Environment Variables 添加 OS_ACTIVITY_MODE = disable
具体见下图

真机测试log屏蔽
经过上述修改,在iOS10模拟器中无用的log输出被屏蔽了,但是真机测试的时候,没有log输出,log日志被完全屏蔽了。不知是屏蔽无用log的设置,还是xcode8为了提高真机测试性能屏蔽了log日志?真机测试的log也很重要。
为了app正式发布时不打印log,让打印操作NSLog只在Debug环境下运行,采用了下面的办法自定义NSLog:
1 | #ifdef DEBUG |
iOS10之后,在真机中NSLog无法打印log,可以使用printf(),具体修改见下面自定义log:
1 | #ifdef DEBUG |
XDString是获取的该log在哪个文件里,__LINE__该log在第几行。printf()是c语言方法,所以要用UTF8String转义,不然每个log都会有警告。
类型判断
网络获取数据,做容错处理,判断某个字段是否符合需要的数据类型。之前一度用如下判断方法:
1 | [NSStringFromClass([userDict[@"plates"] class]) isEqualToString:@"__NSCFArray"] |
如果userDict[@"plates"]的数据类型是数组的话,打印出来的就是__NSCFArray类型。同样如果是字典类型的话,打印出来的就是__NSCFDictionary。但是iOS10之后,打印出来的不同了,同样的数组类型,打印出来的是__NSSingleObjectArrayI。
之前的这种判断方法很欠考虑,还是利用下面的方法比较靠谱:
1 | [userDict[@"plates"] isKindOfClass:[NSArray class]] |
URL Schemes跳转系统设置
跳转系统设置分为跳转到系统设置列表和跳转到自己app的系统设置。
跳转系统设置列表的方法在iOS10被彻底关闭了,也就是说你已不能从app跳转到系统设置列表里了。但是还可以跳转到自己app的系统设置
例如:我的某个app使用地理定位,运行app时会检测是否开启地理定位,如果未开启,提醒alert,用如下代码点击跳转到地理定位的开启设置里。
iOS10之前使用下面方法可以跳转到系统设置列表,列表里有自己的app,可以点击进去做相应设置.使用时要添加URL Schemes,字段为prefs。

1 | NSURL *url = [NSURL URLWithString:@"prefs:root=LOCATION_SERVICES"]; |
iOS10时该方法被关闭了,只能通过下面方法跳转到自己app的系统设置,使用UIApplicationOpenSettingsURLString,这个字段是在iOS8时出现的。在使用这个方法时,注意iOS8/iOS9时可以使用openURL:,iOS10建议使用openURL:options:completionHandler:
1 | NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; |
运行结果:
| 跳转到系统设置列表,iOS10之前可用 | 跳转到自己app的系统设置,iOS8以后可用 |
|---|---|
![]() |
![]() |
附prefs:root
prefs:root=General&path=About
prefs:root=General&path=ACCESSIBILITY
prefs:root=AIRPLANE_MODE
prefs:root=General&path=AUTOLOCK
prefs:root=General&path=USAGE/CELLULAR_USAGE
prefs:root=Brightness
prefs:root=General&path=Bluetooth
prefs:root=General&path=DATE_AND_TIME
prefs:root=FACETIME
prefs:root=General
prefs:root=General&path=Keyboard
prefs:root=CASTLE
prefs:root=CASTLE&path=STORAGE_AND_BACKUP
prefs:root=General&path=INTERNATIONAL
prefs:root=LOCATION_SERVICES
prefs:root=ACCOUNT_SETTINGS
prefs:root=MUSIC
prefs:root=MUSIC&path=EQ
prefs:root=MUSIC&path=VolumeLimit
prefs:root=General&path=Network
prefs:root=NIKE_PLUS_IPOD
prefs:root=NOTES
prefs:root=NOTIFICATIONS_ID
prefs:root=Phone
prefs:root=Photos
prefs:root=General&path=ManagedConfigurationList
prefs:root=General&path=Reset
prefs:root=Sounds&path=Ringtone
prefs:root=Safari
prefs:root=General&path=Assistant
prefs:root=Sounds
prefs:root=General&path=SOFTWARE_UPDATE_LINK
prefs:root=STORE
prefs:root=TWITTER
prefs:root=General&path=USAGE
prefs:root=VIDEO
prefs:root=General&path=Network/VPN
prefs:root=Wallpaper
prefs:root=WIFI
prefs:root=INTERNET_TETHERING
plist里声明获取隐私数据权限
访问隐私数据需要在plist里声明,在iOS10之前只需要声明地理定位之类的敏感隐私数据,获取照片、相机等不需要再plist里声明。iOS10之后,这些也必须声明,不声明会crash。需要声明的用户数据有:
Contacts(联系人), Calendar(日历), Reminders(提醒事件), Photos(照片), Bluetooth Sharing(蓝牙共享), Microphone(麦克风), Camera(相机), Location(位置), Health(健康), HomeKit(家居), Media Library(媒体库), Motion(运动), CallKit(打电话), Speech Recognition(语言识别), SiriKit(Siri), TV Provider(电视提供商).

后面string字段填写弹出用户允许时展示的描述信息。注意,这里必须要写明获取该权限的用途,不然会被AppStore拒绝上架的。
某些app链接网络失败
iOS10之后出现了实用无线局域网与蜂窝移动网络的允许授权弹窗,有些应用没有出现这个弹窗,莫名其妙的就连不上网络了,去设置的“使用无线局域网与蜂窝移动的应用”里找也找不到,搜索该应用,也没有开启使用网络授权的开关。
其实只需要在“使用无线局域网与蜂窝移动的应用”里面修改任意一个应用的使用网络设置,再打开连不上网的应用,就会出现网络授权弹窗。这是一个系统bug,希望后续的iOS10.x.x系统会修复。

