Swift中能否基于String别名修改字符串插值以隐藏敏感字段?
敏感字段自动隐藏的实现方案咨询
我的应用中有大量DTO,其中包含需隐藏的敏感字段。当前定义typealias HiddenFieldType = String,并在多个DTO中使用该类型标记敏感字段。在打印或日志输出(实际为os_log)时,希望自动隐藏这些敏感字段的值。
我尝试了五种方案:
- 方案1:为每个DTO扩展字符串插值,可实现但扩展性差
- 方案2:为
HiddenFieldType扩展插值引发无限递归 - 方案3:尝试重写默认插值,因String已有协议一致性失败
- 方案4:改为struct后扩展插值无效
- 方案5:struct实现
CustomStringConvertible可生效,但需修改所有DTO的初始化代码
现咨询:
- 能否不将
HiddenFieldType从typealias改为struct,也不修改DTO,实现敏感字段隐藏? - 有无比方案5更优的实现方式?
问题1解答
不行。因为typealias HiddenFieldType = String只是给String起了个别名,编译后和原生String完全等价,Swift无法区分普通String和标记为HiddenFieldType的String。不管是字符串插值还是日志输出,系统都会把它当成普通String处理,没有办法针对性触发隐藏逻辑。所以不修改类型定义或DTO的话,做不到自动隐藏。
问题2:更优实现方案
推荐包装结构体+协议适配或者属性包装器的组合,能最小化对现有代码的修改:
方案A:包装结构体+ExpressibleByStringLiteral协议
- 定义包装结构体并实现
CustomStringConvertible:
struct HiddenField: CustomStringConvertible { let rawValue: String var description: String { return "***" // 可自定义隐藏占位符,比如部分显示:"****\(rawValue.suffix(4))" } init(_ value: String) { self.rawValue = value } }
- 让结构体支持字符串字面量初始化,减少DTO修改成本:
extension HiddenField: ExpressibleByStringLiteral { init(stringLiteral value: StringLiteralType) { self.rawValue = value } }
- 修改DTO中的字段类型:
struct UserDTO { let id: String let password: HiddenField // 只改类型,初始化逻辑完全不变 let phone: HiddenField } // 初始化和原来写法一致 let user = UserDTO(id: "123", password: "mypassword", phone: "13800138000")
这种方式只需要替换DTO中敏感字段的类型,初始化代码不用动,就能实现打印/日志时自动隐藏。
方案B:属性包装器(更简洁)
- 定义属性包装器:
@propertyWrapper struct SensitiveField { private let hiddenValue: String var wrappedValue: String { get { hiddenValue } } var projectedValue: String { "***" // 隐藏后的显示值 } init(wrappedValue value: String) { self.hiddenValue = value } }
- 扩展
CustomStringConvertible让DTO自动使用投影值:
extension UserDTO: CustomStringConvertible { var description: String { return "UserDTO(id: \(id), password: \(password.projectedValue), phone: \(phone.projectedValue))" } }
- DTO中标记敏感字段:
struct UserDTO { let id: String @SensitiveField let password: String @SensitiveField let phone: String }
这种方式不需要修改字段类型,只需要给敏感字段加@SensitiveField注解,配合DTO的CustomStringConvertible实现,就能自动隐藏。
两种方案都比方案5的修改量小,扩展性更强,后续新增敏感字段只需要重复对应步骤即可。
内容的提问来源于stack exchange,提问作者olha
相关产品推荐
相关产品推荐

