protocol AuthRepository {
associatedtype AuthData
associatedtype AuthResponseData
associatedtype RegistrationData
associatedtype RegistrationResponseData
func login(with data: AuthData) async throws -> AuthResponseData?
func register(with data: RegistrationData) async throws -> RegistrationResponseData?
}
和我的服务器实现
struct MyServerAuthData {
let email: String
let password: String
}
struct MyServerAuthResponseData {
let token: String
}
struct MyServerRegistrationData {
let email: String
let password: String
let name: String
}
actor AuthRepositoryImpl: AuthRepository {
func login(with data: MyServerAuthData) async throws -> MyServerAuthResponseData? {
...
}
func register(with data: MyServerRegistrationData) async throws -> Void? {
...
}
}
要在整个应用程序上使用,我创建了此ViewModel
@MainActor
final class AuthViewModel<T: AuthRepository>: ObservableObject {
private let repository: T
init(repository: T) {
self.repository = repository
}
func login(data: T.AuthData) async throws -> T.AuthResponseData? {
try await repository.login(with: data)
}
func register(with data: T.RegistrationData) async throws {
try await repository.register(with: data)
}
}
在应用程序中定义
@main
struct MyApp: App {
@StateObject var authViewModel = AuthViewModel(repository: AuthRepositoryImpl())
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(self.authViewModel)
}
}
}
消耗AS
@EnvironmentObject private var authViewModel: AuthViewModel<AuthRepositoryImpl>
但是,使用此代码,对Auth存储库进行通用实现的整个概念是没有用的,因为更改AuthrePostory将需要在所有应用程序中搜索和替换。 我已经直接体验了这一点,创建了一个用于#Preview的octauthimpl,并且预览崩溃了,因为它定义了authviewModel(repository:mockauthimpl()),但是视图期望authviewModel.
有更好的方法吗?
这个设计想法可能有些问题。您还需要在使用AuthViewModel的位置具有清晰的类型。您正在处理UI,因此您应该在协议实施中添加更多详细信息。同一部分是UI的输入和输出,例如以下伪代码:
AuthViewModel<AuthRepositoryImpl>