前言
在模组化的过程中,业务模块间的通信往往是处理最多的.与其应运而生的解决方案有以下几种:
- 提前注册服务
-
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中, 以提高查找性能.
十. 本司基于路由实现的业务架构
image仅供参考, 合适才是最好的.
相关链接
Marmot-iOS: 基于 Khala 设计的 hybird(WKWebview
<=> Native
) 通信组件.
网友评论