V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
neverfall
V2EX  ›  iOS

用 Swift 写了一个路由组件, 可以做组件化解耦的中心路由控制

  •  
  •   neverfall · 2020-05-24 20:17:42 +08:00 · 2236 次点击
    这是一个创建于 1425 天前的主题,其中的信息可能已经有所发展或是发生改变。

    FBRouter

    [地址[( https://github.com/swift-assembly/FBRouter).

    Swift CocoaPods Build Status CodeCov registe-w300 安装

    CocoaPods

    1. 在 Podfile 中添加 pod 'FBRouter'
    2. 执行 pod installpod update
    3. 导入 import FBRouter 。

    API

    regist routerhHost 注册路由组件的 host

    public func registURLMapping(urlmappings:Dictionary<String,String>)
    public static func registURLMapping(urlmappings:Dictionary<String,String>)
    

    set scheme appScheme 注册应用的 scheme

    	public static func setScheme(scheme: String) 
    	public func setScheme(scheme: String) 
    
    

    set wrapNavClass

    public static func setWrapNavgClass(className: AnyClass)
    

    FBURLAction

    //init 
    	public convenience init(url:URL)
    public convenience init(urlString:String)    
    public convenience init(host:String)
    public convenience init( httpUrl:String?)
    
    
    // set params
    public func setInteger(_ key:String, value:NSInteger) 
    
    public func setInt(_ key:String, value:Int)  }
    public func setDouble(_ key:String, value:Double)  
    public func setString(_ key:String, value:String)
    public func setBool(_ key:String, value:Bool)
    public func setAny(_ key:String, value:Any) 
    public func addEntriesFromDictonary(entries:Dictionary<String, Any>)
    public func addParamsFromURLAction(urlAction:FBURLAction)
    
    // query param
    public func integer(_ key:String) -> NSInteger? 
    public func int(_ key:String) -> Int? 
    public func double(_ key:String) -> Double?
    public func string(_ key:String) -> String? 
    public func bool(_ key:String) -> Bool?
    public func anyObject(_ key:String) -> Any?
    
    

    UIViewController Extension

    @discardableResult
    func openURLAction(_ urlAction:FBURLAction) -> UIViewController? 
    
    @discardableResult
    func openHostString(host:String) -> UIViewController? 
    
    @discardableResult
    func openURL(url:URL) -> UIViewController? 
    
    @discardableResult
    func openURLString(urlString:String) -> UIViewController? 
    
    @discardableResult
    func openHttpURLString( httpUrl:String) -> UIViewController?
    
    

    FBRouter Method

    @discardableResult
    public func openURL(url:URL,from:UIViewController) -> UIViewController? {
        return openURLAction(FBURLAction.init(url: url), from: from)
    }
    
    @discardableResult
    public func openURLString(urlString:String,from:UIViewController) -> UIViewController? {
        return openURLAction(FBURLAction.init(urlString: urlString), from: from)
    }
    @discardableResult
    public func openHttpURLString( httpUrl:String,from:UIViewController) -> UIViewController? {
        return openURLAction(FBURLAction.init( httpUrl: httpUrl), from: from)
    }
    
    @discardableResult
    public func openHost(host:String,from:UIViewController) -> UIViewController? {
        return openURLAction(FBURLAction.init(host: host),from: from)
    }
    
    @discardableResult
    public func openHost(host:String) -> UIViewController? {
        return openURLAction(FBURLAction.init(host: host))
    }
    
    @discardableResult
    public func openURL(url:URL) -> UIViewController? {
        return openURLAction(FBURLAction.init(url: url))
    }
    
    @discardableResult
    public func openURLString(urlString:String) -> UIViewController? {
        return openURLAction(FBURLAction.init(urlString: urlString))
    }
    
    @discardableResult
    public func openHttpURLString( httpUrl:String) -> UIViewController? {
        return openURLAction(FBURLAction.init( httpUrl: httpUrl))
    }
    
    @discardableResult
    public static func openURLAction(_ urlAction:FBURLAction) -> UIViewController? {
        return FBRouter.router().openURLAction(urlAction)
    }
    
    @discardableResult
    public static func openURLAction(_ urlAction:FBURLAction,from:UIViewController?) -> UIViewController? {
        return FBRouter.router().openURLAction(urlAction,from: from)
    }
    
    
    @discardableResult
    public static func openURL(url:URL,from:UIViewController) -> UIViewController? {
        return openURLAction(FBURLAction.init(url: url), from: from)
    }
    
    @discardableResult
    public static func openURLString(urlString:String,from:UIViewController) -> UIViewController? {
        return openURLAction(FBURLAction.init(urlString: urlString), from: from)
    }
    
    @discardableResult
    public static func openHttpURLString( httpUrl:String,from:UIViewController) -> UIViewController? {
        return openURLAction(FBURLAction.init( httpUrl: httpUrl), from: from)
    }
    
    @discardableResult
    public static func openHost(host:String,from:UIViewController) -> UIViewController? {
        return openURLAction(FBURLAction.init(host: host),from: from)
    }
    
    @discardableResult
    public static func openHost(host:String) -> UIViewController? {
        return openURLAction(FBURLAction.init(host: host))
    }
    
    @discardableResult
    public static func openURL(url:URL) -> UIViewController? {
        return openURLAction(FBURLAction.init(url: url))
    }
    
    @discardableResult
    public static func openURLString(urlString:String) -> UIViewController? {
        return openURLAction(FBURLAction.init(urlString: urlString))
    }
    
    @discardableResult
    public static func openHttpURLString( httpUrl:String) -> UIViewController? {
        return openURLAction(FBURLAction.init( httpUrl: httpUrl))
    }
    

    FBRouterDelegate

    func shouldOpenURLAction(_ urlAction:FBURLAction) -> Bool
    func willOpenExternal(_ urlAction:FBURLAction) -> Bool
    func didOpenExternal(_ urlAction:FBURLAction,success:Bool)
    func willOpenURLAction(_ urlAction:FBURLAction)
    func onMatchUnhandledURLAction(_ urlAction:FBURLAction)
    func onMatchViewController(_ controller:UIViewController,urlAction:FBURLAction)
    func openExternal(_ urlAction:FBURLAction, completionHandler completion: ((Bool) -> Void)?)
    func handleLoginAction(_ urlAction:FBURLAction,controller:UIViewController) -> Bool
    
    

    Usage

    delegate & register

    ///
    class AppDelegate: UIResponder, UIApplicationDelegate,FBRouterDelegate{
    	.....
    	func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    		//delegate
    		FBRouter.router().deleage = self
    		registerURLMappings()
    	}
    	
    }
    
    func registerURLMappings() {
    	let urlMappings = ["home":"ListViewController",
    					   "vc00":"ViewController",
    					   "vc01":"ViewController01",
    					   "vc02":"ViewController02",
    					   "vc03":"ViewController03",
    					   "vc04":"ViewController04",
    					   "vc05":"ViewController05",
    					   "demo":"ViewControllerDemo"]
        FBRouter.router().registURLMapping(urlmappings: urlMappings)
    	FBRouter.router().wrapNavgClass = BaseNavigationController.self as UINavigationController.Type
    }
    
    
    //FBRouterDelegate
    func shouldOpenURLAction(_ urlAction: FBURLAction) -> Bool {
    	return true
    }
    
    func willOpenExternal(_ urlAction: FBURLAction) -> Bool {
    	return true
    }
    
    func didOpenExternal(_ urlAction: FBURLAction, success: Bool) {
    	
    }
    
    func willOpenURLAction(_ urlAction: FBURLAction) {
    	
    }
    
    func onMatchUnhandledURLAction(_ urlAction: FBURLAction) {
    	
    }
    
    func onMatchViewController(_ controller: UIViewController, urlAction: FBURLAction) {
    	
    }
    
    func openExternal(_ urlAction: FBURLAction, completionHandler completion: ((Bool) -> Void)?) {
    	UIApplication.shared.open(urlAction.url!, options: [:], completionHandler:{
            (success) in
            guard let complete = urlAction.completeBlock else{
                return
            }
            complete(success)
        })
    }
    
    func handleLoginAction(_ urlAction: FBURLAction, controller: UIViewController) -> Bool {
    	return true
    }
    
    
    
    
    

    router regist

    let urlMappings = ["home":"ListViewController",
    				   "vc00":"ViewController",
    				   "vc01":"ViewController01",
    				   "vc02":"ViewController02",
    				   "vc03":"ViewController03",
    				   "vc04":"ViewController04",
    				   "vc05":"ViewController05",
    				   "demo":"ViewControllerDemo"]
    FBRouter.router().registURLMapping(urlmappings: urlMappings)
    FBRouter.router().wrapNavgClass = BaseNavigationController.self as UINavigationController.Type
    

    push

    //use FBURLAction transform data
    let urlAction = FBURLAction.init(host: "vc01?a=b")
    urlAction.completeBlock = {
    	(succes) in
    	print("succes:",urlAction.url!)
    }
    urlAction.isSingleton = true
    urlAction.setBool("Bool", value: true)
    urlAction.setString("String", value: "String")
    urlAction.setDouble("Double", value: 2.0202)
    urlAction.setInteger("Integer", value: 101)
    let person:Person = Person.init()
    person.age = 18
    person.name = "nini"
    urlAction.setAny("person", value: person)
    FBRouter.router().openURLAction(urlAction,from: self)
    
    -----------------
    //use UIViewController Extension
    
    let urlAction = FBURLAction.init(host: "vc02?a=b")
    urlAction.completeBlock = {
    	(succes) in
    	print("succes:",urlAction.url!)
    }
    openURLAction(urlAction)
    
    

    系统要求

    swift 5.0 该项目最低支持 iOS 10.0Xcode 11.0

    许可证

    FBRouter 使用 MIT 许可证,详情见 LICENSE 文件。

    第 1 条附言  ·  2022-02-24 14:30:05 +08:00

    https://github.com/flywithbug/HBRouter 重构了一版,因公司需要 api和包名有变动

    HBRouter

    image

    7 条回复    2020-05-26 21:26:45 +08:00
    GromHellscream
        1
    GromHellscream  
       2020-05-25 23:08:43 +08:00
    牛逼,但 iOS 新手想问下,这个“路由组件”的实际应用场景是啥?看 demo 没太看明白,就是方便 push/present viewcontroller ?
    GromHellscream
        2
    GromHellscream  
       2020-05-25 23:09:13 +08:00
    Star 学习一下
    xayoung
        3
    xayoung  
       2020-05-26 11:52:58 +08:00
    @GromHellscream lz 标题写了啊,应用场景就是组件化解耦。或者举个更实际更常用的例子,假设 app 的推送需要跳转的页面非常多,使用这类组件就很方便了
    neverfall
        4
    neverfall  
    OP
       2020-05-26 16:23:14 +08:00
    @xayoung 👍
    neverfall
        5
    neverfall  
    OP
       2020-05-26 16:24:06 +08:00
    demo 里有演示,如有问题,可以提 issue 也可以直接这里 @我
    neverfall
        6
    neverfall  
    OP
       2020-05-26 16:26:14 +08:00
    @GromHellscream 可以直接使用路由的方式进行解耦式跳转和传参,present 也有实现。
    GromHellscream
        7
    GromHellscream  
       2020-05-26 21:26:45 +08:00
    @xayoung
    原来实际应用场景是这样的,谢谢老哥。


    @neverfall
    好的,谢谢老哥。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4253 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 04:07 · PVG 12:07 · LAX 21:07 · JFK 00:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.