はじめに
Xcode11 で新規にプロジェクトを作成し、iOS13 未満もサポートしようとすると大量のエラーが出てしまいます
この辺りめんどくさくて最近作ったやつ(下記とか)は大抵 iOS13 以上サポートにしてましたが iOS13 未満もサポートするため調べてみました。
対応
SwiftUI を使わない
とりあえず新規作成時に User Interface で SwiftUI ではなく Storyboard を選択する。
頑張ってバージョンで分岐させてもいいがおとなしく今のところは SwiftUI をあきらめる
SceneDelegate 対応
出てるエラーを見てもらうとわかる通り SceneDelegate に関連するものばかりです。
SceneDelegate とはなんぞや?というのは下記参考
対応としては下記2パターンです。
- SceneDelegate を削除する
- エラーに1つずつ対応する
SceneDelegate を削除する
SceneDelegate はどうやら必須ではないらしいので削除しても大丈夫です。
※機能が制限されるのでそことの兼ね合い
- Info.plist の
Application Scene Manifest
キーを削除する
Application Scene Manifest
キーがある場合に必須となるのでこれを削除する。
さあビルドっとやるとまだエラーが出る
ごっそり削除
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
}
ビルド!!!
画面が真っ黒でこんなエラーが
[Application] The app delegate must implement the window property if it wants to use a main storyboard file.
とりあえず window を追加!!
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 でも動いた
エラーに1つずつ対応する
エラーをみていくと全部 @available(iOS 13.0, *)
をつけろ!っていうやつです。
下記のように @available(iOS 13.0, *)
をつけて削除の時と同様に window を追加します。
@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 }
}
:
:
:
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
}
// 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.
}
}
2019/12/21追記。コメントでもっとクールな書き方を教えていただきました
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
}
}
// MARK: UISceneSession Lifecycle
@available(iOS 13.0, *) // ここ追加
extension AppDelegate {
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)
}
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.
}
}
ビルド!!!!!
iOS12 でも動いた
SceneDelegate があると AppDelegate と両方に処理を書かないといけなくなるので 許してくれるなら(お客さんが)削除でいいんじゃないかなと思います
2019/12/21追記。
こちらもコメントいただきました。iOS14 などで今後 AppDelegate の処理が SceneDelegate に移行する可能性もあるのでしっかりバージョンを切り分けて対応した方が無難とのこと(iPhone なら Scene とか関係ないし削除しても...でも結局今後どう変わるかわからないし...)
なのでできるならちゃんと対応しましょう!!!
なんどもこの作業をやるのがめんどくさい場合はテンプレート機能とかあるらしいです(...知らなかった)
さいごに
なんとかまにあった...
(半角スペース2個で改行できるの知らなかった)