oc & swift混編下的路由實踐

前言:

現(xiàn)在有很多第三方路由庫从撼,例如:

1.JLRoute
2.MGJRouter
3.HHRouter
4.FFRouter

等等這些優(yōu)秀的第三方庫差不多都能滿足路由的基本功能

應(yīng)用:

以JLRoute為例:

先注冊一個路由

JLRoutes.global().addRoute("/ViewController1") { (param:[String : Any]) -> Bool in
    let viewController1 = ViewController1.init()
    pushClassStance.pushViewController(viewController1, animated: true)
    return true
}

然后跳轉(zhuǎn)

let url:URL = URL.init(string: "XIAOGUO://ViewController1")!
JLRoutes.routeURL(url)

一個簡單的路由跳轉(zhuǎn)就實現(xiàn)了胆筒,當然如果是單純的跳轉(zhuǎn)到指定頁面還是比較好處理的。

那么這里就會延伸出兩個問題
1邻吞、如果頁面需要傳參該怎么做?
2葫男、ViewController需要提前注冊抱冷,如果沒有注冊的頁面就沒辦法做跳轉(zhuǎn),能否做動態(tài)注冊梢褐?

先看第一個問題旺遮,JLRoute其實已經(jīng)提供了帶參數(shù)的傳遞方式:

let url:URL = URL.init(string: "XIAOGUO://ViewController1/userName/xiaoguo/password/123456/isLogin/1")!
JLRoutes.routeURL(url)

那么我們?nèi)绾螌⒙酚傻膮?shù)與頁面的參數(shù)做對應(yīng)呢?

JLRoutes.global().addRoute("/ViewController1/userName/:userName/password/:password/isLogin/:isLogin") { (param:[String : Any]) -> Bool in
    let viewController1 = ViewController1.init()
    viewController1.userName = param["userName"] as! String
    viewController1.password = Int(param["password"] as! String) ?? 0
    viewController1.isLogin = (param["isLogin"] as! NSString).boolValue
    pushClassStance.pushViewController(viewController1, animated: true)
    return true
}

看起來似乎可以處理參數(shù)問題盈咳,仔細考慮一下如果參數(shù)沒有提前注冊好或者漏掉一些參數(shù)那還是無法實現(xiàn)正常傳參耿眉,能否實現(xiàn)動態(tài)傳參呢?

如果是swift類注冊路由鱼响,傳參我們可以利用反射來做類的屬性的映射:

 JLRoutes.global().addRoute("/:ViewController") { (param:[String : Any]) -> Bool in
    let vcName = param["ViewController"] as? String ?? ""
    //根據(jù)vcName獲取對應(yīng)的控制器
    if let clz = NSClassFromString("\(kCFBundle).\(vcName)") as? UIViewController.Type {
        let vc:UIViewController = clz.init()
        //反射控制器屬性
        let vcM = Mirror(reflecting: vc)
        //過濾參數(shù)關(guān)鍵字
        let filterParam = param.filter({ (arg0) -> Bool in
            let (key, _) = arg0
            return key != "JLRoutePattern" && key != "JLRouteURL" && key != "JLRouteScheme" && key != "ViewController"
        })
        //找到對應(yīng)的控制器屬性并賦值
        for (key,value) in filterParam {
            for child in vcM.children {
                if key == child.label {
                    //print("key:\(key),child.label:\(String(describing: child.label))")
                    vc.setValue(value, forKey: key)
                }
            }
        }
        pushClassStance.pushViewController(vc, animated: true)
        return true
    }
    return false
}

發(fā)起跳轉(zhuǎn)統(tǒng)一用標準url傳參方式(鸣剪?&):

let url:URL = URL.init(string: "XIAOGUO://VC3?userName=xiaoguo&password=123456&isLogin=1")!
JLRoutes.routeURL(url)

這樣就完成動態(tài)傳參的問題。

