SwifRootViewController 0.4.0

SwifRootViewController 0.4.0

Mihael Isaev 维护。



  • MihaelIsaev

SwifRootViewController

🍀有用的根导航视图控制器(最佳实践)

如何安装

SwifRootViewController 通过 CocoaPods 提供。

要安装它,只需在您的 Podfile 中添加以下行

pod 'SwifRootViewController', '~> 0.1.0'

如何使用

在您的项目中创建一个 RootViewController.swift 文件,并像这样从 SwifRootViewCtonroller 继承

import UIKit
import SwifRootViewController

class RootViewController: SwifRootViewController<DeeplinkType> {
    // may be shown on app launch as initial view controller
    override var splashScreen: UIViewController {
        return SplashViewController() // replace with yours
    }
    
    // where user will be moved on `showLoginScreen`
    override var loginScreen: UIViewController {
        return LoginViewController() // replace with yours
    }
    
    // where user will be moved on `switchToLogout`
    override var logoutScreen: UIViewController {
        return LoginViewController() // replace with yours
    }
    
    // means your main view controller for authorized users
    override var mainScreen: UIViewController {
        return MainViewController() // replace with yours
    }
    
    // shows before main screen
    override var onboardingScreen: UIViewController? {
        // return something here to show it right after authorization
        return nil
    }
    
    // check authorization here and return proper screen
    override var initialScreen: UIViewController {
        return Session.shared.isAuthorized ? splashScreen : loginScreen
    }
    
    // handle deep links here
    override func handleDeepLink(type: DeeplinkType) {
        /// check you deep link in switch/case
        /// and go to the proper view controller
    }
}

如果您现在不想使用深链接,可以使用 SwifRootViewControllerSimple 代替 SwifRootViewController

RootViewController 设置为窗口的 rootViewController
@UIApplicationMain
class AppDelegateBase: UIResponder, UIApplicationDelegate {
  var window: UIWindow?
  
  override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    if super.application(application, didFinishLaunchingWithOptions: launchOptions) {
        // needed to set `RootViewController` aswindow's  `rootViewController`
        RootViewController().attach(to: &window)
        // needed for deep links registration
        // ShortcutParser.shared.registerShortcuts()
        return true
    }
    return false
  }
}

切换屏幕

首先在 AppDelegate 中声明辅助器

extension AppDelegate {
    static var shared: AppDelegate {
        return UIApplication.shared.delegate as! AppDelegate
    }
    
    var rootViewController: RootViewController {
        return window!.rootViewController as! RootViewController
    }
}

然后像这样从任何地方使用它们

AppDelegate.shared.rootViewController.showLoginScreen()
AppDelegate.shared.rootViewController.switchToMainScreen()
AppDelegate.shared.rootViewController.switchToLogout()

深度链接

RootViewController设置为窗口的rootViewController

实现ShortcutParser

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

实现DeepLinkManager

import Foundation
import UIKit

// List your deeplinks in this enum
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
    }
    
    // check existing deepling and perform action
    func checkDeepLink() {
        if let rootViewController = AppDelegate.shared.rootViewController as? RootViewController {
            rootViewController.deeplink = deeplinkType
        }
        
        // reset deeplink after handling
        self.deeplinkType = nil
    }
}

配置AppDelegate

@UIApplicationMain
class AppDelegateBase: UIResponder, UIApplicationDelegate {
  var window: UIWindow?

  override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    if super.application(application, didFinishLaunchingWithOptions: launchOptions) {
        // needed to set `RootViewController` aswindow's  `rootViewController`
        RootViewController().attach(to: &window)
        // needed for deep links registration
        ShortcutParser.shared.registerShortcuts()
        return true
    }
    return false
  }

  override 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))
  }
}