搜文章
推荐 原创 视频 Java开发 iOS开发 前端开发 JavaScript开发 Android开发 PHP开发 数据库 开发工具 Python开发 Kotlin开发 Ruby开发 .NET开发 服务器运维 开放平台 架构师 大数据 云计算 人工智能 开发语言 其它开发
Lambda在线 > Swift开源变现之路 > Swift组件化路由--SwiftMediator

Swift组件化路由--SwiftMediator

Swift开源变现之路 2020-07-01

在OC上搞得风生水起的组件化必不可少的就是路由,用于解耦、调度整个APP内组件之间的跳转、传参等等。有依赖协议注册的方案也有target-action。在Swift语言下唯一不同的就是Runtime受到了制约,但是协议却更加好用,所以路由的实现方案更加精简灵活多样,我这提供一个简便的路由实现方案,不需要注册表,不需要大面积改动代码,可以让模块间无耦合的调用服务、页面跳转。无需注册,不需要协议,只需要知道目标VC的类名和module名称。

实现原理:

  1. 生成对象

  2. 属性赋值

  3. 获取最上层VC

  4. 执行跳转或执行方法

其中 生成对象 这地方主要是针对性的初始化VC或者class,根据命名空间+Class名称反射出来这个类然后初始化。然后属性赋值,这个复制过程OC有Runtime执行,Swift这款单独提供了一个Mirror,可以根据对象反射出来这个对象的属性列表,按照惯例反射两层就行了。我的方案是根据传参判断属性是否存在再考虑复制

 /// 判断属性是否存在 /// - Parameters: /// - name: 属性名称 /// - obj: 目标对象 private func getTypeOfProperty (_ name: String, obj:AnyObject) -> Bool{ // 注意:obj是实例(对象),如果是类,则无法获取其属性 let morror = Mirror.init(reflecting: obj) let superMorror = Mirror.init(reflecting: obj).superclassMirror  for (key,_) in morror.children { if key == name { return true } }  guard let superM = superMorror else { return false }  for (key,_) in superM.children { if key == name { return true } } return false }  /// KVC给属性赋值 /// - Parameters: /// - obj: 目标对象 /// - paramsDic: 参数字典Key必须对应属性名 private func setObjectParams(obj: AnyObject, paramsDic:[String:Any]?) { if let paramsDic = paramsDic { for (key,value) in paramsDic { if getTypeOfProperty(key, obj: obj){ obj.setValue(value, forKey: key) } } } }


剩下的查找最上层VC就是递归window的rootVC,然后根据最上层的VC去执行Push或者Present操作,跳转到指定的VC


在某些特定情况下也需要有执行函数的操作,也是根据字符串反射Selector,然后再执行相应的类或者对象的Selector即可,OC上有NSInvocation可以执行命令调用方法并且拿到回调,但是在Swift上还是perform更加灵活一些,我这的封装只做了两个参数的传递,实际上perform可以做到更多。

 /// 路由调用实例对象方法:必须标记@objc 例子:@objc class func qqqqq(_ name: String) /// - Parameters: /// - objc: 初始化好的对象 /// - selName: 方法名 /// - param: 参数1 /// - otherParam: 参数2 @discardableResult public func callObjcMethod(objc: AnyObject, selName: String, param: Any? = nil, otherParam: Any? = nil ) -> Unmanaged<AnyObject>?{  let sel = NSSelectorFromString(selName) guard let _ = class_getInstanceMethod(type(of: objc), sel) else { return nil } return objc.perform(sel, with: param, with: otherParam) }  /// 路由调用类方法:必须标记@objc 例子:@objc func qqqqq(_ name: String) /// - Parameters: /// - moduleName: 组件名称 /// - className: 类名称 /// - selName: 方法名 /// - param: 参数1 /// - otherParam: 参数2 @discardableResult public func callClassMethod(className: String, selName: String, moduleName: String? = nil, param: Any? = nil, otherParam: Any? = nil ) -> Unmanaged<AnyObject>?{  var namespace = Bundle.main.infoDictionary!["CFBundleExecutable"] as! String if let name = moduleName { namespace = name } let className = "\(namespace).\(className)" guard let cls: AnyObject? = NSClassFromString(className) else { return nil }  let sel = NSSelectorFromString(selName) guard let _ = class_getClassMethod(cls as? AnyClass, sel) else { return nil }  return cls?.perform(sel, with: param, with: otherParam) }

剩下的工作就是对openURL进行处理了根据URL携带过来的数据进行VC初始化、赋值、跳转等操作。


APP生命周期抓取

一些组件可能需要对AppDelegate生命周期比较在意需要做一些初始化操作。这里也做了一些生命周期抓取的工作,多个组件勾取生命周期在数组里添加即可


下面就可以愉快的在swift下边使用组件化带来的便利了。


OC组件化路由:https://github.com/jackiehu/JHMediator

Swift组件化路由:https://github.com/jackiehu/SwiftMediator

版权声明:本站内容全部来自于腾讯微信公众号,属第三方自助推荐收录。《Swift组件化路由--SwiftMediator》的版权归原作者「Swift开源变现之路」所有,文章言论观点不代表Lambda在线的观点, Lambda在线不承担任何法律责任。如需删除可联系QQ:516101458

文章来源: 阅读原文

相关阅读

关注Swift开源变现之路微信公众号

Swift开源变现之路微信公众号:Swift__2020

Swift开源变现之路

手机扫描上方二维码即可关注Swift开源变现之路微信公众号

Swift开源变现之路最新文章

精品公众号随机推荐

下一篇 >>

Swift 实践:属性