study record

[iOS] Responding to the Launch of Your App (UIKit - App and environment - Responding to the launch of your app) 본문

iOS/iOS_Document

[iOS] Responding to the Launch of Your App (UIKit - App and environment - Responding to the launch of your app)

asong 2022. 5. 9. 21:04

공식문서를 읽고 정리한 글입니다.

 

Responding to the launch of your app

앱의 데이터 구조를 초기화하고, 앱을 실행시키기 위한 준비를 하고, 시스템으로부터 시작 시간 요청에 반응하는 것


Overview

시스템은 유저가 홈 화면에서 앱 아이콘을 탭할 때 앱을 시작시킨다. 만약 너의 앱이 특정 이벤트를 요청했다면, 시스템은 그 이벤트들을 다루기 위해 백그라운드에서 앱을 시작할지도 모른다. scene 기초 앱들을 위해, 시스템은 scene들 중 하나가 화면에 나타나는 것이 필요하거나 작업을 하는 것이 필요할 때 비슷하게 앱을 시작시킨다.

 

모든 앱들은 UIApplication 객체가 나타내는 연관된 프로세스를 가진다. 앱들은 또한 UIApplicationDelegate 프로토콜을 채택하는 객체, 중요한 이벤트가 발생하는 것에 반응하는 app delegate 객체를 가진다. 심지어 scene 기초 앱들은 시작과 종료와 같은 근본적인 이벤트들을 관리하기 위해 app delegate를 사용한다. 시작 시간에, UIKit는 자동적으로 UIApplication 객체와 app delegate를 만든다. 그리고 나서 앱의 메인 이벤트 루프를 시작시킨다.

 

Provide a Launch Storyboard

유저가 디바이스에 앱을 처음으로 시작할 때, 시스템은앱이 UI를 보여줄 준비가 될 때까지 런치 스토리보드를 보여준다. 런치 스토리보드를 보여주는 것은 앱이 시작되었고 어떤 것을 하는 중이라는 것을 유저에게 확신해 준다. 만약 앱이 스스로 초기화하고, UI를 빠르게 준비한다면 유저는 런치 스토리보드를 아주 짧게 볼지도 모른다.

 

Xcode 프로젝트는 자동적으로 디폴트 런치 스토리보드를 커스텀하도록 포함한다. 런치 스토리보드들을 필요하다면 더 많이 추가할 수 있다. 새 런치 스토리보드를 추가하기 위해서는 다음을 따라야 한다.

1. Xcode에서 프로젝트를 연다.

2. File > New > File

3. 프로젝트에 런치 스크린 리소스를 추가한다.

 

런치 스토리보드에 뷰들을 추가하고 크기와 위치에 Auto Layout 제약을 사용하여 근본 환경에 적응하도록 한다. UIKit는 제공하는 것을 제약을 사용하여 이용가능한 공간에 뷰를 맞게 보여준다. 

 

*Important

런치 스크린에 정적인 이미지를 사용하지 말아라. iOS14 이상에서 런치 스크린은 25MB로 제한된다.

 

Initialize Your App's Data Structures

앱의 런치 타임 초기화 코드는 다음의 메소드 하나 또는 둘 다에 넣는다.

- application(_:willFinishLaunchingWithOptions:)

- application(_:didFinsihLaunchingWithOptions:)

 

UIKit는 이 메소드들을 앱의 런치 사이클 시작에 호출한다.

그 목적은 다음과 같다.

- 앱의 데이터 구조들을 초기화

- 앱이 실행될 필요가 있는 자원들을 가지고 있다는 증명

- 앱이 처음으로 시작될 때 설정 수행. 예를 들어 쓸 수 있는 디렉토리에서  템플렛이나 유저 변경가능 파일들을 설치한다.

- 앱을 사용하는 중요한 서비스들에 연결. 예를 들어, Apple Push 알림 서비스에 연결

- 왜 앱이 시작하는지에 대한 정보를 위한 런치 선택 옵션 사전 체크

 

scene based 가 아닌 앱들을 위해서, UIKit는 기본 유저 인터페이스를 시작 시간에 자동적으로 로드한다. application(_:didFinishLaunchingWithOptions:) 메서드를 스크린에 나타나기 전 추가적 변경을 만들기 위해 사용하라. 예를 들어, 유저가 지난 번에 앱을 사용했던 것을 반영하기 위해 다른 뷰컨트롤러를 설치할지도 모른다.

 

Move Long-Running Tasks off the MainThread

유저가 앱을 시작할 때, 빠르게 시작하는 것에 의해 좋은 인상을 만든다. UIKit는 application(_:didFinishLaunchingWithOptions:) 메서드가 리턴할 때까지 앱 인터페이스를 보내지 않는다. 이 메소드에서 긴 실행 테스크를 수행하는 것은 앱을 유저에게 부진하게 보여줄지도 모른다. 리턴을 빠르게 하는 것은 백그라운드에서 런칭할 때 중요하다. 시스템이 앱의 백그라운드 실행 시간에 제한을 두고 있기 때문이다.

 

런치 타임 시퀀스에서 앱의 초기화에 중요하지 않는 테스크는 이동시켜라.

- 앱이 즉시 필요하지 않는 특징의 초기화는 연기하기

- 중요하고 오래 걸리는 테스크들은 메인 스레드에서 이동시킨다. 예를 들어, 비동기적으로 global dispatch 큐에서 실행시키자.

 

Determine Why Your App Launched

UIKit가 앱을 시작할 때, application(_:willFinishLaunchingWithOptions:), application(_:didFinsihLaunchingWithOptions:) 메서드에 왜 앱이 시작했는지에 대한 정보를 런치 옵션 딕셔너리를 따라 전달한다. 딕셔너리의 키들은 즉시 수행할 중요 테스크들을 가리킨다. 예를들어, 그들은 유저가 어디에서 시작했는지, 앱을 계속하기를 원하는지의 액션들을 반영할지도 모른다. 항상 런치 옵션 딕셔너리의 컨텐츠를 체크하고 적절히 반응해라.

 

*Note

scene based 앱을 위해, UIKit는 application(_:configurationForConnecting:options:) 메서드에 왜 씬이 만들어졌는지를 결정하는 것을 전달한다.

 

아래 코드는 app delegate 메서드가 백그라운드 위치 업데이트를 다루는 것을 보여준다.로케이션 키가 존재할 때, 앱은 로케이션 업데이트를 즉시 시작한다. 위치 업데이트를 시작하는 것은 Core Location 프레임워크가 새 로케이션 이벤트를 전달하는 것을 허락한다.

 

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…
}

 

시스템은 앱이 상응하는 특징을 지원하지 않는다면 키를 포함하지 않는다. 예를 들어, 시스템은 리모트 알림을 지원하지 않는 앱을 위해 remoteNotification 키를 포함하지 않는다.

 

런치 옵션 키들과 어떻게 다루는지에 대한 정보는 UIApplication.LaunchOptionsKey를 참고하자.