接口返回是外部世界,UI 是产品承诺。两者之间必须有一层翻译,否则字段缺失、类型变化和业务码调整会直接污染页面逻辑。
API Model 不等于 ViewData
API Model 描述接口,ViewData 描述展示。列表标题是否为空、按钮是否可点、文案如何兜底,都应该在转换层完成。
struct UserDTO: Decodable {
let name: String?
let avatarURL: URL?
}
struct UserViewData: Hashable {
let title: String
let avatarURL: URL?
init(dto: UserDTO) {
title = dto.name?.isEmpty == false ? dto.name! : "未命名用户"
avatarURL = dto.avatarURL
}
}
错误要分层
传输错误、鉴权错误、业务错误和空数据不是同一种失败。请求层应该映射成明确 enum,页面再决定展示方式。
容错不是吞错
可以给 UI 兜底,但日志必须留下原始上下文。线上问题需要知道是后端字段变化、解析失败还是业务状态没有覆盖。