一个与来源无关、基于请求、面向协议、资源获取的库,专为纯 SwiftUI 应用程序设计。 它之所以被称为 Monarch(君主),是因为它位于视图层级的顶层。
Monarch 是一个资源获取库,旨在利用 SwiftUI 视图层级结构来简化依赖注入。
资源由请求描述,请求由提供程序处理,提供程序可以确定是否应从网络、应用程序包、缓存或其他任何地方获取资源。
提供程序注册到视图层级结构中,并使用响应链模式调用,这意味着如果第一个提供程序未能获取资源,则下一个提供程序将尝试。 这允许轻松地将不同的功能(例如,缓存、网络)分离到模块化提供程序中。
Requests
(请求)是 Monarch 的基本构建块之一,它们描述了资源的路径。 RemoteRequests
(远程请求)描述了远程资源的路径。
struct CurrentUserRequest: RemoteRequest {
var path: String { "users/me" }
var previewData: User { .example }
}
提供程序接收 Requests
(请求)并将它们转换为资源。 它们注册在视图层级结构中,并且可供所有下层视图使用。
struct MonarchApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.register(NetworkClient())
}
}
}
monarch
Environment Value(环境变量)使用在视图层级结构中注册的提供程序,尝试从 Request
(请求)提供资源。
struct ContentView: View {
@Environment(\.monarch) var monarch
@State var user: User?
var body: some View {
Text(user?.name ?? "Loading...")
.task {
user = try? await monarch.perform(CurrentUserRequest())
}
}
}
提供程序不太可能能够处理每个响应。 当注册了多个提供程序时,Monarch
将按注册顺序调用每个提供程序的 perform
方法,并在获得响应后停止。
只有当提供程序注册的 domain
(域)与 Request
(请求)的 domain
(域)兼容时,Monarch
才会将 Request
(请求)传递给提供程序。
extension RequestDomain {
static let images = RequestDomain(rawValue: 1 << 0)
}
ContentView()
.register(ImageCache(), domain: .images)
.register(ImageClient(), domain: .images)
.register(NetworkClient(), domain: .any)
在此示例中,images
域中的任何请求都将被 ImageCache
接收,如果未找到缓存值,则 ImageClient
将获取图像。 任何其他请求都将直接发送到 NetworkClient
。
RequestProvider
是为库中的大多数其他协议和类提供支持的协议; 它定义了一个单一的函数。
func perform<R: Request>(_ request: R) async throws -> R.ResponseType
网络提供程序使用此函数从网络获取数据,缓存提供程序使用它从内存或磁盘读取值。