如何使用Swinject注册遵循ObservableObject的协议?
问题:Swinject注册遵循ObservableObject的协议报错解决方法
问题场景
注册遵循ObservableObject的协议时,因协议包含关联类型导致编译错误,无法直接通过Swinject完成注册。
相关代码
协议定义:
protocol A: ObservableObject {}
实现类:
final class B: A {}
Assembly注册代码:
final class ViewStoreAssembly: Assembly{ func assemble(container: Container) { container.register(A.self) { _ in B() } } }
编译错误
Protocol 'A' can only be used as a generic constraint because it has Self or associated type requirements
需求价值
- 在SwiftUI中实现视图与ViewStore/Presenter解耦,分离视图与视图模型持有者
- 便于通过模拟视图测试ViewStore/Presenter逻辑
解决方法
方法一:使用类型擦除包装器
创建类型擦除类封装协议实例,消除关联类型约束:
final class AnyA: ObservableObject { let objectWillChange: ObservableObjectPublisher private let base: A init(_ base: A) { self.base = base // 若协议实现使用自定义Publisher,需调整类型转换逻辑 self.objectWillChange = base.objectWillChange as! ObservableObjectPublisher } // 若协议A有自定义方法/属性,需在此转发 // 示例:如果协议有var title: String { get } // var title: String { base.title } }
修改注册代码:
final class ViewStoreAssembly: Assembly{ func assemble(container: Container) { container.register(AnyA.self) { _ in AnyA(B()) } } }
视图中使用:
struct ContentView: View { @ObservedObject var viewModel: AnyA var body: some View { // 视图逻辑实现 } }
方法二:依赖具体类型+泛型约束
放弃直接注册协议,改为注册具体实现类,在依赖方使用泛型约束协议:
- 修改注册代码:
final class ViewStoreAssembly: Assembly{ func assemble(container: Container) { container.register(B.self) { _ in B() } } }
- 视图使用泛型约束:
struct ContentView<T: A>: View { @ObservedObject var viewModel: T var body: some View { // 视图逻辑实现 } }
- 注入实例:
guard let viewModel = container.resolve(B.self) else { fatalError("Failed to resolve viewModel") } let view = ContentView(viewModel: viewModel)
内容的提问来源于stack exchange,提问作者Pep Michael904
相关产品推荐
相关产品推荐

