Ariadne 的线,以 Ariadne 的传说命名,指的是通过详尽地将逻辑应用于所有可用的路径来解决具有多种明显进行方式的问题 - 例如物理迷宫、逻辑难题或道德困境。
Ariadne 是一个可扩展的路由框架,其构建考虑了组合和依赖注入原则。 它有助于创建过渡和路由,从而抽象出视图控制器的构建和呈现逻辑,使其可重用且紧凑。
UIKit 存在路由问题。 所有视图控制器的呈现和解除方法都发生在视图控制器中,这通常会导致视图控制器过于臃肿,因为所有视图控制器的构建、依赖注入和过渡也都发生在那里。
这导致了大量的视图控制器,这些控制器无法轻易地进行测试,并且代码很难在不同的视图控制器实例中重复使用。 解决这些问题的一种方法是将视图控制器的构建和过渡代码分离到单独的对象中,通常称为 Router
。 即使只有像 VIPER 这样的架构才将 Router
推广为必需组件,但我认为任何其他架构的应用程序都可以通过至少某种形式的路由得到极大的改进。
这就是 Ariadne
的用武之地。 这是一个框架,它提供视图控制器构建机制、过渡和路由类,以架构无关的方式从视图控制器中抽象出所有这些逻辑。
假设您需要在一个 UINavigationController
中呈现用户个人资料。 通常,在没有任何库的 MVC 应用程序中,您会这样做
let storyboard = UIStoryboard(named: "User", bundle: nil)
let userController = storyboard.instantiateViewController(withIdentifier: "UserViewController")
userController.user = user
let navigation = UINavigationController(rootViewController: userController)
present(navigation, animated: true)
使用 Ariadne,此代码不再绑定到当前的视图控制器,并且可以如下所示
let route = Storyboards.User.userViewController.builder.embeddedInNavigation().presentRoute()
router.navigate(to: route, with: user)
注意:此特定示例需要 SwiftGen 集成,请参阅 SwiftGen 集成 指南。如果没有 SwiftGen,
Storyboards.User.userViewController.builder
可以被任何自定义视图控制器构建器替换。
pod 'Ariadne'
Ariadne
架构从根本上从 ViewBuilder
开始。 因为视图控制器与 iOS 上的视图紧密耦合,所以 UIViewController
被认为是视图,并且类型别名为 ViewController
。
注意:在 watchOS 上,
ViewController
是WKInterfaceController
的类型别名,在 macOS 上是NSViewController
的类型别名,原因类似。
ViewBuilder
的定义很简单 - 它根据提供的 Context
构建一个 ViewController
protocol ViewBuilder {
associatedtype ViewType: ViewController
associatedtype Context
func build(with context: Context) throws -> ViewType
}
开箱即用,Ariadne
为以下内容提供构建器
框架的第二个构建块是 ViewTransition
对象,它用于在视图之间执行过渡。 开箱即用,支持以下过渡
ViewBuilder
和 ViewTransition
对象可以组合在一起以形成可执行的 Route
。 例如,给定 AlertBuilder
,以下是如何使用 Ariadne
创建警报路由
let alertRoute = AlertBuilder().presentRoute()
请注意,presentRoute
方法对于 AlertBuilder
和任何 UIViewController
构建器都是以相同的方式调用的。 通过利用 ViewBuilder
上的协议扩展,任何过渡和路由都可以在 ViewBuilder
实例上重用。 要查看如何实现和扩展 ViewBuilder
协议的示例,请参阅 实现视图构建器 指南。
最后但并非最不重要的是,Router
对象将所有内容联系在一起,并允许您实际执行路由
router.navigate(to: alertRoute, with: alertModel, completion: { _ in
// Route has completed
})
Router 使用 RootViewProvider
来查找哪个视图控制器是视图层次结构中的根视图控制器。 在 iOS 和 tvOS 上,RootViewProvider
是 UIWindow
的接口,允许 Router
获取视图层次结构的根视图控制器。 但是,在其他平台以及应用程序扩展中,无法访问 UIApplication 共享窗口,在这种情况下,RootViewProvider
可能有所不同,例如,在 iMessage 应用程序中,MSMessagesAppViewController
可能扮演类似的角色。
ViewFinder
对象从根视图开始遍历视图层次结构,以查找当前在屏幕上可见的视图控制器。 在 iOS 和 tvOS 上,Ariadne
提供了 CurrentlyVisibleViewFinder
类的实现,该类递归搜索 UIViewController
、UINavigationController
和 UITabBarController
以查找当前可见的视图控制器,但在其他平台和其他情况下,您可能希望使用您的实现或 CurrentlyVisibleViewFinder
的子类,如果您的视图层次结构包含其他视图控制器容器。
SwiftGen 是一个强大的代码生成器,可用于让您摆脱使用基于字符串的 API,这种 API 既繁琐又容易出错。 例如,对于故事板,SwiftGen 能够生成实例化视图控制器所需的代码,并使此代码在编译时保证故事板和视图控制器的存在。 Ariadne
可以在此基础上构建,从而为路由构建产生简洁的语法,如下所示
let route = Storyboards.User.userViewController.builder.embeddedInNavigation().presentRoute()
要了解如何实现这一点,请参阅 SwiftGen 集成 指南。
不同的应用程序可能具有完全不同的架构和要求。 要查看简单依赖注入的示例,请参阅 SwiftGen 集成,对于使用依赖容器(如 Dip)进行更高级的依赖注入,请转到 高级依赖注入示例 指南。
要了解有关项目未来目标和愿景的更多信息,请阅读 愿景 文档。
您可以在这里找到完整的项目文档。
iOS 示例项目可以在 Ariadne.xcodeproj 中找到,并且包含
Ariadne 在 MIT 许可下发布。 有关更多信息,请参阅 LICENSE。