I must admit my knowledge of swift is limited, and I cannot wrap my head around this problem.
I've defined this protocol, so I can use different auth providers in my app.
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?
}
and an implementation for my server
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? {
        ...
    }
}
To use across the app, I've created this 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)
    }
}
defined in the app as
@main
struct MyApp: App {
    @StateObject var authViewModel = AuthViewModel(repository: AuthRepositoryImpl())
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(self.authViewModel)
        }
    }
}
and consumed as
@EnvironmentObject private var authViewModel: AuthViewModel<AuthRepositoryImpl>
But with this code, the whole concept of having a generic implementation for the auth repository is useless, because changing the AuthRepostory will need to search and replace  AuthViewModel<AuthRepositoryImpl> across all the app.
I've experienced this directly creating a MockAuthImpl to use with #Preview, and the preview crashed because it defines AuthViewModel(repository: MockAuthImpl()) but the view expects AuthViewModel<AuthRepositoryImpl>.
There is a better way to do that?
