URLNavigator路由使用

Github地址


介绍

  • URLNavigator 是 devxoul发布在github上的一个Swift 路由库
  • 它提供了通过 URL 导航到 view controller 的方式
  • 路由跳转为的是模块解耦
  • 如果APP业务庞大,尤其是有一些H5打开原生界面的情况下,路由是一个非常好的打开业务的方式。


安装

pod 'URLNavigator'


项目中使用

原始Demo中已经有详细的使用介绍。但是这里我打算做一些改动,按照业务模块解耦。

  • URLNavigator的使用大致分为几步:
    • 自定义路由URL
    • 使用Navigator注册路由,并确认各路由URL对应要打开的VC或者要处理的业务
    • 使用Navigator打开路由对应业务


1. 自定义业务路由

//首页模块路由
enum HomeModuleRoute: String {
    case homeRoute = "st://home"
    case caseRoute = "st://cate/<int:cateId>" 
    //case searchRoute = "st://search/<string:keyword>" //string:可以不写,默认都是字符串
    case searchRoute = "st://search/<keyword>"
    case commonAlert = "st://alert"
}

//用户模块路由
enum UserModuleRoute: String {
    case userHomeRoute = "st://userHome"
}


2. 定义 路由注册器需要遵循的协议

protocol NavigationModulesProtocal {
    //遵循此协议的各 路由注册器 都要实现路由注册方法
    func initRoute(navigator: Navigator)
}


3. 实现各个业务模块的路由注册器

//首页相关模块 路由注册器
struct HomeRouter: NavigationModulesProtocal {
    func initRoute(navigator: Navigator) {
        
        //注册首页
        navigator.register(HomeModuleRoute.homeRoute.rawValue) { url, values, context in
            print("url:", url)
            print("values:", values)
            print("context", context)
            
            return HomeViewCtrl()
        }
        
        navigator.register(HomeModuleRoute.caseRoute.rawValue) { url, values, context in
            print("url:", url)
            print("values:", values)
            print("context", context)
            
            return CateViewCtrl()
        }
        
        navigator.register(HomeModuleRoute.searchRoute.rawValue) { url, values, context in
            print("url:", url)
            print("values:", values)
            print("context", context)
            
            return SearchViewCtrl()
        }

        
        navigator.handle(HomeModuleRoute.commonAlert.rawValue) { url, values, context in
            print("url:", url)
            print("values:", values)
            print("context", context)
            
            //通过url传参时,可以获取参数值
            let title = url.queryParameters["title"]
            let message = url.queryParameters["message"]
            print("title:", title)
            print("message:", message)
            
            //接下来可以添加弹窗了,略...
            
            return true
        }
    }
}

//用户相关模块 路由注册器
struct UserRouter: NavigationModulesProtocal {
    func initRoute(navigator: Navigator) {
        
        //注册我的首页
        navigator.register(UserModuleRoute.userHomeRoute.rawValue) { url, values, context in
            return UserHomeViewCtrl()
        }
    }
}


4. 创建一个Nav结构体作为路由处理总部

  • Nav中创建Navigator的单例。接下来所有的路由注册都用Navigator单例
struct Nav {
    
    static let share = Navigator()
    
    //业务路由注册器都存入此数组,用于后续进行统一注册的初始化工作
    private static let modulesRouteArray : [NavigationModulesProtocal] = [
        HomeRouter.init(),
        UserRouter.init()
    ]
    
    //注册所有需要用到的业务路由
    static func initBusiness() {
        self.share.register("http://<path:_>", self.webViewControllerFactory)
        self.share.register("https://<path:_>", self.webViewControllerFactory)
        
        //这里初始化所有的模块的路由注册
        for router in modulesRouteArray {
            router.initRoute(navigator: self.share)
        }
    }
    
    //这里是复用了原始demo中的模块,就是当路由是web链接时,用webview打开
    private static func webViewControllerFactory(url: URLConvertible, values: [String: Any], context: Any?) -> UIViewController? {
        guard let url = url.urlValue else {
            return nil
        }
        return SFSafariViewController(url: url)
    }
}


5. 初始化路由

  • 可以在AppDelegate.swift中初始化
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
    Nav.initBusiness()
    return true
}


6. 可以测试了。但是这里要介绍一下通过路由打开业务的三种方式

  • URLNavigator的跳转方式有三种:pushpresentopen
  • pushpresent对应navigator.register注册的路由,用于打开VC
  • open对应navigator.handle注册的路由,用于其他功能:譬如打开弹窗等
//常规打开方式
Nav.share.push(UserModuleRouter.userHomeRouter.rawValue)
Nav.share.present(UserModuleRouter.userHomeRouter.rawValue)

//也可以通过 context 传参数。设置from从哪个界面跳转,不设置默认从当前控制器跳转
Nav.share.push(UserModuleRouter.userHomeRouter.rawValue, context: ["param1":"123"], from: nil, animated: true)
//还可以使用它的直接打开控制器的方法
func pushViewController(_ viewController: UIViewController, from: UINavigationControllerType?, animated: Bool) -> UIViewController?
//有时候需要传参,可能就要使用路由的字符串字面量了。有没有更好的办法?可以留言指点,thanks~
Nav.share.push("st://cate/1000")


//打印结果:
url: st://cate/1000
values: ["cateId": 1000]
context nil
//有时候需要传参,可能就要使用路由的字符串字面量了。有没有更好的办法?可以留言指点,thanks~
Nav.share.push("st://home?title=温馨提示&message=内容", context: ["param1":"111"])

//打印结果:
url: st://home?title=温馨提示&message=内容
values: [:]
context Optional(["param1": "111"])
title: Optional("温馨提示")
message: Optional("内容")
//使用open方式打开
Nav.share.open("st://alert?title=温馨提示&message=内容", context: ["param1":"111"])


//打印结果:
url: st://home?title=温馨提示&message=内容
values: [:]
context Optional(["param1": "111"])
title: Optional("温馨提示")
message: Optional("内容")





©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容