Xcode11 + iOS13 APP 使用 statusBar 會 crash 的解法

iOS13 釋出了,然後很快的釋出 13.1,疑似昨天(2019/9/27)還是今天(2019/9/28)又釋出 13.1.1,所以這版本接下來會有更多修正,是可以預見的。
我們已經開發過的 APP、正在開發的 APP,剛好在這週碰上了一些狀況,而這些狀況卻都無法透過 google 找到答案,所以就在這裡分享一下。

iOS13 釋出了,然後很快的釋出 13.1,疑似昨天(2019/9/27)還是今天(2019/9/28)又釋出 13.1.1,所以這版本接下來會有更多修正,是可以預見的。

我們已經開發過的 APP、正在開發的 APP,剛好在這週碰上了一些狀況,而這些狀況卻都無法透過 google 找到答案,所以就在這裡分享一下。

主要的問題是,在 Xcode 11 的開發環境下,使用 iOS13 的模擬器,會遇到底下的錯誤訊息:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'App called -statusBar or -statusBarWindow on UIApplication: this code must be changed as there's no longer a status bar or status bar window. Use the statusBarManager object on the window scene instead.'

但是上週用 Xcode 10 來 build APP,同樣的在 iOS13 底下執行,卻沒有這樣的錯誤,所以蠻有趣的。

後來找到罪魁禍首,將 APP 裡面的這些程式碼做改寫之後,Xcode 11 build 出來在 iOS13 上面跑,就不會錯了。

本來的寫法(Swift):

height = UIApplication.shared.statusBarFrame.height

修改後的寫法(Swift):

height = view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0

但修改後的寫法只適用於 iOS13,所以完整的寫法應該是:

if #available(iOS 13.0, *) {
height = view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0
}
else {
height = UIApplication.shared.statusBarFrame.height
}

另外一個部分舊的寫法是:

let statusBarView = UIApplication.shared.value(forKeyPath: "statusBarWindow.statusBar") as? UIView

修改後的寫法:

let statusBarView = UIView(frame: UIApplication.shared.statusBarFrame)

完整的寫法:

if #available(iOS 13.0, *) {
    let statusBarView = UIView(frame: UIApplication.shared.statusBarFrame)
    statusBarView.backgroundColor = UIColor(red: 175.0/255.0, green: 56.0/255.0, blue: 61.0/255.0, alpha: 1.0)
}
else {
    guard let statusBarView = UIApplication.shared.value(forKeyPath: "statusBarWindow.statusBar") as? UIView else {
        return
    }
    statusBarView.backgroundColor = UIColor(red: 175.0/255.0, green: 56.0/255.0, blue: 61.0/255.0, alpha: 1.0)
}

這樣改完,在 Xcode11 上面 build 出來的結果,再拿到 iOS13 去跑,就不會 crash 了。

markkwsu

markkwsu

2 comments