昨天聽完拐子在 iOS Taipei 的分享後,今天自己嘗試在 Xcode 11 開一個 iOS 12 和 13 都能跑的專案,發現還是有些坑,所以簡單記一下筆記,方便日後使用。
IDE: Xcode 11.1
Github 專案:
master branch:user interface 的設定是 SwiftUI
storyboard branch:user interface 的設定是 Storyboard
我們都知道,SwiftUI 只能在 iOS 13 的系統以上跑,但 Xcode 11 開的新專案是預設用 SwiftUI 的設定。 如果我們在 iOS 12 安裝 Xcode 11 開的專案,會收到一堆 error:
以下是怎麼在 Xcode 11 開一個 iOS 12 和 13 都能跑的專案的步驟~
如果一開始 user interface 的設定是 SwiftUI…
Step 1: 刪掉所有與 Swift UI 相關的 file 和程式碼
刪除與 SwiftUI 相關的 file ,包括 ContentView.swift 和 SceneDelegate.swift,以及 AppDelegate 中的程式碼:
Step 2: 用慣常的做法在 AppDelegate 中 init window
在 AppDelegate 中 init window:
如果我們現在把專案 build 起來,我們會發現 Info.plist 出現 error:
Step 3: 改 Info.plist 的設定
把 <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string
改為<string>$(PRODUCT_MODULE_NAME).AppDelegate</string
.
如果我們現在把專案 build 起來,APP 會 cash, LLDB 出現以下 error 訊息:
[SceneConfiguration] Info.plist configuration “(no name)” for UIWindowSceneSessionRoleApplication contained UISceneDelegateClassName, “ProjectSupportingIOS12n13.AppDelegate”, but it does not conform to the UISceneDelegate protocol.
AppDelegate 出事了。
Step 4: 讓 AppDelegate conform UISceneDelegate protocol
直接把 UISceneDelegate 加上去後,IDE 沒有出現任何要實作 UISceneDelegate function 的提示:
如果我們現在把專案在 iOS 12.2 上跑是沒有問題的,但如果在 iOS 13.1 上跑,我們將得到一個全黑的畫面而 debug console 沒有任何錯誤:
Step 5: 用 UIWindowScene init window
雖然我們沒有看到任何錯誤,但若打開 debug view hierarchy, 我們會發現該 window 不是我們熟悉的 UIWindow,而是 UIWindowScene(瞎毀?!
所以把原本 SceneDelegate 中 init window 的 function 加到 AppDelegate,並在此 init window:
但這次樣寫 window 還是一個與 UIWindowScene 無關的 window,所以我們需要用 UIWindowScene 去 init window:
這樣這個專案在iOS 12和13上均可正常運行。
如果一開始 user interface 的設定是 Storyboard…
要做的事幾乎與上面相同,只是這邊我們只能 conform UIWindowSceneDelegate 而不能用 UISceneDelegate,並且不需要執行步驟5。
AppDelegate 只能 conform UIWindowSceneDelegate
創建的專案的時候如果使用 SwiftUI 的話,AppDelegate conform UISceneDelegate 或 UIWindowSceneDelegate 都可以。
但是,如果我們創建的專案的時候使用Storyboard,AppDelegate 只能 conform UIWindowSceneDelegate, 否則,該 window 將無法正確初始化,我們會收到以下錯誤消息:
[WindowScene] There is no scene delegate set. A scene delegate class must be specified to use a main storyboard file.
Storyboard 的默認配置與 SwiftUI 略有不同:
不需要執行步驟5
更改 Info.plist 的配置就可以,不用加額外的設定:
以上。
如果沒有要用 SwiftUI 的話,我還是會選擇用 Xcode 10.3 去開專案。(累)