協(xié)議化的簡單Router

JMRouter

一個輕量級,純Swift,協(xié)議化的路由控件,使用demo

要求

安裝

pod 'JMRouter'

使用

  1. 自定義一個enum,實現(xiàn)JMRoutePage協(xié)議,每個case,表示該controller的唯一路徑
enum Page: String, JMRoutePage {
    case home //key和約定的字符串一致
    case vc1 
    case vc2 = "nibVc" //key和約定的字符串不一致時
}
  1. 想要一個controller支持路由跳轉(zhuǎn),需要實現(xiàn)JMRoutable協(xié)議,比如
extension HomeController: JMRoutable {
    static var routePage: JMRoutePage {
        return Page.home
    }
    
    static func routePageCreated(with url: String?,
                                 parameters: [String: String]?,
                                 object: Any?) -> UIViewController? {
        return UIStoryboard(name: "Main", bundle: nil)
            .instantiateInitialViewController()
    }
}
  1. 可以使用下面2種方式跳轉(zhuǎn),可以帶額外參數(shù),并提供跳轉(zhuǎn)完成回調(diào)
/// 應(yīng)用內(nèi)使用枚舉方式跳轉(zhuǎn)更方便
JMRouter.goto(Page.home, from: self, object: UIColor.random) { resrult, _ in
    YYHud.showTip(resrult ? "操作成功" : "操作失敗")
}
/// 使用url跳轉(zhuǎn)
JMRouter.routing(with: "scheme1://page/home?title="地圖") { resrult, _ in
    YYHud.showTip(resrult ? "操作成功" : "操作失敗")
}

url類似下面這種格式,lastPathComponent為界面,可以帶參數(shù)

/// scheme1://page/map?title="地圖"

routing完整定義如下

/// 通過url 來跳轉(zhuǎn)對應(yīng)頁面, 或執(zhí)行某個action
///
/// - Parameters:
///   - urlString: url字符串
///   - object: 額外的參數(shù)
///   - vc: 優(yōu)先使用傳入的controller來執(zhí)行跳轉(zhuǎn)或action,否則會自動尋找當前的controller
///   - completion: routing完成后的回調(diào)(有動畫會異步),Bool同return的返回值
/// - Returns: 如果找到了對應(yīng)的page并跳轉(zhuǎn)成功,或執(zhí)行了對應(yīng)action,返回true
@discardableResult
public static func routing(with urlString: String,
                          object: Any? = nil,
                          from vc: UIViewController? = nil,
                          completion: Completion? = nil) -> Bool
  1. 在使用前需要調(diào)用一次路由注冊
static func setup(with appDelegate: UIApplicationDelegate,
                  schemes: [String],
                  pageHost: String = "page")

demo中更為詳細的例子,使用前可以先看看

更詳細的說明

設(shè)計思路

分別取url的

  • scheme:表示支持的協(xié)議,可以配置多個
  • host:表示執(zhí)行操作的類型,默認是page,之前還支持action,不過發(fā)現(xiàn)不好單獨提取出來,需要自己支持吧
  • lastPathComponent:表示執(zhí)行的具體操作,比如跳轉(zhuǎn)到地圖頁

這些配置在每個項目中可能都有自己的規(guī)則,所以可以根據(jù)需求自行調(diào)整??

scheme和host定義在JMRouter.swift文件中,通過setup參數(shù)初始化

/// 支持的schemes
public static private(set) var schemes = [""]
public static private(set) var pageHost = "page"

lastPathComponent的Page部分在自己工程中定義,使用枚舉

/// 聲明哪些controller支持路由跳轉(zhuǎn)
enum Page: String, JMRoutePage {
    case home
    case vc1 //key和約定的字符串一致時
    case vc2 = "nibVc" //key和約定的字符串不一致時
}

對于一些UI層次結(jié)構(gòu)比較特殊的項目

還有一個地方可能需要注意

JMRouter+Page.swiftgoto函數(shù)里用來跳轉(zhuǎn)的vc,優(yōu)先使用傳入的vc,否則使用app top

/// 通過枚舉來跳轉(zhuǎn)對應(yīng)頁面
@discardableResult
static func goto(_ page: JMRoutePage,
                 url: String? = nil,
                 parameters: [String : String]? = nil,
                 object: Any? = nil,
                 from vc: UIViewController? = nil,
                 completion: Completion? = nil) -> UIViewController? {
    。。。   
    /// 優(yōu)先使用傳入的vc,否則使用app top
    guard let finalViewController = vc ?? UIViewController.appTopVC else {
        return nil
    }      
    。。。
}

路由映射

JMRouter.setup方法內(nèi)部會調(diào)用registerPathMap,遍歷主工程中所有類,判斷是否實現(xiàn)JMRoutable協(xié)議來自動注冊映射關(guān)系,可能會有點耗時。根據(jù)我們自己項目測試來看,大概幾W個類,1秒內(nèi)完成,所有看情況這步可以優(yōu)化。。

/// 遍歷所有的類,檢測是否實現(xiàn)Routable,存入字典作為映射表,使用Router前必須先調(diào)用
static func registerPathMap(with appDelegate: UIApplicationDelegate) {
    var count: UInt32 = 0
    guard let image = class_getImageName(object_getClass(appDelegate)),
        let classes = objc_copyClassNamesForImage(image, &count) else {
            print("JMRouter registerPathMap failed!!!!!!!!!!!!!!!!!!")
            return
    }

    for i in 0 ..< Int(count) {
        if let clsName = String(cString: classes[i], encoding: .utf8)?.components(separatedBy: ".").last {
            if let cls = clsName.toClass() as? JMRoutable.Type {
                pagePathMap.updateValue(clsName, forKey: cls.routePage.rawValue)
            }
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容