升级到XCode9(BaseSDK:iOS11)的各种坑 持续更新中

XCode9和iOS11 beta了不知多少版本了,正式版本还没有正式发布。我也终于忍不了了,还是都做了升级。设备版本分别为:
XCode:Version 9.0 beta 6 (9M214v) 10月13日更新GM版
iPhone:11.0(15A5370a)

下面的问题都是在iOS11之前的版本运行完好,但是升级后出现的问题:
1,定位相关
问题描述:无法定位,而且程序在安装后第一次访问定位权限时,无定位权限提示对话框弹出。
原因:iOS11 定位相关的权限做了更改,在iOS11上使用了新的定位权限key。
解决方案:
如果原来申请的权限是始终允许NSLocationAlwaysUsageDescription,那么需要在保留原来的key的基础上增加NSLocationWhenInUseUsageDescription和NSLocationAlwaysAndWhenInUsageDescription。具体参考另篇博客:
http://blog.csdn.net/dangyalingengjia/article/details/77965029

2,系统相册相关
问题描述:iOS11上读写相册的照片时发生崩溃。
原因:由于相册相关权限的key发生了变化。用户在没有权限的情况下,访问相册导致崩溃。
解决方案:
iOS11之前相册对应的key是NSPhotoLibraryUsageDescription,iOS11对应的Key是NSPhotoLibraryAddUsageDescription。同定位的Key一样,由于key没有兼容性,所以需要保留原key以兼容iOS10及之前版本。

3,关于UIScrollView初始位置变化的问题
由于iOS11废弃了UIViewController的automaticallyAdjustsScrollViewInsets属性,位置需要手动调整。
iOS11中为UIScrollView新增了contentInsetAdjustmentBehavior属性,结合UIAppearance协议,可以统一在appDelegate的didFinishLaunchingWithOptions的最开始增加:

if #available(iOS 11.0, *) {
    UIScrollView.appearance().contentInsetAdjustmentBehavior = .never
}
调整前 调整后
这里写图片描述 这里写图片描述

2017/10/21更新
注意1,如果你需要做一个嵌套WebView的画面,直接将WebView加到self.view中时,那就需要对WebView的ScrollView进行单独处理:

UIScrollView.appearance().contentInsetAdjustmentBehavior = .automatic

注意2,对于系统的相册选择视图UIImagePickerController,需要单独处理:

再打开系统相册前设定:
UIScrollView.appearance().contentInsetAdjustmentBehavior = .automatic
从相册返回后设定:
UIScrollView.appearance().contentInsetAdjustmentBehavior = .never

4,第三方库WKWebViewJavascriptBridge
问题描述:在WKWebView的回调函数中崩溃:
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void)
原因:WKWebViewJavascriptBridge内部逻辑问题
解决方案:WKWebViewJavascriptBridge最新的6.0.2上仍然没有解决这个问题,可以参考github issue#272
只能手动修改源文件,将WKWebViewJavascriptBridge.m 的L153的if改为 else if
修改后:                        修改前:
WKWebView

5,第三方库CryptoSwift
如果你使用了加解密相关的第三方库CryptoSwift,而且其版本号在0.7.0以下,可能会遇到找不到UInt8等错误。
你需要更新至0.7.0才能支持XCode9中的Swif3.2。可以查看Github上的CryptoSwift的版本介绍:
CryptoSwift版本
将podfile修改为如下,即可编译通过。
pod ‘CryptoSwift’, ‘~> 0.7.0’

6,第三方库GzipSwift
如果你使用了GZip压缩库GZipSwift的话,可能会遇到这样的错误:
Redefinition of module ‘zlib’
Could not build Objective-C module ‘Gzip’
修改podfile为:
pod ‘GzipSwift’, :git => ‘https://github.com/1024jp/GzipSwift.git‘, :branch => ‘swift4’

7,UIVisualEffectView相关的崩溃
iOS11之前可以将UIView直接加到(addSubview)UIVisualEffectView上面,但是在iOS11上面这么做会导致crash。
正确的姿势是:将UIViewaddSubview到UIVisualEffectView的contentView上。

8,关于上传商店相关改变
之前没有1024*1024的icon,同样可以提交商店审核,但是现在不行了。你会在用Application Loader上传完成后收到一个warning,但是在提交审核(包括beta测试版本)时被告知不允许提交。
上传被拒
而且注意,这个1024的图片一定要去掉alpha通道。可以在github上搜索Alpha-Channel-Remover,用这个工具去掉alpha通道。

9,xcodebuild命令的变化
xocdebuild error
之前用的打包命令是:

./xcodebuild_safe.sh -exportArchive -archivePath "${archive_path}" -exportPath "${export_dir}" -exportOptionsPlist "${plist_file}" || Failed "export fail"
cd "${origin_dir}"

在plist中加入就可以了

    <key>provisioningProfiles</key>
    <dict>
        <key>xxx:YourBundleID</key>
        <string>xxx:YourProvisioningProfileName</string>
    </dict>

在XCode9中,xcodebuild命令的-exportOptionsPlist需要增加provisioningProfiles,用来明确指明用到的provisioningprofile。-exportOptionsPlist这个参数只用在手动管理签名的情况下,尝试使用苹果推荐的xcode自动xcode的自动管理。但是发现带有通配符的AppleID还需要为其指定各种权限,遂作罢。还是手动管理签名吧。

10,iPhoneX的适配
问题1:直接模拟器运行是下图这样的,可以看到顶部,底部都有空余区域:
iPhoneX适配前
解决方案:增加iPhoneX用的启动图(1125*2436)可以让画面充满屏幕。
问题2:充满屏幕后,由于iPhoneX的状态条已经不是20pt,而是44pt。我们的工程用的autolayout,自定义的导航条,约束的写法是相对于self.view做64的位移。这样就会出现视图内容跟导航条重叠。
解决方案1:取消原来的状态条20,导航条44等硬编码写法,定义常量。

// 状态条的高度
func statusBarHeight() -> CGFloat {
    var height: CGFloat = 0
    if #available(iOS 11.0, *) {
        // iPhoneX
        if abs(UIScreen.main.bounds.size.height - CGFloat(812)) < CGFloat.leastNormalMagnitude {
            height = 44
        } else {
            height = 20
        }
    } else {
        height = 20
    }
    return height
}
// 导航条高度
let kNavigationBarHeight: CGFloat = 44
// 画面中视图的起始位置
let kViewTopOffset = statusBarHeight() + kNavigationBarHeight

视图的top从kViewTopOffset开始。
解决方案2:使用safeAreaLayoutGuide。它是当前视图安全区域的范围,可以将其看做一个视图。我们做约束的时候,相对于safeAreaLayoutGuide就好了。但是需要在做约束时区分系统版本,代码量大。

总而言之,上面两种做法,都需要巨大的搬砖量。我选择了第一种做法,昨天从下午搬砖到凌晨1点,每个画面都改了一个遍。
参考:
https://developer.apple.com/ios/human-interface-guidelines/overview/iphone-x/
https://developer.apple.com/videos/play/fall2017/201/
https://developer.apple.com/videos/play/fall2017/801?time=209
http://www.jianshu.com/p/1432a94ef66f

改完后的效果:

图1 图2
修正后1 修正后2

猜你喜欢

转载自blog.csdn.net/dangyalingengjia/article/details/77964582