우선 공식 문서를 먼저 살펴보쟈! 오늘은 공식 문서의 도움을 더더더ㅓㅓ더더ㅓ 많이 받을 예정... ㅎ.ㅎ
앱이 foreground 또는 background에 있을 때 시스템 알림에 응답하고, 기타 중요한 시스템 관련 이벤트를 처리함
✏️ foreground - 쉽게 이야기하자면 앱이 실행되면서 사용자에게 보여지고 있는 상태
✏️ background - 앱이 실행은 되고 있지만, 백그라운드에 있는 상태이므로 사용자에게 보이지 않음
➡️ 자세한 내용은 뒤에서 더 다뤄볼 것!
앱의 현재 상태에 따라 할 수 있는 것과 할 수 없는 것이 결정된다.
예를 들어,
foreground 앱은 사용자에게 보여지므로, system resource에서 우선순위를 가진다.
대조적으로, background 앱은 가능한 적은 작업을 해야 하며, 가급적 아무것도 하지 않는 것이 좋다.
따라서 앱의 상태가 변경될 때마다 그에 따라 동작을 조정해야 한다.
앱의 상태가 변경되면, UIKit은 적절한 delegate 객체의 메서드를 호출하는 방식으로 알린다.
iOS 13부터는 scene-based app의 life-cycle 이벤트에 반응하기 위해 UISceneDelegate object를 사용
iOS 12 이전에는, life-cycle 이벤트에 반응하기 위해 UIApplicationDelegate object를 사용
간단하게 정리해 보자면,
iOS 13부터는 scene을 지원하였고, 그 이전 버전에는 scene을 지원하지 않았다.
scene-based app의 life-cycle 이벤트에 응답할 때는 UISceneDelegate object, 그 이전에는 UIApplicationDelegate object를 사용한다고 한다.
그래서, scene이란 대체 무엇일까?
iOS 13 부터 Scene이라는 개념이 도입되었다.
Scene은 UI의 한 인스턴스를 표시하기 위한 window와 view controller가 포함된다. 각 Scene은 서로 동시에 실행되며, 같은 메모리와 앱 프로세스 공간을 공유한다. 하나의 앱은 여러 개의 Scene과 Scene delegate object를 활성화할 수 있다.
➡️ 하나의 앱을 동시에 켤 수 있다 ❗️
또한, 각 Scene은 각자의 life cycle을 가지기 때문에 각각 다른 실행 상태에 있을 수 있다.
iOS 13부터 UISceneDelegate를 도입하게 되면서, AppDelegate의 역할이 AppDelegate와 SceneDelegate로 나뉘었다.
앱의 scene들이 가지고 있는 정보를 포함하는 객체
참고) app switcher
Unttached
: Scene이 아직 앱에 연결되어 있지 않다는 것을 나타냄Foreground Inactive
: Scene이 foreground에서 실행되고 있지만, 이벤트를 수신하고 있지 않음을 나타냄Foreground Active
: Scene이 foreground에서 실행되고 있고, 이벤트를 수신하고 있다는 것을 나타냄Background
: Scene이 background에서 실행 중이고 화면에 표시되지 않음을 나타냄Suspended
: Scene이 background에 있으며, 아무것도 실행되지 않음사용자나 시스템이 앱의 새로운 scene을 요청하면, UIKit은 scene을 생성하고, unttached state(연결되지 않은 상태)로 둔다.
사용자가 앱의 UI를 닫으면, UIkit은 연결된 장면을 background 상태로 전환하고, 결국에는 일시 중단 상태로 전환한다.
UIkit은 자원을 회수하기 위해 언제든지 background이나 suspended scene의 연결을 끊어 연결되지 않은 상태로 되돌릴 수 있다.
앱이 background 상태로 전환되면 UIkit은 현재 사용자의 인터페이스에 대한 snapshot을 찍는다.
⬆️ 프로젝트를 생성하면 자동으로 생성되는 SceneDelegate 파일을 누르면 나오는 메서드들
scene(_:willConnectTo:options:)
앱의 scene 추가에 대해 대리자에게 알림
sceneDidDisconnect(_:)
대리자에게 UIkit이 앱에서 scene을 제거했음을 알림
sceneDidBecomeActive(_:)
대리자에게 scene이 활성화되었으며 사용자의 이벤트에 응답하고 있음을 알림
sceneWillResignActive(_:)
대리자에게 scene의 활성화 상태를 resign하고 사용자 이벤트에 대한 응답을 중지하려 한다고 알림
sceneWillEnterForeground(_:)
대리자에게 scene이 foreground에서 실행되기 시작하고, 사용자에게 표시될 것임을 알림
sceneDidEnterBackground(_:)
대리자에게 scene이 background에서 실행 중이며, 더이상 화면에 표시되지 않음을 알림
그 외)
https://developer.apple.com/documentation/uikit/uiscenedelegate/
Scene delegate에서 각 메서드에 print(#function)을 적어 주자
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let _ = (scene as? UIWindowScene) else { return }
print(#function)
}
func sceneDidDisconnect(_ scene: UIScene) {
print(#function)
}
func sceneDidBecomeActive(_ scene: UIScene) {
print(#function)
}
func sceneWillResignActive(_ scene: UIScene) {
print(#function)
}
func sceneWillEnterForeground(_ scene: UIScene) {
print(#function)
}
func sceneDidEnterBackground(_ scene: UIScene) {
print(#function)
}
Not Running
: 아직 실행되지 않은 상태 혹은 완전히 종료된 상태Active
: 앱이 foreground에서 실행되고 있으며, 이벤트를 받고 있는 상태Inactive
: 앱이 foreground에서 실행되고 있지만, 이벤트를 받고 있지 않는 상태Background
: 앱이 bacground에서 실행되고 있는 상태Supended
: Scene이 background에 있으며, 아무것도 실행되지 않는 상태실행된 후, 시스템은 UI가 화면에 나타날 것인지 여부에 따라 앱을 inactive나 background 상태로 전환한다.
foreground에서 시작할 때는, 시스템은 앱을 자동으로 active 상태로 전환한다.
그 후에, 앱은 종료되기 전까지 active와 background 상태 사이에서 변동한다.
iOS 12 이전에 scene을 지원하지 않는 앱에서, UIKit은 모든 life-cycle event를 UIApplicationDelegate object에 전달했다. 앱의 delegate(대리자)는 화면에 표시되는 창을 포함하여 앱의 모든 창을 관리했다. 결과적으로, 앱의 상태 전환은 외부 디스플레이 컨텐츠를 포함하여 앱의 모든 UI에 영향을 주었다.
application(_:didFinishLaunchingWithOptions:)
application(_:configurationForConnecting:options:)
application(_:didDiscardSceneSessions:)
그 외)
https://developer.apple.com/documentation/uikit/uiapplicationdelegate/3197905-application
🔗
https://medium.com/@kalyan.parise/understanding-scene-delegate-app-delegate-7503d48c5445
https://developer.apple.com/