iOS最低支援版本低於iOS 13並同時使用AppDelegate以及SceneDelegate
當我們使用Xcode 11
之後的版本新建專案,Xcode
會預設產生AppDelegate.swift
以及SceneDelegate.swift
,此時如果在建立完專案後,需要將最低支援版本改成低於iOS 13
,則會看到許多錯誤:
會出現這些錯誤的原因是,在Xcode 11
之後,預設新增的專案最低支援版本為iOS 13
,並且新增了一個SceneDelegate.swift
檔案,那實際上有什麼改變? 我們先來了解在Xcode 11
及更早版本之前,AppDelegate.swift
在做什麼事
AppDelegate
是App啟動時最一開始載入的檔案,裡面管理著App的生命週期
,例如App進入到前景,或者App被滑到背景,都會觸發這些function,而以下這個function則是在App即將啟動時,最一開始被呼叫的。
當App啟動完成後,會呼叫以下function,在iOS 12
或更低版本時,我們可以在這個function建立我們的初始控制器,或者在這個function建立一些初始化設定,例如以下程式碼:
而到了Xcode 11, iOS 13
之後,新增專案時AppDelegate
內的管理App生命週期的function有所改變了,並且新增SceneDelegate.swift
檔案,變成由SceneDelegate
來管理
以下程式碼是AppDelegate.swift
內將管理App生命週期事件交給SceneDelegate
管理的程式碼:
那如果想要在Xcode 11建立新專案之後,最低支援版本又低於iOS 13,怎麼辦呢?
我看網路上有許多教學是直接刪除SceneDelegate
,全部交由AppDelegate
來管理,但是考慮到之後有可能會有多場景的需求,因此我不打算刪除SceneDelegate
,而且刪除SceneDelegate
之後,又需要去改動到Info.plist
內的屬性
這邊採用的做法是判斷目前聲明哪些函示及類別是iOS 13
或更高版本可用,因此需要用到#available
以及@available
關於兩者的差別,下次我們再寫個文章來說明,因此最終程式碼會變成以下樣子:
AppDelegate:
在AppDelegate.swift
內可以看到,我在application(_ :willFinishLaunchingWithOptions:)
實例化一個window
並設定了初始視圖控制器,並且在application(_:didFinishLaunchingWithOptions:)
設定讓window
顯示
並且在AppDelegate.swift
內加入了App生命週期,低於iOS 13
的版本就會進入這些生命週期
值得一提的是,在Xcode 11產生的AppDelegate.swift
內,預設是沒有window
的屬性的,所以需要自己宣告一個window
接下來是SceneDelegate.swift
,由於這個類別只有iOS 13
才能使用,所以我們可以大膽的直接將整個class上方宣告@available(iOS 13.0, *)
:
SceneDelegate.swift
SceneDelegate.swift
的寫法跟AppDelegate.swift
其實差異不大,差別只是設定初始ViewController的地方寫在scene(_ :willConnectTo:options:)
總結:
當iOS
版本低於iOS 13
時,程式碼的部分只會走AppDelegate.swift
,並且App生命週期由AppDelegate管理
當iOS
版本等於或高於iOS 13
時,程式碼的部分會一開始先走AppDelegate.swift
,當啟動完成後,進到AppDelegate.swift
內配置SceneDelegate
的function,並且App生命週期由SceneDelegate.swift管理
終於寫完了~這篇的目的主要是要解決新建的專案要支援較低(低於iOS 13)版本時,
AppDelegate.swift與SceneDelegate.swift共存的問題
,如果有更好的方式或者我有哪裡寫錯了也歡迎留言一起討論,感謝閱讀~