跳转到正文
YGJoon 技术博客

iOS 依赖注入设计:目录数据协议与渐进式替换

发布于:
·594 字 · 约 1 分钟·作者:YGJoon
通过分类与分页数据加载示例,说明怎样让 SwiftUI 页面与具体 HTTP 实现解耦。
iOS 依赖注入设计:目录数据协议与渐进式替换文章封面
目录

示例代码均为匿名化改写,用于说明模式;网络实现和响应模型由应用提供。

先给外部数据源留一条替换路径

目录数据页面需要读取分类、分页项目和搜索结果。可以先定义一个小型异步协议描述这些能力,再由线上实现调用统一网络客户端并解码业务模型。视图接收协议,不直接创建 URLSession 或拼接服务器请求。

应用组装层负责创建具体实现并把它传给页面。这种接线能让页面在测试中使用内存替身,控制加载顺序、空结果和失败状态,而不必依赖真实后端。

struct CatalogItem: Identifiable, Sendable {
    let id: UUID
    let title: String
}

protocol CatalogProviding: Sendable {
    func items(page: Int) async throws -> [CatalogItem]
}

@MainActor
final class CatalogModel {
    private let provider: any CatalogProviding
    private(set) var items: [CatalogItem] = []

    init(provider: any CatalogProviding) {
        self.provider = provider
    }

    func loadFirstPage() async throws {
        items = try await provider.items(page: 1)
    }
}

依赖注入不必一次铺满

已有工程可能一部分功能使用协议注入,另一部分仍从共享实例调用。优先为外部副作用多、状态复杂、测试成本高的边界增加替换能力即可;纯模型并不需要为了形式统一而包一层协议。

协议是源码层的边界。如果工程仍在一个应用 target 中编译,目录分层不会自动阻止跨功能引用。是否提取独立模块,应根据稳定性、复用需求和维护成本决定。

协议优先用于网络、系统副作用和需要控制时序的边界;普通模型不必为了形式统一再包一层。若某条热路径确实受动态派发影响,再用性能测量决定是否改成泛型约束。

数据合同要留在适配层

后端字段映射、分页默认值和错误 envelope 属于服务实现的职责。它们应集中在适配层,并有针对参数和模型解码的检查。视图不应知道服务端字段名,也不应自行处理多种响应格式。


分享这篇文章:


相关文章

上一篇
SwiftUI 启动流程设计:隐私同意与登录恢复状态
下一篇
iOS 表单请求校验:金额边界与提交条件收敛