Tranquillity 是一个轻量级但功能强大的 Swift 依赖注入 库。
“Tranquillity”这个名字奠定了该库的基本原则:清晰、简洁和安全。
它表示 - 使用该库,您将对您的依赖项感到放心。
语言切换:English (英语), Russian (俄语)
依赖注入是一种软件设计模式,其中某人将依赖项传递给对象。
它是更广泛的 控制反转 技术的一种形式,并有助于实现 依赖倒置原则。
我还建议您阅读 术语表,这将有助于更好地理解这些术语。
该库支持三种流行的包管理器:Cocoapods、Carthage、SwiftPM。
5.0.0 之后的版本不再支持 Cocoapods。
您可以使用 "Xcode/File/Swift Packages/Add Package Dependency..." 并写入 github url
https://github.com/ivlevAstef/DITranquillity
您也可以编辑您的 Package.swift
文件,并将以下行添加到 dependencies
部分
.package(url: "https://github.com/ivlevAstef/DITranquillity.git", from: "5.0.0")
并且不要忘记在您的 target
部分指定依赖项
.product(name: "DITranquillity")
将以下行添加到您的 Podfile
文件
pod 'DITranquillity'
将以下行添加到您的 Cartfile
文件
github "ivlevAstef/DITranquillity"
该库使用声明式的依赖关系描述风格,并允许您将应用程序代码与依赖关系描述代码分开。
为了快速入门,让我们看一个简化的 VIPER 屏幕的示例代码
.................................................
/// Dependency description
let container = DIContainer()
container.register(LoginRouter.init)
container.register(LoginPresenterImpl.init)
.as(LoginPresenter.self)
.lifetime(.objectGraph)
container.register(LoginViewController.init)
.injection(cycle: true, \.presenter)
.as(LoginView.self)
.lifetime(.objectGraph)
container.register(AuthInteractorImpl.init)
.as(AuthInteractor.self)
.................................................
/// Application start point
let router: LoginRouter = container.resolve()
window.rootViewController = router.rootViewController
router.start()
.................................................
/// Application Code
import SwiftLazy
class LoginRouter {
let rootViewController = UINavigationController()
private let loginPresenterProvider: Provider<LoginPresenter>
init(loginPresenterProvider: Provider<LoginPresenter>) {
loginPresenterProvider = loginPresenterProvider
}
func start() {
let presenter = loginPresenterProvider.value
presenter.loginSuccessCallback = { [weak self] _ in
...
}
// Your can write code without force cast, it's code simple example
rootViewController.push(presenter.view as! UIViewController)
}
}
protocol LoginPresenter: class {
var loginSuccessCallback: ((_ userId: String) -> Void)?
func login(name: String, password: String)
}
protocol LoginView: class {
func showError(text: String)
}
class LoginPresenterImpl: LoginPresenter {
private weak var view: LoginView?
private let authInteractor: AuthInteractor
init(view: LoginView, authInteractor: AuthInteractor) {
self.view = view
self.authInteractor = authInteractor
}
func login(name: String, password: String) {
if name.isEmpty || password.isEmpty {
view?.showError(text: "fill input")
return
}
authInteractor.login(name: name, password: password, completion: { [weak self] result in
switch result {
case .failure(let error):
self?.view?.showError(text: "\(error)")
case .success(let userId):
self?.loginSuccessCallback?(userId)
}
})
}
}
class LoginViewController: UIViewController, LoginView {
var presenter: LoginPresenter!
...
func showError(text: String) {
showAlert(title: "Error", message: text)
}
private func tapOnLoginButton() {
presenter.login(name: nameTextField.text ?? "", password: passwordTextField.text ?? "")
}
}
protocol AuthInteractor: class {
func login(name: String, password: String, completion: (Result<String, Error>) -> Void)
}
class AuthInteractorImpl: AuthInteractor {
func login(name: String, password: String, completion: (Result<String, Error>) -> Void) {
...
}
}
正如您所看到的,依赖关系描述代码只占很小的一部分,并且应用程序代码不知道依赖关系是如何实现的。
您还可以展示示例
您还可以阅读文章
iOS 13.0+, macOS 10.15+, tvOS 13.0+, watchOS 8.0+, Linux; ARC
请提出一个 GitHub issue。
请帮助库的开发并创建 pull requests
如果您喜欢我的库,请通过添加星标来支持该库。
您可以随时通过电子邮件提问:ivlev.stef@gmail.com。