소피it블로그

[UIKit] 앱 론치에 응답하기 - 공식 문서 번역 본문

개발_iOS/UIKit

[UIKit] 앱 론치에 응답하기 - 공식 문서 번역

sophie_l 2022. 8. 12. 14:15

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

 

Apple Developer Documentation

 

developer.apple.com

1. 개요

 

시스템은 유저가 홈 스크린에서 앱의 아이콘을 탭하면 앱을 론치한다. 앱이 특정 이벤트를 요청한다면 시스템은 해당 이벤트를 처리하기 위해 백그라운드에서 앱을 론치시킬 수도 있다. 씬에 기반한 앱의 경우 시스템은 씬이 스크린에 나타나거나 일을 하려 할 경우 앱을 론치한다.

모든 앱들은 UIApplication 객체가 나타내는 처리과정을 갖는다. 앱은 또한 해당 처리과정 중에 발생하는 중요한 이벤트에 응답하기 위해 UIApplicationDelegate 프로토콜에 순응하는 객체인 app delegate 객체를 갖는다. 씬에 기반한 앱들도 론치나 종료같은 근본적인 이벤트를 다루기 위해서는 app delegate를 사용한다. 론치시에 UIKit는 자동적으로 UIApplication 객체와 app delegate를 생성한다. 그런 후에 앱의 메인 이벤트를 시작한다.

 

2. 론치 스토리보드 제공하기

 

유저가 앱을 기기에서 처음 구동하면 시스템은 앱이 UI를 보여줄 준비가 될 때까지 론치 스토리보드를 보여준다. 론치 스토리보드를 보여주면 유저가 앱이 론치되고 있다는 것을 확신할 수 있다. 만약 앱이 빠르게 초기화되어 UI를 준비시킨다면 론치 스토리보드는 짧게만 보여질 것이다.

Xcode 프로젝트들은 디폴트 론치 스토리보드를 자동으로 제공하여 커스텀할 수 있게 해준다. 필요하다면 더 많은 론치 스토리보드를 추가할 수도 있다. 프로젝트에 새로운 론치 스토리보드를 추가하기 위해서는 다음 과정을 진행하면 된다:

 

  1. 엑스코드에서 프로젝트 열기
  2. File > New > File
  3. 프로젝트에 론치 스크린 추가

론치 스토리보드에 뷰를 추가하고 오토 레이아웃 컨스트레인트를 적용하여 환경에 맞게 배치하라.

 

3. 앱의 데이터 구조를 초기화하기

 

다음 메서드 둘 중 하나 혹은 둘 다에 론치타임 초기화 코드를 작성하라:

 

  • application(_:willFinishLaunchingWithOptions:)
  • application(_:didFinishLaunchingWithOptions:)

UIKit는 앱의 론치 사이클이 시작할 때 이 메서드들을 호출한다. 해당 메서드들을 다음과 같은 용도로 사용하라:

 

  • 앱의 데이터 구조를 초기화하기
  • 앱이 구동해야 할 자원을 가지고 있음을 검증하기
  • 앱이 처음으로 론치될 때 1회의 초기 셋업 작업을 수행하기. 예를 들자면 템플릿이나 유저가 수정할 수 있는 파일을 writable directory에 설치하기
  • 앱 사용에 필수적인 서비스에 연결하기. 예를 들면 앱이 원거리 알림을 지원한다면 Apple Push Notification service에 연결한다.
  • 앱이 왜 론치되었는지에 대한 정보를 확인하기 위해 론치 옵션 딕셔너리를 확인하기

씬에 기반하지 않은 앱들의 경우 UIKit는 론치시에 자동적으로 디폴트 유저 인터페이스를 로딩한다. application(_:didFinishLaunchingWithOptions:) 메서드를 사용하여 해당 인터페이스가 화면에 나타나기 전에 추가 수정 작업을 하라. 예를 들어 유저가 마지막에 앱을 사용했을 때 무엇을 하고 있었는지를 보여주기 위해 다른 뷰 컨트롤러를 설치할 수도 있다.

 

4. 장기적인 태스크를 메인 스레드에서 옮기기

 

유저가 앱을 론치할 때 론치 과정을 빠르게 함으로써 좋은 인상을 줘라. UIKit는 application(_:didFinishLaunchingWithOptions:) 메서드가 리턴하기 전에는 앱의 인터페이스를 보여주지 않는다. 시간이 오래 걸리는 태스크를 application(_:didFinishLaunchingWithOptions:)나 application(_:willFinishLaunchingWithOptions:)에서 수행한다면 유저는 애빙 느리다고 생각할 수 있을 것이다. 앱이 백그라운드로 론치될 때에도 마찬가지로 빠른 리턴이 중요한데, 이는 시스템이 앱의 백그라운드 실행 시간에 제약을 걸기 때문이다.

앱의 초기화에 필수적이지 않은 업무는 론치타임이 아닌 때로 옮겨라. 예를 들면

 

  • 앱이 당장 필요로하지 않는 기능들의 초기화를 뒤로 미루라
  • 중요하고 시간이 오래 걸리는 태스크를 앱의 메인 스레드에서 옮겨라. 예를 들면 이들을 global dispatch queue에서 비동기적으로 구동하라.

5. 앱이 왜 론치되었는지 결정하기

 

UIKit은 앱을 론치할 때 application(_:willFinishLaunchingWithOptions:)와 application(_:didFinishLaunchingWithOptions:) 메서드에 론치 옵션 딕셔너리와 함께 왜 앱이 론치되었는지에 관한 정보 또한 넘긴다. 딕셔너리의 키는 당장 수행해야 하는 중요한 업무들을 나타낸다. 예를 들어 유저가 다른 곳에서 시작했고, 이 앱에서 계속 이어서 하고 싶어하는 액션을 반영할 수도 있다. 항상 예상하는 키에 대한 론치 옵션 딕셔너리의 내용을 확인하고 이에 걸맞은 적절한 응답을 하라.

 

이하는 백그라운드 위치 업데이트를 다루는 앱의 앱 delegate 메서드를 보여준다. 위치 키가 존재할 때 앱은 이를 뒤로 미루지 않고 즉시 위치를 업데이트 한다. 위치 업데이트를 시작하면 코어 로케이션 프레임워크가 새로운 위치 이벤트를 전달할 수 있다.

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 notifications를 지원하지 않는 앱에 대해서는 remoteNotification 키를 포함시키지 않는다.