본문 바로가기
프로그래밍/Swift + SwiftUI

IOS App의 Life-Cycle들(scene-based와 app-based)

by yonmoyonmo 2022. 1. 20.

답답- 하다!

IOS앱을 Swift 개발할 이렇게 고려할게 많을줄 전혀 몰랐다.

일단 IOS12 이하 버전의 구조와 IOS13이상 버전의 구조를 기준으로 달라진 부분을 중심으로 자료를 찾아보며 이해했다. 그런 기준을 잡았냐면, IOS13부터 안드로이드처럼 멀티테스킹을 지원하기로 하면서 Scene이라는 개념이 생겼고 그로 인해 코드와 LifeCycle에도 변화가 생겼기 때문이다. 그리고 SwiftUI IOS13부터 출현했다고 하니 그렇게 기준을 잡아봤다.


일단 IOS 관한 조사를 하게되었는지에 대해 짧게 잡설을 해보자면

생각없이 친구들과 아이폰 앱을 하나 만들어서 내자 해서 SwiftUI 앱을 하나 만들었다. SwiftUI 앱을 개발할 때에는 옛날에 개발자들이 얼핏 보면 포토샾 화면 같은걸로 아이폰 앱을 개발하더니 요즘은 그냥 이걸로 하는가보다 하고 작업을 했는데, 중간 개발했을  SwiftUI 여러가지 기능을 쓰려면 빌드 타겟이 IOS14이상 되어야 한다는 것을 알게되고(별생각없이 Xcode 세팅해 놓은 빌드 타겟 그대로 개발하고 있었다. 개발 처음부터 하위버전 OS호환이 당연히 될거라 생각해버렸고...), 그러면 도대체 IOS13부터 호환은 어떻게 처리해야하는가를 알아보니 그딴건 없었고... 다행히 IOS 점유율이 14, 15 90%였기 때문에 다행이다라고 생각은 했지만 찝찝함을 거둘 없었고...

그리고 지금에 와서 ARKit 써볼까 싶어서 자료를 뒤져 보았다. 이번에는 IOS12 이하에서도 돌아갔으면 좋겠다고 생각했는데, Scene이라는 개념과 SceneDelegate 분리되면서 UIKit 써도 IOS13이상 되야 돌아간다는 것이 아닌가? 그러면 12?!?!!!?

12이하는 뒤로 돌아가서 SceneDelegate 분리되기 , 아이패드의 분할화면 기능이 없던 시절, AppDelegate 있던 시절의 방식으로 개발을 하면 된다고 한다. 아니면 벌의 코드를 작성하고 어노테이션 같은 것을 달아서 호환문제를 해결 있다고 한다. 정말 혼란스럽다.

이런 혼란을 스스로 잠재우기 위해 이해한 내용을 정리해 글로 남겨본다. 그래도 다행히 공식 document가 읽기 좋게 잘 나와있음.



scene-based app  과 app-based app

IOS13포함 이후 버전부터는 scene-based app이라고 하는 방식을 사용하고, UISceneDelegate 객체를 사용하여 life-cycle 이벤트에 응답한다. scene-based app 아이패드에서 하나의 앱을 여러 화면으로 띄울 있게 해준다고 한다. 

IOS12포함 이전 버전은 UIApplicationDelegate 객체가 life-cycle 이벤트에 응답한다. 이걸 app-based app이라고 하는 같다.


Scene-Based App, IOS13 이상

Scene-based app IOS13부터 지원한다. UI scene 담당하게 하여, 멀티플 윈도우를 가능하게 주는 방식으로, 이전 버전의 life-cycle 다른 부분이 많다. 프로젝트를 생성할 appDelegate 파일과 SceneDelegate 파일이 생긴다면 xcode 최신버전이라서 그런 것이고, Scene-based app 만들어라고 유도한 것으로 보인다(나중에라도 IOS12이하를 커버해야하게 되면 그에 따른 작업들을 줘야 한다. 그래서 프로젝트 생성시점에 멀티플 윈도우를 지원할 것인지 것인지, IOS12포함 이전 버전도 지원할 것인지 등을 고려해야하지 않을까 싶다).

UISceneDelegate

UISceneDelegate 앱의 UI 인스턴스 하나의 life-cycle 이벤트들을 관리하는 객체다. 이것은 scene foreground, background 들어가며 변화하는 상태를 포함한 state transition 관한 method들이 정의된 프로토콜(자바 interface 같은 것임)인데,

직접 UISceneDelegate 구현해서 쓰지말고 Info.plist파일에 커스텀 delegate 명시하거나 appDelegate application(_:configurationForConnecting: options:) method 이용해서 UISceneConfiguration 리턴할 안에 명시하면 된다고 한다.

모든 것이 전부 멀티플 윈도우기능을 지원하려면 필요하다는 말인 같다. Xcode UIKit app 프로젝트를 처음 생성했을 때에는 Info.plist 멀티플 윈도우 기능이 비활성화되어 있다. 만들던 앱이 멀티플 윈도우를 지원하게 하려면 프로젝트 생성 초기부터 관련 세팅을 해주는게 좋을 같다.

처음 프로젝트를 생성하면 sceneDelegate appDelegate 파일을 있는데, sceneDelegate UIWindowSceneDelegate 구현하는 클래스임을 있다. UIWindowSceneDelegate UISceneDelegate 속성들을 따르게 되어있다.

