일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- TypeScript
- Xcode
- globalcommunity
- 회고
- UIKit
- JavaScript
- 코딩테스트실력진단
- git
- 코드트리챌린지
- 알고리즘
- tshaped
- 프로그래머스
- Front-end
- 프로젝트
- 코딩테스트
- 프론트엔드
- 자바스크립트
- AppleDeveloperAcademy
- swiftUI
- SWIFT
- NextJs
- velog
- Apple Developer Academy
- ios
- react
- iOSDeveloper
- frontend
- react-query
- 코드트리
- error
- Today
- Total
Moon Work
iOS 13 이상에서의 App Life Cycle(AppDelegate, SceneDelegate) 본문
CS 스터디에 참여하면서 다시 기본기를 다지고 있습니다. 재미있는 내용이 많은데, SceneDelegate를 통해 어떻게 로그가 찍히는지 확인해보겠습니다.
App Life Cycle
사실 앱의 라이프 사이클과 관련해서는 애플에서도 너무 정리를 잘 해두었고, 좋은 리소스가 많습니다. 라이프 사이클에 대한 배경은 아래 참고로 남겨두겠습니다.
https://developer.apple.com/documentation/uikit/managing-your-app-s-life-cycle
Managing your app’s life cycle | Apple Developer Documentation
Respond to system notifications when your app is in the foreground or background, and handle other significant system-related events.
developer.apple.com
https://blog.naver.com/doctor-kick/222423840595
[iOS] 앱의 생명주기(LifeCycle) AppDelegate
생명주기 (Life Cycle)이란? 생명주기라는 것은 앱의 최초 실행부터 앱이 완전이 종료되기까지 앱이 가지...
blog.naver.com
Swift: SwiftUI 프로젝트에 AppDelegate, SceneDelegate 만들기
AppDelegate와 SceneDelegate 만드는 법, 그리고 그 두 파일 없이도 대응하는 법을 알아보자
medium.com
그래서 언제 어떤 함수가 호출되는걸까?
AppDelegate, SceneDelegate.. 함수명도 길어서 헷갈리네요. 이럴 때는 프로젝트에서 직접 확인해보는 것을 선호합니다.
저는 아래 AppDelegate를 만들고 SwiftUI에서 사용하기 위해
`@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate`
를 앱 최상단에 선언하여 앱의 상태관리에 대해 이전하였습니다.
import SwiftUI
class AppDelegate: NSObject, UIApplicationDelegate {
func applicationWillEnterForeground(_ application: UIApplication) {
print("""
---
Background -> InActive
앱이 Background에서 InActive로 전활될 때 호출됩니다.
호출된 함수: \(#function)
호출한 객체 \(String(describing: type(of: self)))
"""
)
}
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
print("""
---
InActive
main storyboard, nib 파일이 로드된 이후 호출되며 초기화 및 실행 준비를 합니다.
호출된 함수: \(#function)
호출한 객체 \(String(describing: type(of: self)))
"""
)
return true
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
print("""
---
InActive -> Active
앱을 실행시키기 위한 모든 설정을 완료하고 화면을 보여주기 직전에 호출됩니다.
호출된 함수: \(#function)
호출한 객체 \(String(describing: type(of: self)))
"""
)
return true
}
func applicationDidBecomeActive(_ application: UIApplication) {
print("""
---
Active
Active 상태가 된 직후 호출됩니다.
호출된 함수: \(#function)
호출한 객체 \(String(describing: type(of: self)))
"""
)
}
func applicationWillResignActive(_ application: UIApplication) {
print("""
---
Active -> InActive
Active 상태에서 InActive 상태가 된 직후 호출됩니다.
호출된 함수: \(#function)
호출한 객체 \(String(describing: type(of: self)))
"""
)
}
func applicationDidEnterBackground(_ application: UIApplication) {
print("""
---
Background
앱이 Background 상태가 되었을 때 호출됩니다.
호출된 함수: \(#function)
호출한 객체 \(String(describing: type(of: self)))
"""
)
}
func applicationWillTerminate(_ application: UIApplication) {
print("""
---
Background -> Not Running
앱이 종료될 때 호출됩니다.
호출된 함수: \(#function)
호출한 객체 \(String(describing: type(of: self)))
"""
)
}
}
@main
struct TestProjectApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
로그가 찍히지 않습니다?
제 기대는 앱을 작동하면 촤라라락 로그가 찍힐 줄 알았는데
`application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool`
와
`func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool`
에 대한 로그만 찍힌 것을 확인했습니다. 이건 너무 이상했지만, iOS 13부터 적용된 SceneDelegate의 존재를 알고 있었기 때문에 SceneDelegate를 아래와 같이 적용해서 다시 로그를 찍어보았습니다.
import SwiftUI
class AppDelegate: NSObject, UIApplicationDelegate {
func applicationWillEnterForeground(_ application: UIApplication) {
print("""
---
Background -> InActive
앱이 Background에서 InActive로 전활될 때 호출됩니다.
호출된 함수: \(#function)
호출한 객체 \(String(describing: type(of: self)))
"""
)
}
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
print("""
---
InActive
main storyboard, nib 파일이 로드된 이후 호출되며 초기화 및 실행 준비를 합니다.
호출된 함수: \(#function)
호출한 객체 \(String(describing: type(of: self)))
"""
)
return true
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
print("""
---
InActive -> Active
앱을 실행시키기 위한 모든 설정을 완료하고 화면을 보여주기 직전에 호출됩니다.
호출된 함수: \(#function)
호출한 객체 \(String(describing: type(of: self)))
"""
)
return true
}
func applicationDidBecomeActive(_ application: UIApplication) {
print("""
---
Active
Active 상태가 된 직후 호출됩니다.
호출된 함수: \(#function)
호출한 객체 \(String(describing: type(of: self)))
"""
)
}
func applicationWillResignActive(_ application: UIApplication) {
print("""
---
Active -> InActive
Active 상태에서 InActive 상태가 된 직후 호출됩니다.
호출된 함수: \(#function)
호출한 객체 \(String(describing: type(of: self)))
"""
)
}
func applicationDidEnterBackground(_ application: UIApplication) {
print("""
---
Background
앱이 Background 상태가 되었을 때 호출됩니다.
호출된 함수: \(#function)
호출한 객체 \(String(describing: type(of: self)))
"""
)
}
func applicationWillTerminate(_ application: UIApplication) {
print("""
---
Background -> Not Running
앱이 종료될 때 호출됩니다.
호출된 함수: \(#function)
호출한 객체 \(String(describing: type(of: self)))
"""
)
}
func application(
_ application: UIApplication,
configurationForConnecting connectingSceneSession: UISceneSession,
options: UIScene.ConnectionOptions
) -> UISceneConfiguration {
let sceneConfig = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role)
sceneConfig.delegateClass = MySceneDelegate.self
return sceneConfig
}
}
class MySceneDelegate: NSObject, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let _ = (scene as? UIWindowScene) else { return }
}
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)
}
}
@main
struct TestProjectApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
로그를 보겠소
SceneDelegate에서 호출한 로그들이 잘 찍히는 것을 확인할 수 있습니다. SceneDelegates는 iOS 13부터 여러개의 Scene을 사용하기 위한 목적으로 UI LifeCycle을 AppDelegate 대신 처리하게 되었습니다.
만약 위에 SceneDelegate 대신 iOS 12 이전 처럼 AppDelegate를 사용하길 원한다면
Info.plist-Scene Configuration 속성을 삭제하면 AppDelegate에서 라이프 사이클을 처리하게 됩니다.
정리
코드를 다 외우기 어렵다고 생각했는데, SceneDelegate에서 직접 로그를 찍어보니 생각보다 직관적이어서 앱의 상태에 따라 필요한 리소스, 메모리 관련 처리를 하는 것에 대한 해상도가 높아진 것 같습니다.
레퍼런스
https://developer.apple.com/documentation/uikit/managing-your-app-s-life-cycle
Managing your app’s life cycle | Apple Developer Documentation
Respond to system notifications when your app is in the foreground or background, and handle other significant system-related events.
developer.apple.com
https://blog.naver.com/doctor-kick/222423840595
[iOS] 앱의 생명주기(LifeCycle) AppDelegate
생명주기 (Life Cycle)이란? 생명주기라는 것은 앱의 최초 실행부터 앱이 완전이 종료되기까지 앱이 가지...
blog.naver.com
Swift: SwiftUI 프로젝트에 AppDelegate, SceneDelegate 만들기
AppDelegate와 SceneDelegate 만드는 법, 그리고 그 두 파일 없이도 대응하는 법을 알아보자
medium.com
'iOS' 카테고리의 다른 글
ScreenTime API로 앱 접근 제한 및 앱 배포하기 (1) | 2025.05.04 |
---|---|
[SwiftUI] 자연스러운 애니메이션 구현하기: @Namespace & matchedGeometryEffect(+matchedTransitionSource) (0) | 2025.05.01 |
'Instrument' 처음 시작하기: Instrument 기초와 기본 활용 (2) | 2024.11.01 |
Code Signing & Provisioning Profile 총정리: 하나의 앱을 여러 팀원과 공유하기 (1) | 2024.10.21 |
WeatherKit Attribution 이슈: Guideline 5.2.5 - Legal - Intellectual Property (3) | 2024.10.05 |