Monarch 👑 - 开发中

Social Banner

License

一个与来源无关、基于请求、面向协议、资源获取的库,专为纯 SwiftUI 应用程序设计。 它之所以被称为 Monarch(君主),是因为它位于视图层级的顶层。

特性

描述

Monarch 是一个资源获取库,旨在利用 SwiftUI 视图层级结构来简化依赖注入。

资源由请求描述,请求由提供程序处理,提供程序可以确定是否应从网络、应用程序包、缓存或其他任何地方获取资源。

提供程序注册到视图层级结构中,并使用响应链模式调用,这意味着如果第一个提供程序未能获取资源,则下一个提供程序将尝试。 这允许轻松地将不同的功能(例如,缓存、网络)分离到模块化提供程序中。

如何使用

步骤 1:创建请求

Requests(请求)是 Monarch 的基本构建块之一,它们描述了资源的路径。 RemoteRequests(远程请求)描述了远程资源的路径。

struct CurrentUserRequest: RemoteRequest {
  var path: String { "users/me" }
  var previewData: User { .example }
}

步骤 2:注册提供程序

提供程序接收 Requests(请求)并将它们转换为资源。 它们注册在视图层级结构中,并且可供所有下层视图使用。

struct MonarchApp: App {
  var body: some Scene {
    WindowGroup {
      ContentView()
        .register(NetworkClient())
    }
  }
}

步骤 3:执行请求

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 协议

RequestProvider 是为库中的大多数其他协议和类提供支持的协议; 它定义了一个单一的函数。

func perform<R: Request>(_ request: R) async throws -> R.ResponseType

网络提供程序使用此函数从网络获取数据,缓存提供程序使用它从内存或磁盘读取值。