[ios] AppDelegate & SceneDelegate

Oxong·2022년 5월 26일
0

iOS 개발 관련 모음

목록 보기
8/8

공부한 것을 정리하는 용도의 글이므로 100% 정확하지 않을 수 있습니다.
참고용으로만 봐주시고, 내용이 부족하다고 느끼신다면 다른 글도 보시는 것이 좋습니다.
+ 틀린 부분, 수정해야 할 부분은 언제든지 피드백 주세요. 😊

해당 글은 Swift 공식 문서를 기반으로 여러 블로그의 글을 읽고 작성되었습니다.
블로그들의 출처는 맨 아래에 있습니다.

                                                 by. Oxong




SceneDelegate와 AppDelegate의 차이를 처음 ios를 공부했을 때 분명 한 번 읽어봤던 것 같은데
개발을 하면서 SceneDelegate를 굳이 사용하지 않으니 기억 속에서 약간 잊혀졌던 것 같다.

이번에 SceneDelegate에 대해 한 번 정리해야겠다고 생각하게 된 이유는 아래와 같다.

push 메세지를 클릭했을 때, 데이터의 type에 따라 분기를 다르게 태우기 위해
다른 화면으로 전환하는 코드를 찾아 테스트 해보는데 화면 전환이 되지 않는 것...

찾아보니 ios13부터 SceneDelegate가 추가되며 생긴 변화 + 현재 구글링(스오플, 블로그 등)으로 나온
모든 화면 전환 자료들이 iOS 13 이전의 내용을 다루고 있어서 인 것 같았다. ㅎ....

역시 사람은 스스로 직접 경험해봐야,, 필요함을 아는 것 같다,,,^-^,,,,







iOS 13 이전

AppDelegate (⇒ App-Based LifeCycle)


iOS 13 이전에는 AppDelegate가 앱의 생명주기(Life-Cycle → launch, foregrounding, backgrounding 등)를 관리하였다.

출처 : wwdc2019 - Architecting Your App for Multiple Windows

하나의 앱에 하나의 window가 존재하므로 앱은 1개의 Process와 1개의 UI를 유지하고, 모든 관리는 AppDelegate가 했다.

  • Process Lifecycle : Process 상태 (앱의 launch, terminated 직전 등)
  • UI Lifecycle : active, inactive, background, foreground

그러나 iOS 13부터 AppDelegate는 일부 역할을 SceneDelegate에게 넘겼다.

왜?? Multiple Window를 지원하기 위해서!




iOS 13 ~

AppDelegate & SceneDelegate (⇒ Scene-Based LifeCycle)


iOS 13부터는 window의 개념을 scene으로 대체되었다고 한다.

기존 앱은 window 하나 뿐이었으나 scene으로 대체되면서 여러 UI 인스턴스가 존재하는 것이 가능해졌다.
1 process & multiple user interface(= scene sessions) 를 지원하게 되었다.

출처 : wwdc2019 - Architecting Your App for Multiple Windows

AppDelegate가 필요없어졌다는 말은 아니다.

AppDelegate는 일부의 역할을 SceneDelegate에게 넘겨준 것이고, 대신 새로운 역할을 하나 가지게 된 것!


그렇게 ios12까지 관리하던 UI LifeCycle 관리를 ios13부터는 SceneDelegate가 책임지게 되었다.

대신 AppDelegate는 Session을 관리하는 역할을 맡게 되므로써, 새로운 Scene Session이 생성(created)되거나 삭제(discarded)될 때 AppDelegate에게 알리는 메소드가 추가되었다.




AppDelegate


그렇다면 iOS 13 부터 AppDelegate는 어떤 역할을 하는 걸까?

  1. 앱의 가장 중요한 데이터 구조를 초기화
  2. 앱의 scene을 환경설정(Configuration)
  3. 앱 밖에서 발생한 알림(배터리 부족, 다운로드 완료 등)에 대응
  4. 특정한 scenes, views, view controllers에 한정되지 않고 앱 자체를 타겟하는 이벤트에 대응
  5. 애플 푸쉬 알림 서브스와 같이 실행시 요구되는 모든 서비스를 등록



SceneDelegate


바로 위에서 말한 것과 같이 SceneDelegate는 UI의 상태변화를 메소드들을 통해 application에게 알리는 역할을 한다.
ios 12까지 AppDelegate가 가졌던 UI 상태 변화 메소드들과 거의 1:1 mapping이 가능하다.

출처 : wwdc2019 - Architecting Your App for Multiple Windows


아래의 그림은 김종권의 iOS앱 개발 알아가기 블로그에서 본 call stack인데 이해하기 쉬운 것 같아 가져왔다.


특히 didDisconnect코드는 앱을 종료하기 직전에 등장하는 메소드로 Scene과 관련된 불필요한 자원을 초기화해줘도 된다.
그러나 앱이 종료되지 않고, 재연결될 경우를 대비하여야 하기 때문에 위 코드에서 모든 자원을 초기화하는 것은 위험하다.