UISceneSession

scene 나오기 이전까지는 appDelegate(UIApplicationDelegate 구현함)에서 UI life-cycle 관리했는데, scene이후로는 sceneDelegate에서 관리한다. appDelegate에서는 그에 따라 새롭게 UISceneSession 이라는 것을 관리할 있는 method 생기고 scene 생성하고 관리할 있도록 되어있다.

scene

scene 멀티플 윈도우를 지원하기 위해 도입된 개념인데, 이전까지의 app life-cycle 다른 life-cycle 가지게 되었다. 본질적으로 하나의 앱에서 여러 화면을 띄우기 위해 존재한다. scene 하나의 UI인스턴스이며, winodows view controllers 포함하며, scene UIWindowSceneDelegate 객체에 상응하는 것을 갖고 있다. 그걸로 UIKit 앱과 상호작용한다. scene들은 각각 동시에 실행될 있는데, scene끼리 같은 메모리와 프로세스 공간을 공유한다.

만약 앱이 scene 지원한다고 여겨지면 UIKit scene마다 분리된 life-cycle 이벤트를 보낸다. scene마다 각각 개별된 life-cycle 가지게 되는 것이다. 그래서 멀티플 윈도우를 사용할 각각 백그라운드, 포그라운드 등의 상태를 가질 있게 된다.

개발하는 앱이 멀티플 윈도우를 지원하지 않더라도 sceneDelegate 이용해서 scene-based app 만들 있는 같다. UIKit UI life-cycle 이벤트를 appDelegate 아닌 sceneDelegate 알아서 보내주지 않을까 싶은데, 봐야 같다.


App-Based App, IOS12 이하

scene 지원하지 않는 IOS app이다. UIKit life-cycle이벤트를 UIAppDelegate 객체로 보낸다.

UIApplicationDelegate

앱이 공유하는 동작들에 관한 method들을 관리하는 프로토콜이다. 앱의 root 객체로써 앱을 관리한다. UIApplication 결합하여 시스템과의 상호작용도 관리한다. UIKit 앱의 런치 단계에서 app delegate 생성한다. 앱에 쓰이는 이것저것을 초기화하고, 설정하고 아무튼 초기 단계 작업을 있도록 해준다. IOS12이하에서는 app life-cycle 관리한다.

새로 추가된 개념이 아니라서 이정도만 적어놔도 같다. 개발 중요한 것은 "scene-based app이냐 아니냐" 같고, 아니라면 app-based 방식에 따라 개발하면 되는구나 정도만 알고 넘어가면 같다.

 


Life-Cycle

scene-base

하나에서 여러개의 화면을 실행할 있고, 화면은 scene 인스턴스이다. 화면은 각각의 life-cycle 가진다. 화면(scene) 종료되거나 해도 다른 화면은 영향을 받지 않는다.

Suspended, Unattached, Foreground Inactive, Foreground Active, Background 상태를 가진다.

유저가 새로운 화면을 요청하면, UIKit scene 만들고 unattached 상태로 만든다. unattached 화면은 빠르게 foreground active 되어 화면에 나타난다. 유저가 UI 끄면, UIKit UI background 보내고, 결과적으로 suspanded 된다. Background scene 필요로 한다면 계속 프로세스를 유지할 있다(GPU 그런거 , 백그라운드 프로세스). UIKit 언제든지 background, suspended 상태의 scene과의 연결을 끊고 리소스를 되찾을 있고 연결끊긴 scene unattached 상태가 된다.

app-based

하나의 하나의 화면만 실행할 있다.

Not Running, Inactive, Active, Backgrond, Suspended 상태가 있다.

앱이 실행되면 system 앱을 inactive 혹은 background 상태로 놓는다. UI 화면에 나타날 때인지 아닌지에 따라 그렇게 하는데, foreground 런칭될 시스템은 앱을 active상태로 알아서 놓아준다. 실행 이후로 앱은 수시로 active background 왔다리 갔다리 하다가 app 완전히 종료하면 life-cycle 끝난다.


느낀

그러면 SwiftUI에서 멀티플 윈도우를 지원하려면 어떻게 해야하는지 궁금해졌다. 하지만 그만 알아보고 이제 ARKit 앱을 만들어 봐야겠다.


참고자료 : 애플 개발자 문서

https://developer.apple.com/documentation/uikit/app_and_environment/managing_your_app_s_life_cycle

https://developer.apple.com/documentation/uikit/uiscenedelegate

https://developer.apple.com/documentation/uikit/uiwindowscenedelegate

https://developer.apple.com/documentation/uikit/app_and_environment/scenes

https://developer.apple.com/documentation/uikit/uiscenedelegate/supporting_multiple_windows_on_ipad

https://developer.apple.com/documentation/uikit/app_and_environment/scenes/specifying_the_scenes_your_app_supports

https://developer.apple.com/documentation/uikit/uiapplicationdelegate

https://developer.apple.com/documentation/uikit/uiapplication


'프로그래밍 > Swift + SwiftUI' 카테고리의 다른 글

UIKit  (0) 2022.01.19
IOS UI개발 방법 네 가지에 대한 글  (0) 2022.01.18

댓글