Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[iOS] @UIApplicationMain @main #22

Closed
seungchan2 opened this issue May 9, 2022 · 0 comments
Closed

[iOS] @UIApplicationMain @main #22

seungchan2 opened this issue May 9, 2022 · 0 comments
Assignees
Labels

Comments

@seungchan2
Copy link
Owner

seungchan2 commented May 9, 2022

프로젝트를 생성하면 기본적으로 생성되는 것들이 있음

그 중 하나가 AppDelegate, SceneDelegate가 있음. 다들 많이 보셨죠?

그 중 AppDelegate에 들어가보면 import UIKIt 밑에 @main이라고 있을 거임

스크린샷 2022-05-09 오후 10 15 57

앱의 시작되는 진입점, 앱의 런루프를 생성함. 굉장히 중요한 역할을 하는 놈임

만약 @main을 지우고 빌드한다면 당연히 에러가 발생할 거임
스크린샷 2022-05-09 오후 10 18 28

왜냐하면 entry point 즉 진입점을 찾을 수 없어서 에러가 발생하는거임

그럼 지금부터 @main에 대해 자세히 살펴보겠음

사실 위에서 말했던 내용이 다 이긴한데

AppDelegate에서 전역범위에 있는 코드를 자동으로 인식하게 하고 Entry Point를 지정함

간단한 예시를 들자면 FirebaseMessaging 설정을 AppDelegate에서 해주니까 background, foreground에서 자유롭게 푸시알림이 옴

Xcode 12 이전 버전에서는 @UIApplicationMain으로 되어 있었고 Xcode 12 부터 @main으로 바뀜 ㅇㅇ.

@UIApplicationMain

앱의 본체에 해당하는 객체인 UIApplicaion객체를 생성하고 앱의 Life Cycle을 관리

지정된 클래스 (@UIApllicationMain이 표시된) 에서 델리게이트를 인스턴스화하고, 이를 앱의 객체에 할당

@UIApplicationMain 어노테이션은 UIApplicationMain 함수를 호출하는데, 이 함수는 App의 핵심 객체 구현과 App 구동 플로우에서 중요한 역할을 수행

@main

@main은 프로그램 실행 시작 시 진입점으로 타입을 지정하기 위한 Swift 언어의 기능

사용자는 탑 레벨의 코드를 작성하는 대신 @main 단일 유형의 속성을 사용할 수 있음

라이브러리와 프레임워크는 프로토콜이나 클래스 상속을 통해 맞춤형 진입점 동작을 제공할 수 있음

탑 레벨 코드

Swift 소스 파일 안에서 탑 레벨 코드는 0개 이상의 선언이나 정의 그리고 표현식으로 구성이 됨

기본적으로 소스파일의 탑 레벨에서 선언된 것들은 같은 모듈 내의 모든 소스파일에서 접근 가능

탑 레벨 코드에는 선언문과 실행 구문 두 가지가 있음

선언문 (top-level declarations)

모든 Swift Source File에서 사용이 가능

변수, 함수 등의 선언문은 전역으로 얼마든지 선언이 가능하며 같은 모듈 내에서 자유롭게 접근 가능

실행문 (excutable top-level code)

선언을 제외한 모든 구문을 의미

실행문은 Top-Level Entry Point에서만 사용이 가능

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        
        // firebase 연동
        FirebaseApp.configure()
        
        // push notification 권한 요청하기
        UNUserNotificationCenter.current().delegate = self
        Messaging.messaging().delegate = self
        
        let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
        UNUserNotificationCenter
            .current()
            .requestAuthorization(
                options: authOptions,completionHandler: { (_, _) in }
            )
        application.registerForRemoteNotifications()
        
        // 키보드 내려가는 현상 방지
        IQKeyboardManager.shared.enable = true
        IQKeyboardManager.shared.enableAutoToolbar = false
        IQKeyboardManager.shared.shouldResignOnTouchOutside = true
        
        // custom font load
        FontBlaster.blast()
        
        // 카카오 로그인
        KakaoSDKCommon.initSDK(appKey: "")
        return true
    }

그럼 왜 @UIApplicationMain 대신 @main을 사용하게 된 것인가?

초기 Swift에서 앱 실행은 UIApplication모든 단일 iOS 앱에 대해 동일한 프로세스인 인스턴스를 실행하고 유지 관리하는 데 의존

부팅의 이 초기 프로세스는 UIApplicationUIKit에 의해 추상화되며, 특히 이것이 앱이 가장 먼저 해야 할 일이라는 점을 고려하면 사용자가 이에 대해 걱정할 이유가 없었음ㅇㅇ

하지만 이러한 이유로 사용자에 대한 이러한 책임을 처리하는 것이 부정적인 결과를 초래할 수 있다고 합니다.

이 문제가 발생하지 않도록 Apple은 UIKit이 iOS 앱을 부팅 코드를 제공하는 책임이 있다면 Swift 자체에서 해결을 해야 한다고 생각을 했고

Swift 컴파일러는 두 가지 새로운 특수 속성인 @UIApplicationMain 및 @NSApplicationMain을 지원하기 시작함

Swift CLI 도구를 위한 많은 프레임워크는 일종의 초기 설정을 포함하므로 언어가 현재 하드코딩된 것을 복제하는 표준 방법을 제공하는 것이 @UIApplicationMain입니다.

근데 이렇게 조금 길고 직관적이지 않은 코드를 사용하기 보단 @main 과 같은 더 일반적이고 가벼운 메커니즘을 제공하는 것이 더 이상적이라고 생각해서 만들었다고 함.

마지막으로 Swift 5.3 @main에서는 개발자가 이 동작을 제어할 수 있도록 속성이 추가되었다고 함.

정리

@UIApplicationMain 대신 @main을 사용함으로 타입 기반의 스위프트 코드에서 이상적인 진입점을 알려주며 main() 함수는 일반 정적 메서드이므로 프로토콜에서 확장 메서드 또는 기본 클래스로 제공 할 수 있다. -> 자유롭게 Entry Point 지정 가능!

클래스나 구조체에 @main이 명시된 경우라면 static func main() 메서드가 실제 진입점이 된다! -> 자유롭게 Entry Point 지정 가능!

@main, @UIApplicationMain, 및 @NSApplicationMain는 컴파일러가 애플리케이션의 진입점을 합성하고 "main.swift" 파일이 필요 없도록 하는 속성!

@seungchan2 seungchan2 self-assigned this May 9, 2022
@seungchan2 seungchan2 added the iOS label May 9, 2022
@seungchan2 seungchan2 changed the title [iOS] UIApplication @main [iOS] @UIApplicationMain @main May 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant