ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • UIKitPlus - RootViewController
    Library 2021. 6. 23. 12:40

    안녕하세요. 그린입니다🟢

    이번 포스팅에서는 UIKitPlus에서 RootViewController에 대해 학습해보겠습니다🧑🏻‍💻

     

    RootViewController?

    루트 네비게이션 뷰 컨트롤러의 호출과 사용법에 대해 어떻게 구성되는지 단계별로 알아보겠습니다.

     

    1. RootViewController 파일 생성 및 정의

     - RootViewController.swift 파일을 생성하고 RootController<DeeplinkType>을 아래와 같이 상속하여 필요 기능을 정의

    import UIKitPlus
    
    class RootViewController: SwifRootViewController<DeeplinkType> {
        // 앱 시작시 초기 뷰 컨트롤러 표시
        override var splashScreen: UIViewController {
            SplashViewController() // 정의 가능
        }
        // showLoginScreen에서 사용자가 이동할 위치
        override var loginScreen: UIViewController {
            LoginViewController() // 정의 가능
        }
        // switchToLogout에서 사용자가 이동할 위치
        override var logoutScreen: UIViewController {
            LoginViewController() // 정의 가능
        }
        // 인증된 사용자에게 보여줄 메인 뷰 컨트롤러
        override var mainScreen: UIViewController {
            MainViewController() // 정의 가능
        }
        // 메인 뷰 앞에 표시
        override var onboardingScreen: UIViewController? {
            // 반환하여 승인 직후 표시
            nil
        }
        // 승인 확인 후 적절한 화면 반환
        override var initialScreen: UIViewController {
            Session.shared.isAuthorized ? splashScreen : loginScreen
        }
        // 딥링크 처리
        override func handleDeepLink(type: DeeplinkType) {
            /// 딥링크를 다룰 스위치/케이스 조건에 따라 딥 링크 확인
            /// 맞는 뷰 컨트롤러로 이동 구현
        }
    }

    2. window의 RootController 세팅 (AppDelegate)

    @UIApplicationMain
    class AppDelegateBase: UIResponder, UIApplicationDelegate {
        var window: UIWindow?
    
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
            if #available(iOS 13.0, *) {
                // use scene delegate
            } else {
                window = UIWindow(frame: UIScreen.main.bounds)
                RootViewController().attach(to: window)
            }
            ShortcutParser.shared.registerShortcuts()
            return true
        }
    }

    3. SceneDelegate 설정

    @available(iOS 13.0, *)
    class SceneDelegate: UIResponder, UIWindowSceneDelegate {
        var window: UIWindow?
    
        func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
            guard let _ = (scene as? UIWindowScene) else { return }
            window = RootViewController().attach(to: scene)
        }
    }

    4. 화면전환

     - UIView, UIViewController, UIApplicationDelegate에서 설정한 RootViewController를 호출할 수 있음

    rootController.switch(to: .login, animation: .none)
    rootController.switch(to: .main, animation: .fade)
    rootController.switch(to: .logout, animation: .dismiss)

    Deep Link 설정

    import Foundation
    import UIKit
    
    enum ShortcutKey: String {
        case activity = "com.yourapp.activity"
        case messages = "com.yourapp.messages"
    }
    
    class ShortcutParser {
        static let shared = ShortcutParser()
        private init() { }
    
        func registerShortcuts() {
            let activityIcon = UIApplicationShortcutIcon(type: .invitation)
            let activityShortcutItem = UIApplicationShortcutItem(type: ShortcutKey.activity.rawValue, localizedTitle: "Recent Activity", localizedSubtitle: nil, icon: activityIcon, userInfo: nil)
    
            let messageIcon = UIApplicationShortcutIcon(type: .message)
            let messageShortcutItem = UIApplicationShortcutItem(type: ShortcutKey.messages.rawValue, localizedTitle: "Messages", localizedSubtitle: nil, icon: messageIcon, userInfo: nil)
    
            UIApplication.shared.shortcutItems = [activityShortcutItem, messageShortcutItem]
        }
    
        func handleShortcut(_ shortcut: UIApplicationShortcutItem) -> DeeplinkType? {
            switch shortcut.type {
            case ShortcutKey.activity.rawValue:
                return  .activity
            case ShortcutKey.messages.rawValue:
                return  .messages
            default:
                return nil
            }
        }
    }

    Deep Link Manager 설정

    import UIKitPlus
    
    // 딥링크 열거 타입 설정
    enum DeeplinkType {
        case messages
        case activity
    }
    
    let Deeplinker = DeepLinkManager()
    class DeepLinkManager {
        fileprivate init() {}
    
        private var deeplinkType: DeeplinkType?
    
        @discardableResult
        func handleShortcut(item: UIApplicationShortcutItem) -> Bool {
            deeplinkType = ShortcutParser.shared.handleShortcut(item)
            return deeplinkType != nil
        }
    
        // 기존 딥링크를 확인 후 작업 수행
        func checkDeepLink() {
            if let rootViewController = AppDelegate.shared.rootViewController as? RootViewController {
                rootViewController.deeplink = deeplinkType
            }
    
            // 작업 처리 후 딥링크 재설정
            self.deeplinkType = nil
        }
    }

    AppDelegate 및 위와 같은 SceneDelegate 설정

    @UIApplicationMain
    class AppDelegateBase: UIResponder, UIApplicationDelegate {
        var window: UIWindow?
    
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
            if #available(iOS 13.0, *) {
                // SceneDelegate 사용
            } else {
                window = UIWindow(frame: UIScreen.main.bounds)
                RootViewController().attach(to: window)
            }
            ShortcutParser.shared.registerShortcuts()
            return true
        }
        func applicationDidBecomeActive(_ application: UIApplication) {
            super.applicationDidBecomeActive(application)
            Deeplinker.checkDeepLink()
        }
        
        // MARK: Shortcuts
        func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
            completionHandler(Deeplinker.handleShortcut(item: shortcutItem))
        }
    
        // MARK: UISceneSession Lifecycle
        @available(iOS 13.0, *)
        func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
            UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
        }
    
        @available(iOS 13.0, *)
        func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {}
    }

     

    [참고자료]

    https://github.com/MihaelIsaev/UIKitPlus

    https://github.com/MihaelIsaev/UIKitPlus/blob/master/Docs/RootViewController.md

    'Library' 카테고리의 다른 글

    NaverMap SDK - 경로선 & 화살표  (0) 2021.08.13
    UIKitPlus - View  (0) 2021.06.26
    UIKitPlus - Constraints  (0) 2021.06.19
    ReactorKit  (0) 2021.06.16
    UIKitPlus  (0) 2021.06.14
Designed by Tistory.