SceneDelegate와 Appdelegate의 역할 정의와 차이점

임혜정·2024년 7월 15일
0
post-thumbnail
post-custom-banner

SceneDelegate는 IOS 13 (2019.09.19출시) 부터 도입된 개념으로 각각의 윈도우 씬 생명주기 관리, ui씬을 초기화하고 구성하는 기능을 담당한다.

SceneDelegate가 도입되기 전에 개발자들이 겪었던 어려움

  1. AppDelegate의 역할과 책임이 너무 큼
    AppDelegate클래스가 생명주기 이벤트와 ui설정코드를 모두 처리해야했기 때문에 파일이 너무 비대하고 복잡했다. 그로 인해 더 복잡한 기능이나 ui상태를 확장시키는 것이 힘들었다.
  1. multi window 씬 (ipad한정)
    13이전에 하나의 앱 당, 하나의 scene만 가질 수 있었다. (아이폰 환경은 지금도 그렇다 -ios 17.4 기준) 그러나 13 이후에는 한 앱이 여러개의 scene을 가질 수 있게 되었다. 아이패드 한정이지만 하나의 앱을 두 번 열어 각자 다른 파일을 작업하거나 각각의 씬을 갖고 작업을 할 수 있게 되었다.

SceneDelegate가 하는 일

개별 윈도우(scene)의 생명주기 관리, multi window지원

주요 메서드 / scene, sceneDidconnect, sceneDidBecomeActive, sceneWillEnterForeground...등

import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // 씬이 처음 연결될 때 호출, UIWindow를 설정하고 초기 UI 구성
    }

    func sceneDidDisconnect(_ scene: UIScene) {
        // 씬이 시스템에 의해 해제될 때 호출, 씬이 다시 연결될 때 복원할 수 있도록 현재 상태를 저장하는 데 사용
    }

    func sceneDidBecomeActive(_ scene: UIScene) {
        // 씬이 활성화되고 사용자가 상호작용할 수 있게 되었을 때 호출, 애니메이션을 시작하거나 일시 중지된 작업을 재개하는 데 사용
    }

    func sceneWillResignActive(_ scene: UIScene) {
        // 씬이 비활성화되기 직전에 호출, 애니메이션을 일시 중지하거나 상태를 저장하는 데 사용
    }

    func sceneWillEnterForeground(_ scene: UIScene) {
        // 씬이 백그라운드에서 포그라운드로 전환되기 직전에 호출, UI 업데이트나 데이터를 새로 고치는 작업을 수행
    }

    func sceneDidEnterBackground(_ scene: UIScene) {
        // 씬이 백그라운드로 전환된 후 호출, 데이터를 저장하거나 리소스를 해제하는 작업을 수행할 수 있습니다.
    }
}


AppDelegate가 하는 일

앱의 전체적인 생명주기 이벤트 관리, 앱이 foreground, background로 전환될 때 상태처리

주요 메서드 : application, applicationWillResignActive, applicationDidEnterBackground...등

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // 애플리케이션이 처음 시작될 때 호출, 초기 설정, UI 초기화, 기본 데이터 로드 등을 수행
        return true
    }

    func applicationWillResignActive(_ application: UIApplication) {
        // 애플리케이션이 활성 상태에서 벗어나려고 할 때 호출, 일시 중지할 작업이나 실행 중인 작업을 저장합니다.
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        // 애플리케이션이 백그라운드 상태로 전환될 때 호출, 데이터 저장, 공유 자원 해제, 백그라운드 작업 시작 등을 수행합니다.
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
        // 애플리케이션이 백그라운드에서 포그라운드로 전환되기 직전에 호출, 백그라운드에서 해제된 자원을 다시 로드하거나 UI를 업데이트합니다.
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        // 애플리케이션이 활성 상태로 전환될 때 호출, 일시 중지된 작업을 재개하거나 앱 상태를 갱신합니다.
    }

    func applicationWillTerminate(_ application: UIApplication) {
        // 애플리케이션이 종료될 때 호출, 데이터 저장, 리소스 정리 등을 수행합니다.
    }
}



아이폰용 앱이라면 멀티윈도우를 지원할 수 없는데 SceneDelegate파일이 없어도 되는 것 아닌가?

결론부터 말하자면 IOS 13 이하 타게팅이 아니라면 아이폰용 앱이라도 필요하다

  1. iOS 13의 아키텍처 변경 - iOS 13 릴리즈 이후에 애플은 애플리케이션의 생명주기 관리 방식을 변경했다. AppDelegate는 여전히 전체적인 애플리케이션 생명주기를 관리하지만, 각 개별 윈도우 또는 씬의 생명주기는 SceneDelegate를 통해 관리한다.

  2. 미래에 확장을 대비 - 현재 아이폰 환경에서는 안되지만 미~~래에 다중 윈도우 기능이 추가될 경우를 대비할 수 있다

  3. 애플 권장 사항임 - 그렇다네요.


누군가가 SceneDelegate파일을 지워버린 뒤 AppDelegate파일에 초기 화면설정 코드를 작성한다면 , 이 사람의 의도는 무엇일까?



SceneDelegate파일에 자주 사용되는 코드는 패턴화 된 편이다.

쉽게 이해하고 외울 수 있는 방법은 반복 타이핑해가며 코드내용에 익숙해지고 의미를 이해하는 것이 좋다.

// SceneDelegate.swift

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
    var window: UIWindow? //객체 선언
    
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // scene을 UIWindowScene으로 캐스팅하고 유효한지 확인
        guard let windowScene = (scene as? UIWindowScene) else { return }
        
        // UIWindow 인스턴스를 생성하고 windowScene을 지정
        let window = UIWindow(windowScene: windowScene)
        
        // rootViewController를 UINavigationController로 설정하고 그 루트에 ViewController를 배치
        window.rootViewController = UINavigationController(rootViewController: ViewController())
        
        // 창을 표시
        window.makeKeyAndVisible()
        
        // SceneDelegate의 window 속성에 할당
        self.window = window
    }
    
    // 다른 생명주기 메서드들은 필요에 따라 구현
}
  1. Scene 캐스팅 scene을 UIWindowScene으로 캐스팅, 유효성 검사

  2. UIWindow 생성 windowScene으로 UIWindow 인스턴스 생성

  3. Root View Controller 설정 주로 메인 ViewController를 루트로 설정하지만 런치스크린이 있는 앱의 경우 런치스크린 vc로 설정한다

  4. 창 표시 window.makeKeyAndVisible()

  5. window 속성에 할당 self.window에 생성한 window를 할당한다

profile
오늘 배운걸 까먹었을 미래의 나에게..⭐️
post-custom-banner

0개의 댓글