Viperit

Language Build Status Platform License Codecov codebeat badge CocoaPods Carthage Compatible Accio Swift Package Manager compatible SwiftUI compatible

编写一个遵循 VIPER 架构的 iOS 应用程序,以一种简单的方式

Viper 的简单方式

我们都知道 Viper 很棒。但我们也知道它很难设置。这个库旨在简化所有这些样板流程。如果您还不知道 Viper 是什么,请查看:使用 VIPER 构建 iOS 应用程序 (objc.io)

安装

要求

Swift Package Manager (SPM)

您可以使用 Xcode 上的 SPM 轻松安装此框架。转到 Xcode 中的 File | Swift Packages | Add Package Dependency... 并搜索 "http://github.com/ferranabello/Viperit"

CocoaPods

CocoaPods 是 Cocoa 项目的依赖管理器。

将 Viperit 指定到您的项目的 Podfile 中

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '12.0'
use_frameworks!

pod 'Viperit'

Carthage

Carthage 是一个分散的依赖管理器,它构建您的依赖项并为您提供二进制框架。

要使用 Carthage 将 Viperit 集成到您的 Xcode 项目中,请在您的 Cartfile 中指定它

github "ferranabello/Viperit"

运行 carthage update 以构建框架并将构建的 Viperit.framework 拖到您的 Xcode 项目中。

功能

使用 Xcode 模板轻松创建模块

Viperit Xcode 模板可以从最新版本页面下载。 下载 Templates.zip 文件。

要安装它们,解压缩文件,打开终端并运行

cd PATH/TO/UNZIPPED/FOLDER
mkdir -p ~/Library/Developer/Xcode/Templates/
cp -R Viperit ~/Library/Developer/Xcode/Templates/

Module Creation

如果您希望自动为您创建 storyboard 文件,您可以选中“Also create a Storyboard file for module”。 选择“Universal”以仅使用一个视图用于手机和平板电脑,如果您希望为平板电脑设备拥有一个单独的视图,则选择“Dedicated Tablet View”。

使用 storyboard、xib、程序化视图或 SwiftUI

默认情况下,任何 Viperit 模块都将假定其视图是从 Storyboard 加载的。 但是您可以使用storyboardsnibs代码甚至 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 模块!

0. 创建您的模块文件

让我们使用提供的 Xcode 模板来轻松创建模块所需的所有类。 只需在文档面板中单击 New file,然后在“Viperit”部分下选择 Protocol-oriented moduleObject-oriented moduleSwiftUI module

1. 创建一个模块枚举

您至少需要一个(您可以根据需要使用任意多个,也许可以按功能对模块进行分组)实现 ViperitModule 协议的枚举来枚举您的应用程序模块。

import Viperit

//MARK: - Application modules
enum AppModules: String, ViperitModule {
    case myFirstModule
}

2. 构建模块并执行导航

假设这是一个新应用程序,我们希望将我们的“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)

2.1. 您正在使用 SwiftUI 吗?

假设您创建了一个基于 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 管理数据流。

3. 遵循 Viper 流程

一切都已准备好让您以 Viper 的方式创造伟大的事物! 克隆 repo 并运行“Example”目标以查看其实际效果! 或者只是用 Cocoapods 尝试一下

pod try Viperit

作者

Ferran Abelló

许可证

Viperit 在 MIT 许可证下发布,版权归 Ferran Abelló 所有。