前言:仔细看了又看CTMediator的Demo,在这个过程中突然想到了Moya。所以我下面介绍的将基于Moya的思想的封装。
1. 新建一个协议:内部包含CTMediator的所需参数。如下:
// 使用方式:创建枚举, 遵守该协议,根据不同case设置下列参数的值
public protocol SPTargetType {
/// 参数
var commonParams: [String: Any] { get }
/// 组件名称
var moudle: String { get }
/// 响应者名称
var target: String { get }
/// 方法名称
var action: String { get }
/// 是否缓存
var shouldCacheTarget: Bool { get }
}
2. 稍微封装一下CTMediator的使用方法:
- 这里要解释一下为什么要在方法内部去设置callback、kCTMediatorParamsKeySwiftTargetModuleName 这两个参数,因为使用者大概率是不用去关心这两个参数的,所以我选择在方法内部去赋值。
public class SPMediator {
@discardableResult
static func performTarget(_ target: MediatorService, callback:@escaping (Any) -> Void) -> Any? {
let callbackParams: [String: Any] = ["callback": callback, kCTMediatorParamsKeySwiftTargetModuleName: target.service.moudle]
return CTMediator.sharedInstance()?.performTarget(
target.service.target,
action: target.service.action,
params: target.service.commonParams.merging(callbackParams, uniquingKeysWith: { _ , _ in }),
shouldCacheTarget: target.service.shouldCacheTarget)
}
}
3. 创建设置参数枚举, 并遵守协议(1),设置协议参数:
public enum BalanceService: SPTargetType {
case balance
case test([String: Any])
public var commonParams: [String : Any] {
switch self {
case .balance:
return ["animation": true]
case .login(let params):
return ["id": params["id"] ?? ""]
}
}
/// 区分每个业务模块
public var moudle: String {
switch self {
default:
return "SPRouteModule"
}
}
public var target: String {
switch self {
default:
return "Balance"
}
}
public var action: String {
switch self {
case .balance:
return "Test_ViewController"
case .login(_):
return "Login_ViewController"
}
}
public var shouldCacheTarget: Bool {
return true
}
}
4. 使用:
比如我需要Balance的控制器:
guard let result = (SPMediator.performTarget(MediatorService.balance(BalanceService.balance)) { (params) in
print(params)
}) as? UIViewController else {
return
}
回调适用于耗时、异步操作等,其它情况直接拿到返回值然后转成自己需要的Class就可以了。
我这里使用的是
MediatorService
,因为我最后针对每个Service
做了一层封装,统一调用入口。