编写一个遵循 VIPER 架构的 iOS 应用程序,以一种简单的方式。
我们都知道 Viper 很棒。但我们也知道它很难设置。这个库旨在简化所有这些样板流程。如果您还不知道 Viper 是什么,请查看:使用 VIPER 构建 iOS 应用程序 (objc.io)
您可以使用 Xcode 上的 SPM 轻松安装此框架。转到 Xcode 中的 File | Swift Packages | Add Package Dependency...
并搜索 "http://github.com/ferranabello/Viperit"
CocoaPods 是 Cocoa 项目的依赖管理器。
将 Viperit 指定到您的项目的 Podfile 中
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '12.0'
use_frameworks!
pod 'Viperit'
Carthage 是一个分散的依赖管理器,它构建您的依赖项并为您提供二进制框架。
要使用 Carthage 将 Viperit 集成到您的 Xcode 项目中,请在您的 Cartfile
中指定它
github "ferranabello/Viperit"
运行 carthage update
以构建框架并将构建的 Viperit.framework
拖到您的 Xcode 项目中。
Viperit Xcode 模板可以从最新版本页面下载。 下载 Templates.zip 文件。
要安装它们,解压缩文件,打开终端并运行
cd PATH/TO/UNZIPPED/FOLDER
mkdir -p ~/Library/Developer/Xcode/Templates/
cp -R Viperit ~/Library/Developer/Xcode/Templates/
如果您希望自动为您创建 storyboard 文件,您可以选中“Also create a Storyboard file for module”。 选择“Universal”以仅使用一个视图用于手机和平板电脑,如果您希望为平板电脑设备拥有一个单独的视图,则选择“Dedicated Tablet View”。
默认情况下,任何 Viperit 模块都将假定其视图是从 Storyboard 加载的。 但是您可以使用storyboards,nibs,代码甚至 SwiftUI 视图! 您需要做的就是在模块枚举中覆盖变量 viewType
enum MySuperCoolModules: String, ViperitModule {
case theStoryboardThing
case oldSchool
case xibModule
case whatTheSwift
var viewType: ViperitViewType {
switch self {
case .theStoryboardThing: return .storyboard
case .oldSchool: return .code
case .xibModule: return .nib
case .whatTheSwift: return .swiftUI
}
}
}
该框架非常灵活,旨在以您想要的任何方式使用,但它在路由器中具有一些有用的内置功能,您可以使用
//Show your module as the root view controller of the given window
func show(inWindow window: UIWindow?, embedInNavController: Bool, setupData: Any?, makeKeyAndVisible: Bool)
//Show your module from any given view controller
func show(from: UIViewController, embedInNavController: Bool, setupData: Any?)
//Show your module inside another view
func show(from containerView: UIViewController, insideView targetView: UIView, setupData: Any?)
//Present your module modally
func present(from: UIViewController, embedInNavController: Bool, presentationStyle: UIModalPresentationStyle, transitionStyle: UIModalTransitionStyle, setupData: Any?, completion: (() -> Void)?)
您可以像这样注入模拟层来测试您的模块
var module = AppModules.home.build()
view = HomeMockView()
view.expectation = expectation(description: "Test expectation")
module.injectMock(view: view)
...
现在,让我们创建我们的第一个名为“myFirstModule”的 Viperit 模块!
让我们使用提供的 Xcode 模板来轻松创建模块所需的所有类。 只需在文档面板中单击 New file,然后在“Viperit”部分下选择 Protocol-oriented module、Object-oriented module 或 SwiftUI module。
您至少需要一个(您可以根据需要使用任意多个,也许可以按功能对模块进行分组)实现 ViperitModule 协议的枚举来枚举您的应用程序模块。
import Viperit
//MARK: - Application modules
enum AppModules: String, ViperitModule {
case myFirstModule
}
假设这是一个新应用程序,我们希望将我们的“myFirstModule”模块加载为应用程序的启动模块
import Viperit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
let module = AppModules.myFirstModule.build()
let router = module.router as! MyFirstModuleRouter
router.show(inWindow: window)
return true
}
}
这只是一个例子,您当然可以使用自己的路由器函数来代替提供的 show(inWindow:)
window = UIWindow(frame: UIScreen.main.bounds)
let module = AppModules.myFirstModule.build()
let router = module.router as! MyFirstModuleRouter
router.mySuperCoolShowFunction(inWindow: window)
假设您创建了一个基于 SwiftUI 的模块,名为“Cool”。 您需要做的就是使用新的 Viperit SwiftUI 模块构建器
import SwiftUI
import Viperit
//A sample function that could be implemented in some Router to show your Cool SwiftUI module
//You can even inject an @EnvironmentObject view model to your SwiftUI view.
func showTheCoolModule() {
let module = AppModules.cool.build { presenter -> (CoolView, UserSettings) in
let p = presenter as! CoolPresenterApi
let settings = p.settings()
return (CoolView(presenter: p), settings)
}
let router = module.router as! CoolRouter
router.show(from: viewController)
}
查看示例应用程序以更好地了解其工作原理,以及如何在 SwiftUI 上使用 presenter 管理数据流。
一切都已准备好让您以 Viper 的方式创造伟大的事物! 克隆 repo 并运行“Example”目标以查看其实际效果! 或者只是用 Cocoapods 尝试一下
pod try Viperit
Viperit 在 MIT 许可证下发布,版权归 Ferran Abelló 所有。