[iOS] Responding to the launch of App

Hyunndy·2023년 2월 18일
0

iOS-App-Structure

목록 보기
2/8
post-custom-banner

🐸

지난번 App Life Cycle에 대해 정리했는데요.
이번 글에는 Responding to the launch of your app 을 학습해보겠습니다.

App이 실행되고 LaunchScreen이 보이고, UI가 보이기 까지
App의 Data Structure을 초기화하고, App을 실행시킬 준비를 하고, 시스템을 통한 launch-time request에 응답하는 내용을 담고 있습니다.


개요

App이 launch되는 시점에 App의 Data Structure을 초기화하고, 실행할 App을 준비하고, system으로 부터의 request에 응답합니다.

사용자가 App의 아이콘을 터치하면 시스템은 App을 launch 합니다.
만일 App이 특정 이벤트를 요청받았다면, 시스템은 이벤트를 처리하기 위해 백그라운드로 App을 launch 합니다.

👩‍💻 이게 무슨 경우?
알람앱 같은 경우를 생각해보면, 내가 앱을 종료 시켰어도 알람 맞춘 시간에 알람이 울립니다.
어쨋든 알람이 울리기 때문에 시스템이 이 앱을 깨워준거고, Background에서 깨워준겁니다.

모든 App은 UIApplication객체가 연결하는 프로세스가 있습니다.

또한 App에는 해당 프로세스 내에서 발생하는 중요한 Event에 응답하는 UIApplicationDelegate 프로토콜을 준수하는 AppDelegate 객체가 있습니다.
Scene기반 App도 launch나 terminate는 App Delegate를 이용합니다.

앱의 실행과정

App이 launch 되면
1. UIKit은 자동으로 UIApplication 객체와 App Delegate 객체를 생성합니다.
2. nib파일을 사용하는 경우나, Info.plist 파일을 읽어들여 파일에 기록된 정보를 참고하여 그외에 필요한 데이터를 로드한다.
3. UIApplication 객체와 App Delegate 객체를 연결하고 App의 Main Event loop를 만드는 등 실행에 필요한 준비를 합니다.
4. 실행 완료를 앞두고 UIApplication 객체가 App Delegate에 application:didFinishLaunchingWithOptions: 메세지를 보냅니다.

👩‍💻 참고) Entry Point
AppDelegate 객체는 App의 Entry Point 입니다.
Swift 프로젝트에는 왜 C++ 같은 main() 함수가 없는걸까요?
이유는 UIKit 프레임워크에 숨어있기 때문입니다.

Swift 컴파일러는 @Main 어노테이션을 통해 AppDelegate에서 전역 범위에 있는 코드를 자동으로 인식하게 하고 실행시켜 AppDelegate가 App의 Entry Point가 되게 합니다.

@main
class AppDelegate: UIResponder, UIApplicationDelegate { ... }

Provide a launch storyboard

App을 실행하면 System은 App이 UI를 display할 준비가 될 때 가지 launchStoryboard를 보여줍니다.
splash 화면을 보여주면 사용자에게 App이 실행되었고, 뭔가 하려고 한다는걸 알게할 수 있습니다.
만약 App이 초기화와 UI 준비를 빨리 마쳤다면, 유저는 splash화면을 아주 잠깐만 볼 것입니다.

launchScreen에 static 이미지를 쓰지마세요. iOS14부터는 25MB 제한이 걸렸습니다.

Initailize your app's data structure

App launch Time에 초기화가 필요한 코드는 다음 두 delegate 함수에 작성합니다.

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { ... }
    
    func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { ... } 

UIKit은 이 메서드들을 App의 launch Cycle의 시작에 호출합니다.
이 함수에 다음과 같은 것들을 정의하세요.

  • App의 Data Structure 초기화
  • 실행할 리소스가 있는지 확인
  • one-time setup을 수행하세요.
    • 예를들면, template 인스톨이나 writable dirctory의 user-modifiable 같은거(?)
    • 참고
  • 앱이 사용하는 중요 서비스를 연결
    • Ex) APNs
  • 앱이 어떻게 launch되었는지 정보를 확인하세요. Push로 켜졌는지? 등

👩‍💻 구체적인 예시를 들어보자면...
타 회사 서비스 사용 시 초기화(Kakao SDK, FireBase, 결제 모듈 등..)
Push로 실행되었는지 체크하고, 그에 맞는 이벤트 정의
내부 캐시 정책 초기화
Singletone 변수 초기화

Move long-running tasks off the main thread

당연하게도 여기에 느린 작업을 넣어두면 App launch 시간에 영향을 줄테니 피하는게 좋습니다.
당장 초기화 해야될게 아니면 미루고, 너무 중요하다면 Mian Thread에서 제거하세요.
Global Dispatch Queue에서 Async하게 동작하게 하면 되겠군요~

Determine why your app launched

앱이 launch 될 때 UIKit은 앱이 실행된 이유에 대한 정보를 위 함수들의 launchOptions 딕셔너리에 전달합니다.

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { ... }
    
    func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { ... } 

이 딕셔너리의 Key엔 당장 수행해야할 중요한 task가 들어있는데요.
예를들면...
사용자의 위치정보가 중요한 앱이라고 할 때 백그라운드에서 계속 위치 업데이트를 처리했다면, 앱이 시작할 때 새로운 위치 정보를 받아올 수 있습니다.

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

시스템이 사용자가 설정하지 않은 기능까지 Key를 제공하진 않습니다.
예를 들면
App이 Remote Notificiation을 지원한다고 설정하지 않았으면 remoteNotification 에 관한 Keys는 오지 않습니다.

profile
https://hyunndyblog.tistory.com/163 티스토리에서 이사 중
post-custom-banner

0개의 댓글