Entry Point

시원·2022년 2월 26일
0

iOS

목록 보기
1/1
post-thumbnail

진입점(Entry point) 부터 앱 화면이 보이기 직전의 상태까지의 과정에 대해 알아보자.

Entry Point

위 사진에는 표기되지 않았지만 iOS 15이후로는 앱 시작시 Prewarming이라는 과정을 진행할 수 있다고 한다. 지금은 main 함수 호출부터 알아보자.


1. main 함수의 호출 (main())

진입점으로 제일 처음에 실행되는 코드이다.

// main.m
int main(int argc, char * argv[]) {
  @autoreleasepool {
    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
  }
}

Objective-C로 생성된 프로젝트에서는 main.m 파일이 생성되어 위와 같은 내용의 main 함수를 확인 가능하다고 한다.

하지만 Swift 프로젝트에서는 main 함수를 확인할 수 없는데 @UIApplicationMain 또는 @main을 클래스에 작성하면, 시스템이 자동으로 main 함수를 호출한다

@UIApplicationMain // Swift 5.3 이전
class AppDelegate: UIResponder, UIApplicationDelegate {
}

@main // Swift 5.3 이후
class AppDelegate: UIResponder, UIApplicationDelegate {
}

@main // SwiftUI 프로젝트
struct myApp: App {

  var body: some Scene {
    WindowGroup {
      ContentView()
    }
  }
}

@main 를 사용하여 긴 코드가 깔끔하게 한줄로 동일하게 처리 가능하다!

정말 동일하게 처리될까?

Swift 프로젝트를 생성하여 main.swift 라는 파일을 만든다음 아래와 같이 UIApplicationMain 함수를 작성 해보자. 해당 함수를 감싸는 코드 블럭을 작성하지 않는다.(top-level)

// main.swift

// 함수인데 코드 블럭 내부에서 작성되지 않는다..
UIApplicationMain(
  CommandLine.argc,
  CommandLine.unsafeArgv,
  nil,
  NSStringFromClass(AppDelegate.self)
)

작성 이후 빌드를 해보면, 아래와 같이 두가지 에러가 발생한다.

1. top-level 코드가 포함된 모듈에서는 @main을 사용할 수 없다

즉, main.swift 파일 내부에 top-level코드가 이미 모듈에 포함되었기 때문에 @main은 사용하지 못한다.


top-level 코드란?

  • 최상위 수준 선언(top-level declarations):

    최상위 수준에서 선언되어 동일한 모듈에 속한 모든 코드에 접근이 가능하다.
    (개인적으로 자주 사용하는 log 라이브러리 SwiftyBeaver의 log 상수 선언와 같은..)

  • 실행 가능한 최상위 수준 코드(executable top-level code):

    선언 뿐만 아니라 구문과 표현식을 포함하고 있으며, 프로그램에 대해 top-level entry point로만 허용된다.

    • main.swift 파일의 UIApplicationMain과 같은 코드 블럭에 포함되어있지 않은 코드
    • @UIApplication, @main attribute 등

2. 심볼의 중복
duplicate symbol for architecture로 검색해보니 동일한 함수가 중복 로드되었을 때 발생 한다고 한다.

결론적으로 UIApplicationMain의 호출과 @main을 특정 클래스에 작성하는것은 동일하다!


2. UIApplicationMain

main 함수가 실행되면 UIApplicationMain 함수가 실행된다.

func UIApplicationMain(
  // argv의 갯수.
  _ argc: Int32,     
  // 인자의 변수 목록
  _ argv: UnsafeMutablePointer<UnsafeMutablePointer<CChar>?>,
  // UIApllication 클래스 또는 하위 클래스 이름, nil을 지정하면 UIApplication으로 가정
  _ principalClassName: String?,   
  // application delegate가 인스턴스화 되는 클래스 이름
  _ delegateClassName: String? 
) -> Int32

함수가 실행 되면 각 인자의 내용과 같이 UIApplication 및 UIApplicationDelegate 프로토콜을 채택한 클래스의 인스턴스가 생성된다.


3. Load Default Storyboard

info.plist에 설정된 기본 스토리보드 파일이 로드 된다. info.plist에 지정되어 있지 않다면 이 과정은 스킵된다.

  • 참고사항
    Xcode 13 환경에서는 info.plist가 Target -> Info 탭으로 이동 되었다.

https://developer.apple.com/documentation/xcode-release-notes/xcode-13-release-notes


4. First initialization

앱을 초기화 하고 실행을 위한 준비를 진행한다. 기본 storyboard 또는 nib 파일을 로드된 이후 App State Restoration 진행되기 이전에 application(_:willFinishLaunchingWithOptions:) 메서드가 호출 된다.

해당 메서드가 호출될 때 앱은 inactive state 상태이다.

optional func application(
  _ application: UIApplication,
  willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil
) -> Bool
  • application: 싱글턴 앱 객체.
  • launchOptions: 앱 시작의 이유가 있는경우 옵션키가 포함된 딕셔너리. (옵션키 링크 참조)
  • return value:
    • false: 앱이 URL 리소스 또는 사용자 작업을 처리할 수 없거나 홈 스크린의 빠른 작업의 호출을 처리하고 있기 때문에 application(_:performActionFor:completionHandler:)메서드를 수행하지 않아야 하는 경우 반환
    • true: false의 경우가 아닌 경우 반환
    • other: remote notification의 결과로 앱이 시작되면 반환값 무시

5. App state restoration

https://developer.apple.com/documentation/uikit/uiscenedelegate/restoring_your_app_s_state


6. Final initialization

앱 초기화를 완료하고 마지막 수정을 진행한다. App State Restoration이 발생한 이후에 호출되지만 앱의 화면 및 다른 UI가 표시되기 이전에 application(_:didFinishLaunchingWithOptions:) 메서드가 호출된다.

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

이 메서드가 반환된 후 어느 시점에 시스템이 App delegate의 다른 메서드를 호출하여 앱을 active(foreground) 상태 또는 background 상태로 이동.


마무리

아래 플로우에서 Entry Point 부분만 살펴 보았다.

Entry Point 및 App LifeCycle에 대한 순서도와 같은 내용을 애플 Documentation Archive에서 찾지 못했고 다른분들의 정리글에서 출처로 표기된 예전 주소로 들어가면 UIKit 애플 최신문서로 진입되어 볼수가 없어서 답답 했지만 참고자료가 있어서 도움이 되었다.


[포스팅 예정목록]

  • App Life Cycle
  • Attribute
  • Prewarming
  • App state restoration

출처 및 참고

profile
신나고 흥미롭게

0개의 댓글