본문 바로가기
Dev/iOS

[SwiftUI] 신규 SwiftUI 프로젝트에서 AppDelegate, SceneDelegate 사용하기

by steady.dev 2021. 10. 29.

아래 내용은 XCode 13.1 을 기준으로 작성했다.

 

1. 프로젝트 생성

XCode 13.1 에서 프로젝트를 생성 시 Interface를 SwiftUI 로 생성하면, 기본 iOS SDK Target을 15.0으로 한다.

프로젝트 생성
iOS SDK Version

그리고 프로젝트의 시작은 기존 AppDelegate 및 SceneDelegate가 아닌 App 프로토콜을 상속한 프로젝트명+App 구조체를 시작점으로 한다.

(참고로 App  프로토콜은 iOS 14 이상에서 사용 가능하다.)

import SwiftUI

@main
struct TestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

 

2. AppDelegate 및 SceneDelegate 파일 생성

AppDelegate와 SceneDelegate 파일은 Storyboard를 통해 생성 시 기본으로 제공하는 코드들을 사용해준다.

아래 코드는 AppDelegate를 main으로 하였을 때의 코드이다.

SceneDelegate.swift 파일내에 자신의 SwiftUI의 View 구조체 이름을 사용하면 된다.

 

AppDelegate.swift

더보기
import UIKit

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

    // MARK: UISceneSession Lifecycle
    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.
    }
}

SceneDelegate.swift

더보기
import UIKit
import SwiftUI

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).

        // Create the SwiftUI view that provides the window contents.
        let contentView = TestApp()

        // Use a UIHostingController as window root view controller.
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: contentView)
            self.window = window
            window.makeKeyAndVisible()
        }
    }

    func sceneDidDisconnect(_ scene: UIScene) {
        // Called as the scene is being released by the system.
        // This occurs shortly after the scene enters the background, or when its session is discarded.
        // Release any resources associated with this scene that can be re-created the next time the scene connects.
        // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
    }

    func sceneDidBecomeActive(_ scene: UIScene) {
        // Called when the scene has moved from an inactive state to an active state.
        // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
    }

    func sceneWillResignActive(_ scene: UIScene) {
        // Called when the scene will move from an active state to an inactive state.
        // This may occur due to temporary interruptions (ex. an incoming phone call).
    }

    func sceneWillEnterForeground(_ scene: UIScene) {
        // Called as the scene transitions from the background to the foreground.
        // Use this method to undo the changes made on entering the background.
    }

    func sceneDidEnterBackground(_ scene: UIScene) {
        // Called as the scene transitions from the foreground to the background.
        // Use this method to save data, release shared resources, and store enough scene-specific state information
        // to restore the scene back to its current state.
    }


}

 

3. Info.plist 파일 수정

SceneDelegate를 사용하기 위해서는 Info.plist 에 아래 내용을 추가해준다.

Info.plist

코드로 추가하기 위한 코드

더보기
<key>UIApplicationSceneManifest</key>
    <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>

 

Info.plist 파일이 없을 때

XCode 13에서는 프로젝트 생성 시 SwiftUI로 생성하게 되면 Info.plist 파일이 없다. 프로젝트 설정에서 타겟 프로젝트에서는 Info 가 있어 이를 통해서 수정 및 추가가 가능한데, 여기에서 사용한 값을 아무거나 한개 추가하게 되면 자동으로 프로젝트에 Info.plist 파일이 생성된다.

(출처: https://useyourloaf.com/blog/xcode-13-missing-info.plist/)

 

댓글