Xcode11 の Single View App をiOS12以前に対応させる

Xcode11で Single View AppSwift Storyboard の設定で作成して、iOS10系以降をサポートする設定にした。

ビルドすると沢山エラーが出た。
AppDelegate.swiftSceneDelegate.swift で、iOS13からavailableになったクラスが使用されているため。

赤丸が点いた箇所、画像の AppDelegate.swift ではfuncの宣言箇所で @available(iOS 13.0, *) を書く(赤丸をクリックすると自動で挿入してくれる)。

SceneDelegate.swiftclass SceneDelegate 自体がiOS13以降のサポートとなるのでこうなる。

これでビルドに成功するようになる。


iOS12系の実機で実行するとコンソールに以下のメッセージが表示され、実機の画面は真っ暗になる。

2019-10-02 02:28:28.466280+0900 Demo[495:13067] [Application] The app delegate must implement the window property if it wants to use a main storyboard file.

これは class AppDelegate のインスタンス変数 var window: UIWindow? がいないため。
下記のように1行追記することでコンソールのメッセージは表示されなくなり、画面は従来通り正常に表示されるようになる。

// AppDelegate.swift
import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow? // これを追記する

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        return true
    }

iOS12(iOS13より前のOS)に対応させるためこの実装を行った。
これでわかったことは、iOS13では従来のように UIApplicationDelegate から windowの取得が行えずnilが返ってくる。

// 従来のWindow取得(Swift)
let window = (UIApplication.shared.delegate as! AppDelegate).window

今後はWindow単体という考えがあり得ないと言うことなんだと思うので(よく調べてないので適当)
とりあえずこのようにしてwindowを取得するのが良いのかなと調べ中。実際は ! とか使わないと思うけど。

// 従来のWindow取得(Swift)
let window =  (UIApplication.shared.connectedScenes.first as! UIWindowScene).windows.first!

従来からある下記の方法でもウィンドウの取得は出来るけど、用途によってはScene関連の問題が出そうなので使わない方が良いのかなという気がしている。

UIApplication.shared.windows

今後はWindow単体という考えがあり得ないと言うことなんだと思うので

これについては class UIApplication のInterfaceファイルを開くとこのように書かれていたための理解です。

@available(iOS, introduced: 2.0, deprecated: 13.0, message: "Should not be used for applications that support multiple scenes as it returns a key window across all connected scenes")
open var keyWindow: UIWindow? { get }

すごい人たちが早く情報まとめてくれることを祈ります。