Help us understand the problem. What is going on with this article?

SceneDelegateのせいでiOS12以下のビルドが通らない

はじめに

SwiftUIが登場して話題になっているXCode11
そんな中に埋もれていたSceneDelegateが地味に厄介だったので対処法を書き置きします。

SceneDelegateって?

正直何者なのかは分かっていませんが、アプリを複数表示させるためにSceneという概念が導入されてそれがゴニョゴニョしてるみたいなことなのでしょうか

詳しいことは参考にさせていただいた記事に書いてありますので、そちらか別の記事を見てください
参考はこちら

対処法

プロジェクトを新規で作成し、targetのOSをiOS12以下にすると、大量にエラーが出るかと思います。
大体は、↓のようなavailableの設定をしろ的なのがSceneDelegate.swiftとAppDelegate.swiftに表示されました。

'ConnectionOptions' is only available in iOS 13.0 or newer
'UIScene' is only available in iOS 13.0 or newer

というわけで、SceneDelegateにはクラスごと、AppDelegateにはUISceneSession LifecycleのMARKコメントが付けられている箇所から下のメソッドにavailableを付与します。

AppDelegate.swift
// MARK: UISceneSession Lifecycle

@available(iOS 13.0, *)
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
    // Called when a new scene session is being created.
    // Use this method to select a configuration to create the new scene with.
    return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}

@available(iOS 13.0, *)
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
    // Called when the user discards a scene session.
    // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
    // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}

SceneDelegate.swift
@available(iOS 13.0, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
        // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
        // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
        guard let _ = (scene as? UIWindowScene) else { return }
    }

    ~ 以下略 ~

さあこれでエラーもなくなったし大丈夫!
iOS12の実機で確認だ!っと意気込んで実行すると、なんと画面が真っ暗のまま動きません

どうしたのでしょうかとコンソールを覗いてみると、こんなメッセージが表示されていました

[Application] The app delegate must implement the window property if it wants to use a main storyboard file.

(翻訳)
[Application]Main.storyboardを使用する場合、AppDelegateはwindowプロパティを実装する必要があります。

なんのこっちゃ!ということで調べてみると、どうやら今まであったwindowプロパティが作られなくなっていたようで、それが原因で表示されないみたいでした。

というわけで、過去のプロジェクトを参考に、下記のように修正

AppDelegate.swift
@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
    }

これでXcode11で作成したプロジェクトもiOS12以下でビルドが通るようになります!

終わりに

SwiftUIも出てXCodeを使う人が増えればな〜と思いますが、こんな序盤でつまずきポイントがあったとは...
この記事をみて解決した方は、今後の励みになりますので、ぜひいいねを押していただけると嬉しいです!

sakuto0116
大分のエンジニア。 WebとiOSが中心。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした