-
[개발자 문서읽기] Responding to the Launch of Your AppiOS 2021. 1. 16. 15:54728x90
개인적으로 공부하며 정리하는 블로그 입니다.
오류나 부족한 부분이 있을 수 있으니 감안하여 봐주시고 아낌없는 조언 감사드립니다 :DInitialize your app’s data structures, prepare your app to run, and respond to any launch-time requests from the system.
앱을 실행하면 어떤 일들이 일어날까요? 관련 문서를 읽으면서 정리해봤습니다.
아이폰 홈에서 앱을 클릭하면 스플래시 화면이 보이면서 앱이 시작하게 되죠? 스플래시 화면(런치 스크린)은
"앱이 잘 실행은 됐어요. 준비될 때까지 조금만 기다려주세요"
라는 의미로 보여주는 화면입니다. 그 런치스크린이 보여지는 동안에 이루어지는 작업들에 관한 이야기 입니다.
이 문서를 잘 읽으려면 사용자가 직접 앱을 터치해서 시작하는 것 말고 다른 경우에도 앱이 시작될 수 있다는 걸 이해해야 할 거 같아요. 앱은 꼭 내가 직접 켜야만 켜지는 건 아닙니다. 위치 기반 앱이나 알림 앱 같은 경우를 생각해보면, 내가 앱을 종료시켰더라도 필요한 경우에 알아서 알림이 오고 하죠? 이런 건 분명 앱 내의 코드로 동작하는 작업들입니다. 앱이 실행되었기 때문에 가능한 일이라는거죠! 즉, 시스템(아이폰)이 필요할 때 앱을 깨워주기 때문에 가능합니다. 이럴 땐 시스템이 백그라운드에서 앱을 깨워주고 있는거에요.
여기까지 이해하셨다면 간단하게 흐름을 정리해보겠습니다.
앱이 처음 실행되면 UIKit이 UIAppliationMain(_:_:_:_:) 메소드를 호출해서 UIApplication 객체와 app delegate를 생성하고 메인 이벤트 루프를 시작하는 등 기본적인 세팅을 합니다.
기본적인 세팅에 대해 더 자세한 내용이 궁금하시다면 UIApplicationMain(:::) 글을 참고해주세요 :)
앱의 기본적인 세팅이 다 끝나면 마지막으로 application(:didFinishLaunchingWithOptions:) 를 호출해서
나는 준비가 다 됐는데, 더 할 게 있으면 하라고 물어봐줍니다. 이 함수에서 return 값까지 오면 준비가 다 됐다고 판단하고 앱을 보여주는 겁니다.
따라서 application(:didFinishLaunchingWithOptions:) 에서 너무 오래 걸리는 작업을 처리하면 사용자는 그 작업이 끝날 때까지 기다려야 합니다. 그러니까 그런 작업은 가급적 피하고 해야한다면 global dispatch queue 같은 걸 이용해서 비동기적으로 처리해줘야 합니다.추가로,
이때 option 파라미터로 앞서 말씀드린 대로 앱이 왜 실행됐는지에 대한 정보를 넘겨줍니다. 상황에 맞게 처리해주면 되겠죠 :)리턴 값으로는 URL resource를 처리할 수 없거나 사용자 activity를 계속 할수 없는 경우와
홈화면에서 quick action으로 깨워졌을 때는 application(_:performActionFor:completionHandler:) 메소드가 불리므로,
같은 처리를 해주는 경우에 false를 반환해줍니다.
나머지는 true를 반환하면 됩니다.이제 문서를 제대로 읽어볼까요? :)
공부하며 번역한 내용입니다.
오역과 의역이 있을 수 있습니다. 정확한 내용은 원문을 참고해주세요 :)OverView
사용자가 아이폰 홈에서 앱 아이콘을 클릭하면 시스템은 앱을 시작합니다. 만약 앱이 특정 이벤트를 요청했다면, 이 이벤트들을 처리하기 위해 백그라운드에서 앱을 실행할 수도 있습니다. scene 기반 앱의 경우 scene 중 하나가 화면에 나타나거나 어떤 작업을 해야할 때 시스템은 앱을 실행시킵니다.
모든 앱은 UIApplication 객체가 나타내는 관련된 프로세스가 있습니다. 앱은 또 UIApplicationDelegate 프로토콜을 처리하는 AppDelegate 객체를 갖는데, 프로세스 내의 중요한 이벤트에 응답합니다. scene 기반 앱도 app delegate를 사용해서 시작 및 종료 같은 기본 이벤트를 관리합니다. 시작 할 때(at launch time), UIKit은 자동으로 UIApplication 객체와 app delegate 객체를 생성합니다. 그리고 앱의 메인 이벤트 루프를 실행시킵니다.
Provide a Launch Storyboard
사용자가 앱을 처음 실행하면 시스템은 앱이 UI를 보여줄 준비가 될 때까지 Launch Storyboard를 보여줍니다. 런치 스토리보드를 보여줌으로써 사용자에게 앱이 실행됐고 뭔가 하고 있다고 인지시켜줄 수 있습니다. 앱의 초기화와 준비가 빨리 끝났다면 사용자는 아주 잠깐만 동안만 런치 스토리보드를 볼 수 있습니다.
Xcode Project는 자동으로 커스텀할 수 있는 Launch Storyboard를 제공합니다. 필요하다면 더 추가할 수도 있습니다. 다음 과정으로 추가할 수 있습니다.
- Open your project in Xcode.
- Choose File > New > File.
- Add a Launch Screen resource to your project.
런치 스토리보드에 뷰를 추가하고 기본 환경에 맞게 오토레이아웃을 사용해서 크기와 위치를 조정하세요. UIKit은 제약 조건에 맞게 적합한 영역에 뷰를 보여줍니다. 디자인 가이드라인은 Human Interface Guidelines 를 확인하세요.
런치스크린에 정적인 이미지를 사용하지 마세요. iOS 14 이후로 런치스크린은 14MB로 제한됩니다.
Initialize Your App's Data Structures
앱 시작타임(launch-time)의 초기화 코드를 다음 메소드 중에 하나 또는 둘다 넣으세요.
UIKit은 이 메소드들을 시작 사이클의 처음에(the beginning of your app's launch cycle) 호출합니다. 이렇게 사용하세요.
- 앱의 데이터 구조를 초기화하세요
- 실행해야 하는 리소스가 있는지 확인하세요
- 앱이 처음 실행될 때 한 번만 하는 작업을 수행하세요. 예를 들어, 쓰기가능한 디렉토리에 있는 템플릿이나 유저가 수정할 수 있는 파일을 설치하세요. Performing One-Time Setup for Your App을 확인하세요.
- 앱이 사용하는 중요 서비스들을 연결하세요. 예를 들어, 만약 앱이 원격 푸시알림을 사용한다면 APNs(Apple Push Notification service)와 연결하세요
- 앱이 시작된 이유 대한 정보는 시작옵션(launch option) 딕셔너리를 확인하세요. Determine Why Your App Launched 를 확인하세요.
scene 기반 앱이 아니라면 UIKit이 시작시간에 기본 UI를 자동으로 불러옵니다. 앱이 화면에 나타나기 전에 다른 인터페이스로 바꾸고 싶다면 the application(_:didFinishLaunchingWithOptions:) 를 사용하세요. 예를 들어, 사용자가 마지막에 하던 동작으로 바꿔주고 싶을 때 사용할 수 있습니다.
Move Long-Running Tasks off the Main Thread
앱이 빨리 실행되어야 사용자에게 좋은 인상을 줄 수 있습니다. UIKit은 application(:didFinishLaunchingWithOptions:) 메소드가 반환되기 전까지 앱 인터페이스를 보여주지 않습니다. 오래 걸리는 작업을 이 메소드나 application(:willFinishLaunchingWithOptions:) 에서 실행하면 사용자에게 앱이 느리다는 인상을 줄 수 있습니다. 시스템이 앱의 백그라운드 작업도 제한하기 때문에 백그라운드에서 실행할 때도 빨리 수행되는 게 중요합니다.
시작시간에 반드시 수행되어야 하는 작업이 아니라면 다른 곳으로 옮기세요. 예를 들어,
- 당장 필요하지 않은 초기화는 연기합니다.
- 오래 걸리는 작업은 메인 스레드에서 제거합니다. 예를 들어, 글로벌 디스패치 큐에서 비동기적으로 수행하세요.
Determine Why Your App Launched
앱이 시작할 때 UIKit은 앱이 실행된 이유에 대한 정보를 application(:willFinishLaunchingWithOptions:) 와 application(:didFinishLaunchingWithOptions:) 에 넘겨줍니다. 딕셔너리의 key는 당장 시작할 중요한 작업을 나타냅니다. 예를 들어, 사용자가 다른 곳에서 앱을 시작했으며 계속 하려고 하는 작업을 반영할 수 있습니다. 항상 실행 옵션을 확인하고 딕셔너리에 원하는 키가 있는지 확인해서 적절하게 대응하세요.
Note
scene 기반 앱에서는 UIKit이 application(_:configurationForConnecting:options:) 메소드에 전달하는 옵션으로
scene이 만들어진 이유를 확인하세요.Listing 1은 백그라운드에서 위치 업데이트를 처리한 앱에 대한 app delegate를 보여줍니다. 시작 옵션에 location 키가 존재하면 나중으로 미루지 않고 즉시 위치 업데이트를 시작합니다. 위치 업데이트를 시작하면 Core Location Framework가 새로운 위치 이벤트를 전달합니다.
Listing 1 Responding to a location event at launch time
class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate { let locationManager = CLLocationManager() func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // If launched because of new location data, // start the visits service right away. if let keys = launchOptions?.keys { if keys.contains(.location) { locationManager.delegate = self locationManager.startMonitoringVisits() } } return true } // other methods… }
앱이 해당 기능을 제공하지 않으면 시스템을 키를 갖고 있지 않습니다. 예를 들어, 앱이 remote notificaitons를 지원하지 않으면 시스템은 remoteNotification 키를 갖고 있지 않습니다.
시작 옵션 키와 어떻게 다루는지에 대한 정보는 UIApplication.LaunchOptionsKey를 확인하세요.
참고
'iOS' 카테고리의 다른 글
GCD, Dispatch (0) 2021.01.19 [개발자 문서읽기] UIApplicationMain(::::) (0) 2021.01.16 [개발자 문서읽기] UIApplication (0) 2021.01.16 앱에서 너무 많은 메모리를 사용하면 어떻게 될까? 어떻게 확인할까? (0) 2021.01.15 [개발자 문서읽기] UIView - 1 (0) 2021.01.13