内容简介:在模组化的过程中,业务模块间的通信往往是处理最多的.与其应运而生的解决方案有以下几种:前辈们在借鉴 web 服务路由设计之后,将服务绑定至固定规则的 URL 上.什么是 Target-Action?
前言
在模组化的过程中,业务模块间的通信往往是处理最多的.与其应运而生的解决方案有以下几种:
Runtime
前辈们在借鉴 web 服务路由设计之后,将服务绑定至固定规则的 URL 上.
- CTMediator :
Target-Action
形式设计的路由组件. - 其他以统一注册形式设计的路由.
前情提要
什么是 Target-Action?
ans: 目标-行为模式,它贯穿于iOS开发始终, 最常见的便是:
UIButton().addTarget(target: target, action: action, for: event) 复制代码
什么是 Target-Action 形式的路由?
ans: 在触发路由路径时, 通过 Runtime
机制来发现具体服务,并执行.
相对于提前统一注册的路由,相当于懒加载.
Khala 路由组件使用
一. 编写 服务类(路由类)
- 继承自
NSObject
:Runtime
机制本身便是基于NSObject
. - 声明
@objc(ClassName)
: 由于Xcode 8.0之后在编译时会移除未显式使用的swift类与函数,所以需要加此声明.(服务类不建议在任何模块实例化,会破坏设计逻辑) - 声明
@objcMembers
: 在swift 4.0
中继承NSObject
的swift class
不再默认全部桥接到objective-c
,如果我们想要使用的话我们就需要在class前面加上@objcMembers
这么一个关键字. - 示例如下如下:
@objc(AModule) @objcMembers class AModule: NSObject { } 复制代码
二. 编写 服务函数(路由函数)
-
参数类型限制: 只能使用单个
KhalaInfo(集合类型)
与多个KhalaClosure(闭包类型)
-
第一个参数需要匿名: 方便查找函数, 非匿名
swift
函数桥接至objective-c
时会形成funNameWithParam
结构.(Khala
前期在此花费时间较多, 最后还是采用该折中方案.) -
示例如下如下:
@objc(AModule) @objcMembers class AModule: NSObject,UIApplicationDelegate { func vc() -> UIViewController { let vc = UIViewController() vc.view.backgroundColor = UIColor.red return vc } func action(_ info: KhalaInfo, success: KhalaClosure, failure: KhalaClosure) { success(["success": #function]) failure(["failure": #function]) } } 复制代码
三. 调用
-
通用型调用
Khala(str: "kf://AModule/forClosures")?.call(blocks: { (item) in print("forClosures block3:", item) },{ (item) in print("forClosure block4:", item) }) let value = Khala(str: "kl://AModule/doSomething")?.call() 复制代码
-
UIKit
特例化调用:guard let vc = Khala(str: "kl://BModule/vc?style=0")?.viewController else { return } self.navigationController?.pushViewController(vc, animated: true) 复制代码
四. URL重写 (KhalaRewrite)
该部分设计来源自nginx: 在某些场景下需要对 URL 进行转化与拦截, 例如:
-
服务类与服务函数存在前缀.
-
接收非标准 URL .
-
URL重定向: 页面的动态升降级, 示例如下:
let filter = KhalaRewriteFilter { if $0.url.host == "AModule" { var urlComponents = URLComponents(url: $0.url, resolvingAgainstBaseURL: true)! urlComponents.host = "BModule" $0.url = urlComponents.url! } return $0 } Khala.rewrite.add(filter: filter) // "kl://AModule/doSomething" => "kl://BModule/doSomething" let value = Khala(str: "kl://AModule/doSomething")?.call() print(value ?? "nil") 复制代码
五. UIApplicationDelegate 生命周期分发
部分组件往往依赖于主工程中的 AppDelegate
中部分函数.
- 在
Khala
中,需要显式的在主工程中的AppDelegate
调用与处理相关逻辑. - 服务类需要遵守
UIApplicationDelegate
协议.
主工程 AppDelegate
:
@UIApplicationMain class AppDelegate: UIResponder,UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { let list = Khala.appDelegate.application(application, didFinishLaunchingWithOptions: launchOptions) return true } } 复制代码
组件中服务类:
@objc(AModule) @objcMembers class AModule: NSObject,UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { print("AModule.didFinishLaunchingWithOptions") return true } } 复制代码
六.日志模块: KhalaHistory
每一份url请求都将记录至日志文件中, 可以在适当的时候提供开发者便利.
-
开启日志(默认关闭)
Khala.isEnabledLog = true // or Khala.history.isEnabled = true 复制代码
-
文件路径:
/Documents/khala/logs/
-
文件内容: 日期 + 时间 + URL + 参数
2018-12-01 02:06:54 kl://SwiftClass/double? {"test":"666"} 2018-12-01 02:06:54 kl://SwiftClass/double {"test":"666"} 复制代码
七. 扩展机制: KhalaStore
khala 库中提供了一个空置的类[ KhalaStore ]用于盛放 路由函数 对应的本地函数.来简化本地调用复杂度的问题.
extension KhalaStore { class func aModule_server(value: Int) -> Int { return Khala(str: "kf://AModule/server", params: ["value": value])!.call() as! Int } } @objc(AModule) @objcMembers class AModule: NSObject { func server(_ info: [String: Any]) -> Int { return info["value"] as? Int ?? 0 } } let value = KhalaStore.aModule_server(value: 46) 复制代码
ps: KhalaStore 扩展文件建议统一放置.
八. 断言机制
为方便开发者使用,添加了部分场景下断言机制,示例:
khala.iOS Fatal error: [Khala] 未在[AModule]中匹配到函数[server], 请查看函数列表: 0: init 1: doSomething: 2: vc 复制代码
关闭断言(默认开启):
Khala.isEnabledAssert = false 复制代码
九.缓存机制: KhalaClass.cache
-
当路由第一次调用/注册路由类时,该路由类将被缓存至 KhalaClass.cache 中, 以提高二次查找性能.
-
当路由类实例化时,该路由类中的函数列表将被缓存至 KhalaClass().methodLists 中, 以提高查找性能.
十. 本司基于路由实现的业务架构
仅供参考, 合适才是最好的.
相关链接
Marmot-iOS : 基于 Khala 设计的 hybird( WKWebview
<=> Native
) 通信组件.
参考
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Vue异步组件处理路由组件加载状态
- [ Laravel 5.7 文档 ] 基础组件 —— 路由
- [ Laravel 5.8 文档 ] 基础组件 —— 路由
- 解读 iOS 组件化与路由的本质
- [译] React 路由和 React 组件的爱恨情仇
- React组件卸载、路由跳转、页面关闭(刷新)之前进行提示
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
程序设计语言理论基础
米切尔 / 电子工业出版社 / 2006-11 / 68.00元
本书提出了一个框架,用于分析程序设计语言的语法、操作和语义性质,该框架基于称为类型化λ演算的数学系统。λ演算的主要特色是对于函数和其他可计算的值的一种记法,以及一个等式逻辑和用于表达式求值的一组规则。本书中最简单的系统是称为泛代数的一个等式系统,它可以用来公理化和分析通常用于程序设计的许多数据类型。可作为理论计算机科学、软件系统和数学专业的大学本科高年级或者研究生初始学习阶段的教材,同时也适合用于......一起来看看 《程序设计语言理论基础》 这本书的介绍吧!