這里會發(fā)現(xiàn)通過反射只能在swift頁面內(nèi)部之間跳轉(zhuǎn),如果跳轉(zhuǎn)的頁面是oc頁面則反射不到對應(yīng)的屬性筐骇,那要如何處理呢债鸡?

只能通過Runtime的class_copyPropertyList 或class_copyIvarList獲取類的屬性(swift屬性必須聲明為@objc賦予動態(tài)性)

改成class_copyPropertyList方式:

JLRoutes.global().addRoute("/:ViewController") { (param:[String : Any]) -> Bool in
            let vcName = param["ViewController"] as? String ?? ""
            //oc類
            let ocClz = NSClassFromString("\(vcName)") as? UIViewController.Type
            //swift類
            let swfClz = NSClassFromString("\(kCFBundle).\(vcName)") as? UIViewController.Type
            //根據(jù)vcName獲取對應(yīng)的類(oc/swift)
            if let clz = ocClz ?? swfClz {
                //過濾參數(shù)關(guān)鍵字
                let filterParam = param.filter({ (arg0) -> Bool in
                    let (key, _) = arg0
                    return key != "JLRoutePattern" && key != "JLRouteURL" && key != "JLRouteScheme" && key != "ViewController"
                })
                let vc:UIViewController = clz.init()
                //Runtime獲取類屬性
                var count:UInt32 = 0
                let propertyList = class_copyPropertyList(clz, &count)
                //找到對應(yīng)的類屬性并賦值
                for (key,value) in filterParam {
                    print("key:\(key),value:\(value)")
                    for i in 0..<numericCast(count) {
                        let property = property_getName((propertyList?[i])!);
                        let proper = String.init(cString: property)
                        if key == proper {
                            vc.setValue(value, forKey: key)
                        }
                    }
                }
                //釋放內(nèi)存
                free(propertyList)
                pushClassStance.pushViewController(vc, animated: true)
                return true
            }
            return false
        }

這樣就可以兼容oc頁面的傳參了


完整Demo:
https://github.com/sg369326973/routerTest/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市铛纬,隨后出現(xiàn)的幾起案子娘锁,更是在濱河造成了極大的恐慌,老刑警劉巖饺鹃,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件莫秆,死亡現(xiàn)場離奇詭異,居然都是意外死亡悔详,警方通過查閱死者的電腦和手機镊屎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來茄螃,“玉大人缝驳,你說我怎么就攤上這事」椴裕” “怎么了用狱?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長拼弃。 經(jīng)常有香客問我夏伊,道長,這世上最難降的妖魔是什么吻氧? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任溺忧,我火速辦了婚禮,結(jié)果婚禮上盯孙,老公的妹妹穿的比我還像新娘鲁森。我一直安慰自己,他們只是感情好振惰,可當我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布歌溉。 她就那樣靜靜地躺著,像睡著了一般骑晶。 火紅的嫁衣襯著肌膚如雪痛垛。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天透罢,我揣著相機與錄音榜晦,去河邊找鬼。 笑死羽圃,一個胖子當著我的面吹牛乾胶,可吹牛的內(nèi)容都是我干的抖剿。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼识窿,長吁一口氣:“原來是場噩夢啊……” “哼斩郎!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起喻频,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤缩宜,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后甥温,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體锻煌,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年姻蚓,在試婚紗的時候發(fā)現(xiàn)自己被綠了宋梧。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡狰挡,死狀恐怖捂龄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情加叁,我是刑警寧澤倦沧,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站它匕,受9級特大地震影響展融,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜超凳,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一愈污、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧轮傍,春花似錦、人聲如沸首装。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽仙逻。三九已至驰吓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間系奉,已是汗流浹背檬贰。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留缺亮,地道東北人翁涤。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親葵礼。 傳聞我的和親對象是個殘疾皇子号阿,可洞房花燭夜當晚...
    茶點故事閱讀 44,927評論 2 355