Latest | 0.4.0 |
---|---|
Homepage | https://github.com/Arror/RTSession |
License | MIT |
Platforms | ios 10.0 |
Authors |
说明
该工程仍处于早期阶段,不建议在工程中直接使用。
该项目为 Target-Action
组件化方案的现代化实现。使用 Thrift
文件定义接口,清晰明确,同时可作为文档。使用代码生成工具,开发者在开发中不在使用硬编码进行调用,避免产生低级错误,提高开发效率。
工具
thrift:Thrift 文件解析工具
swift-gen:Swift 代码生成工具
下载可执行文件或者下载源码编译,使用时将thrift
、swift-gen
放置于同一文件夹下。
示例
工程以集成发票组件为例,来展示组件化工程结构,工程中以Target
表示Pod
。
服务定义
定义 thrift
文件:LoginService.thrift
struct Invoice {
0: required i32 id
1: required string name
2: required string email
}
service InvoiceService {
Invoice loadInvoice(1: required string userID)
}
生成代码
终端执行如下命令
./thrift --clientNamespace RT --serverNamespace RTServer -i ./Services/InvoiceService.thrift -o ./
生成文件:InvoiceService.c.swift
,放置在RTService
中提供给替他模块调用
//
// Code generated by thrift & swift-gen.
// Don't edit manually.
//
import Foundation
import RTSession
public struct RTInvoice: Codable {
public let id: Int
public let name: String
public let email: String
public init(id: Int, name: String, email: String) {
self.id = id
self.name = name
self.email = email
}
}
public enum InvoiceService {
public static func loadInvoice(userID: String) throws -> RTRequest<RTInvoice> {
struct Parameter: Codable {
let userID: String
}
return try RTRequest(
method: "InvoiceService.loadInvoice",
parameter: Parameter(userID: userID),
responseType: RTInvoice.self
)
}
}
生成文件:InvoiceService.s.swift
,该文件放置于RTInvoiceModule
//
// Code generated by thrift & swift-gen.
// Don't edit manually.
//
import Foundation
import RTSession
struct RTServerInvoice: Codable {
let id: Int
let name: String
let email: String
}
protocol __RTInvoiceServiceProtocol: class {
func loadInvoice(userID: String, completion: @escaping (RTResult<RTServerInvoice, RTError>) -> Void)
}
@objc(RTInvoiceService)
class RTInvoiceService: NSObject, __RTInvoiceServiceProtocol {
@objc private func __loadInvoice(parameter: Data, completion: RTCompletion) {
struct Parameter: Codable {
let userID: String
}
let p: Parameter
do {
p = try JSONDecoder().decode(Parameter.self, from: parameter)
} catch {
completion.c(.failure(RTError(code: .decodeError, errorDescription: error.localizedDescription)))
return
}
self.loadInvoice(userID: p.userID) { result in
switch result {
case .success(let value):
do {
completion.c(.success(try JSONEncoder().encode(value)))
} catch {
completion.c(.failure(RTError(code: .encodeError, errorDescription: error.localizedDescription)))
}
case .failure(let error):
completion.c(.failure(error))
}
}
}
}
服务实现
RTInvoiceModule
实现__RTInvoiceServiceProtocol
协议
extension RTInvoiceService {
func loadInvoice(userID: String, completion: @escaping (RTResult<RTServerInvoice, RTError>) -> Void) {
let invoiceVC = RTInvoiceViewController.makeViewController(ensureAction: { vc, invoice in
vc.dismiss(animated: true, completion: {
completion(.success(invoice))
})
}, cancelAction: { vc in
vc.dismiss(animated: true, completion: {
completion(.failure(RTError(code: RTError.Code(rawValue: "user_cancel"), errorDescription: "User click cancel button.")))
})
})
UIViewController.current.present(UINavigationController(rootViewController: invoiceVC), animated: true, completion: nil)
}
}
调用方实现
在主工程或其他模块中引入RTServices
,发起调用
try! InvoiceService.loadInvoice(userID: "Arror").invoked { result in
switch result {
case .success(let invoice):
let alert = UIAlertController(title: "Success", message: "(invoice.name)n(invoice.email)", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
UIViewController.current.present(alert, animated: true, completion: nil)
case .failure(let error):
let alert = UIAlertController(title: "Failure", message: error.localizedDescription, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
UIViewController.current.present(alert, animated: true, completion: nil)
}
}
小结
至此,组件化开发流程已初见雏形。定义的Thrift
文件可作为文档,清晰明确,更方便使用Git
管理。所有的硬编码全部通过代码生成器生成,无需开发者维护,可减少在开发过程中低级错误的出现。文档升级的同时,更新生成的代码,编译器会帮助我们检查可能出现的错误,尽可能的降低开发成本和沟通成本。
更多
在实际开发中一个不可忽略的问题是如何处理URL
,RTSession
允许以method
字符串和parameter
字典参数发起调用,method
必须为InvoiceService.loadInvoice
格式,而parameter
必须可生成Data
,method
和parameter
必须和服务提供者匹配。RTURLBridge
允许开发者处理URL
做匹配,详情请看源码。
未来
目前代码生成器可以生成Swift
代码,完成Module
间的通信,同样可以实现其他语言的代码生成器。例如我们可以实现一个Flutter
插件的代码生成器,实现和Flutter
的通信等等。
Latest podspec
{ "name": "RTSession", "version": "0.4.0", "summary": "Cross module process call", "description": "CMPC for iOS project.", "homepage": "https://github.com/Arror/RTSession", "license": "MIT", "authors": { "Arror": "[email protected]" }, "source": { "git": "https://github.com/Arror/RTSession.git", "tag": "0.4.0" }, "platforms": { "ios": "10.0" }, "swift_versions": "5.0", "swift_version": "5.0", "subspecs": [ { "name": "Core", "source_files": "RTSession/Classes/Core/**/*", "dependencies": { "RTCore": [] } }, { "name": "RTURLBridge", "source_files": "RTSession/Classes/URLBridge/**/*" } ] }
Mon, 10 Jun 2019 10:02:05 +0000