위에서 언급헀던 것처럼 Scene Sesson(Scene LifeCycle)은 AppDelegate가 관리하기 때문에 App이 종료될 때 최종적으로 삭제하고 싶은(삭제해도 무방한) 일반 데이터 또는 Scene과 관련된 데이터가 있다면 AppDelegated의 didDiscardSceneSessions 코드 내에서 삭제되도록 작성해야 한다.




SceneDelgate Method


SceneDelegate의 메소드에 대해 LifeCycle에 맞춰 조금 더 알아보자.


scene(_: willConnectTo: options: )

iOS 12 AppDelegate의 didFinishLaunchingWithOptions와 같은 기능을 하는 메소드이다.
UISceneSession lifecycle에서 제일 처음 불리는 메소드로 Scene이 앱에 새로 추가될 때 사용된다.

첫 content view, 새로운 UIWindow를 생성하고 window의 rootViewController를 설정한다.
이 때, 여기서 말하는 'window'는 사용자가 보는 window가 아니라 app이 작동하는 viewport를 말한다.

이 곳에서는 스토리보드가 있든 없든, 코드로서 어떤 화면을 보여줄 지 setup할 수 있다.



sceneWillEnterForeground(_ :)

background → foreground로 전환될 때 사용되어지는 메소드로 willConnectTo 메소드 다음에 바로 사용되어진다.



sceneDidBecomeActive(_ :)

그 다음으로 사용되어지는 메소드로 scene이 setup되고, 화면에 보여지면서 사용 준비가 완료된 상태이다.
앱이 Switcher에서 선택되면 inactive → active로 전환된다.
또한, inactive상태가 되면서 멈춘 task를 재실행할 때도 이 메소드를 사용할 수 있다.



sceneWillResignActive

앱이 잠시 interruption 상태에 빠질 때 사용되어지는 메소드로 active → inactive 상태로 전환될 때 사용된다.



sceneDidEnterBackground(_ :)

scene이 foreground → background로 전환 될 때 사용된다.

다시 foreground에 돌아 올 때 복원할 수 있도록 state 정보, 데이터 등을 저장, 공유 자원 돌려주는 등의 일을 처리할 때 이 메소드를 사용한다.



sceneDidDisconnect(_ :)

Scene의 연결이 해제될 때 호출되는 메소드이다.

call stack에서 언급한 것 처럼 sceneDidDisConnect는 앱이 종료되는 것이 아니다.


system은 한정된 자원을 가지고 있기 때문에 자원을 언젠가는 회수한다.
따라서 scene이 background에 들어간 후 어느 시점에 scene을 memory로부터 해제시킨다.

즉, scene이 background로 들어갔을 때 시스템이 자원을 확보하기 위해 disconnect하려고 할 수도 있기 때문에
이 메소드 내에서 해야 할 가장 중요한 작업은 필요 없는 자원은 돌려주어야 한다.

가령 디스크로나 네트워크를 통해 쉽게 불러올 수 있거나 생성이 쉬운 데이터들은 돌려주고, 사용자의 input과 같이 재생성이 어려운 데이터는 갖고 있게끔 하는 작업을 해주어야 한다.




아래 그림은 Scene-Based LifeCycle을 그림으로 이해하기 쉽게 구현한 것이다.

출처: Apple Docs - Managing Your App's Life Cycle


앱이 scene을 지원하면서 uikit는 모든 라이프 사이클 이벤트를 UIapplicationDelegate로 전달하는 것이 아니라 각각에 대해 별도 라이프 사이클을 제공하도록 한다고 한다.

즉 사용자가 앱의 UI를 해제하면 UIKit은 연결된 장면을 background 상태로, 결국에는 suspended 상태로 전환한다.

UIKit은 언제든지 background 또는 suspended된 Scene의 연결을 끊어 Scene을 연결되지 않은 상태로 되돌릴 수 있다.



AppDelegate에 configurationForConnecting와 didDiscardSceneSessions 메소드를 필수로 구현해야한다.

configurationForConnecting connectingSceneSession:UISceneSession

configurationForConnectiong 메소드는 앱이 실행된 직후, 사용자의 화면에 보여지기 전에 호출된다.
새로운 Scene을 만들때 UIKit를 위한 configuration data를 가져온다.



didDiscardSceneSessions sceneSessions: Set<UISceneSession>

사용자가 app switcher에서 하나 이상의 앱 Scene을 닫았음을 Appdelegate에게 전달하는 메서드이다.







Rerefence


Swift 공식 문서
Apple Developer - wwdc2019
[iOS - SceneDelegate] iOS13이상 버전의 SceneDelegate
[iOS] AppDelegate & SceneDelegate
[iOS] iOS13이후의 AppDelegate와 SceneDelegate

0개의 댓글