目的
一般的な入門書は、XCodeでプロジェクトを作成したら、ContentViewでUIを追加することから記載されています。Swift UIなのでそうなるのは普通なのですが、ContentViewを見るまでどういう動作をしているかが気になったので調べてみました。
この調査内容をまとめるのが本記事の目的になります。
AppDelegate
これは従来どおり、アプリケーションのコールバックをまとめて、アプリケーションの動作をカスタマイズするためのクラスで@UIApplicationMain属性がついており、アプリケーションデリゲートであることを表しています。
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)
}
ここでは、コールバックの一つを実装して、UIScenceConfigurationを設定しています。
Info.plist
情報プロパアティリストのInfo.plistですが、「Application Scene Manifest」が設定されていて、以下のような要素が定義されています。
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
</dict>
</array>
</dict>
</dict>
ScenceDelegateの決定
AppDelegateでは以下のコールバックが実装されています。
- application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions)
生成されたコードにおいて、UISceneConfigurationを生成していますが、引数である**name: "Default Configuration"**がポイントで、Info.plistに同じ名前でUISceneConfigurationNameキー(UIWindowSceneSessionRoleApplication辞書)に記載されています。
この設定のUISceneDelegateClassNameキーに設定されているクラスがScenceのDelegateになるという意味になります。この値はSecenceDelegateとなっており、生成されたクラスを指しています。
SceneDelegate
Sceneのライフサイクルに対するコールバックを実装しているクラスです。
Sceneが作られるタイミング
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions){
let contentView = ContentView()
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
}
Sceneのライフサイクルコールバックとして上記の実装が生成されています。
ここで実際の画面であるContentViewが作られ、引数のsceneに対して設定をします。
UIWindowSceneはUIWindowを使ったシーン実装で現状ほかのもの見つけられませんでした。
UIHostingController(UIViewController化するためのラッパー)によって最初にだすべきViewに設定されています。
ContentView
import SwiftUI
struct ContentView: View {
var body: some View {
Text("Hello, World!")
}
}
View プロトコルを実装しているContentViewは自動生成された構造体です。
body変数にUIを記載することで画面を構成します。この変数に定義する内容がSwiftUIの特徴といえます。
ContentView_Previews
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
この構造体がPreviewを可能とするものになります。previews変数にて、プレビューするViewを設定します。ここでは上記のContentViewを設定しています。
この後
ContentView のbody変数に要素を追加していきます。