Swift4中使用JSONDecodable报错:UserRegister未遵循Decodable协议
解决Swift 4中
UserRegister不遵循Decodable协议的问题 我来帮你排查这个错误的原因,你碰到的"Type UserRegister does not conform to protocol 'Decodable'",主要是你的模型结构体里存在几个不符合Decodable协议要求的地方,咱们一步步来看:
首先先还原你给出的模型代码:
struct UserRegister: Decodable { let id : NSInteger let name : String? let email : String? let cities : Array<Any>? let tax : [tax] let username : [username] } struct tax : Decodable { let deviceId : NSInteger? let financialYear : String? let country : String? let name : String? let state : String? let taxCode : String? let v... }
错误原因分析
Array<Any>?类型不符合要求:Decodable协议要求所有属性的类型(包括集合的元素类型)都必须遵循Decodable,但Any并没有遵循这个协议,所以cities这个属性直接导致整个结构体无法符合协议。你需要把Any换成具体的、遵循Decodable的类型,比如如果JSON里cities是字符串数组,就改成[String]?;如果是自定义对象数组,就定义对应的City结构体并改成[City]?。- 嵌套结构体的问题:你定义的
tax和username结构体用了小写开头(虽然语法允许,但不符合Swift大驼峰的命名规范),而且username结构体完全没有给出定义——如果它没有遵循Decodable,或者定义不完整,都会让UserRegister无法满足协议要求。另外你的tax结构体代码没写完(let v...),未完成的属性定义也会导致它不满足Decodable。 - Objective-C类型的使用:
NSInteger是Objective-C的类型,虽然能勉强解码,但Swift里更推荐使用原生的Int类型,这样更符合Swift的编码习惯,也能避免一些潜在的类型转换问题。
修正后的示例代码
// 遵循Swift命名规范,结构体用大驼峰 struct UserRegister: Decodable { let id: Int // 替换NSInteger为原生Int let name: String? let email: String? let cities: [String]? // 假设cities是字符串数组,根据实际JSON调整 let tax: [Tax] let username: [Username] } struct Tax: Decodable { let deviceId: Int? let financialYear: String? let country: String? let name: String? let state: String? let taxCode: String? // 补充完整之前未写完的属性,比如let vatRate: Double?之类的,确保类型都可解码 } // 补充Username结构体的定义,必须遵循Decodable struct Username: Decodable { // 根据你的JSON结构添加对应属性,比如: let value: String? let isVerified: Bool? }
额外注意事项
如果你的JSON键名和结构体属性名不一致(比如JSON里是user_name而你用了username),需要通过CodingKeys枚举来做映射:
extension UserRegister { enum CodingKeys: String, CodingKey { case id case name case email case cities case tax case username = "user_name" // 这里映射JSON的键名 } }
内容的提问来源于stack exchange,提问作者Zac24
相关产品推荐
相关产品推荐

