Swift自定义Location类遵循Decodable与MKAnnotation报协议不兼容错误
报错核心原因
你的代码存在两个导致无法遵守Decodable协议的问题:
CLLocationCoordinate2D系统类型默认没有实现Decodable协议,你的类中包含该类型的存储属性coordinate,编译器无法自动生成解码逻辑- 你的JSON结构中不存在与
coordinate对应的字段,且自定义的初始化方法没有给coordinate属性赋值,即使编译通过运行也会崩溃
最优修复方案
把coordinate改为计算属性,无需参与解码,直接用已有的latitude、longitude生成坐标即可,编译器会自动合成Decodable的实现,代码改动最小:
class Location: NSObject, Decodable, Identifiable, MKAnnotation { // 明确指定需要解码的属性,排除coordinate enum CodingKeys: String, CodingKey { case id, name, latitude, longitude } var id: Int var name: String var latitude: Double var longitude: Double // 改为计算属性,满足MKAnnotation协议要求 var coordinate: CLLocationCoordinate2D { CLLocationCoordinate2D(latitude: latitude, longitude: longitude) } init(id : Int, name : String, latitude : Double, longitude : Double){ self.id = id self.name = name self.latitude = latitude self.longitude = longitude } }
可选方案(需要保留coordinate为存储属性时使用)
先给CLLocationCoordinate2D添加Decodable协议实现:
extension CLLocationCoordinate2D: Decodable { enum CodingKeys: String, CodingKey { case latitude, longitude } public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let latitude = try container.decode(Double.self, forKey: .latitude) let longitude = try container.decode(Double.self, forKey: .longitude) self.init(latitude: latitude, longitude: longitude) } }
之后在Location类的CodingKeys中排除coordinate,在初始化方法中手动给coordinate赋值即可。
额外注意
你当前粘贴的JSON结构不完整,缺少末尾的]和},解码前需要补全为合法JSON格式:
{ "locations": [ { "id": 0, "name": "New York City", "latitude": 40.71, "longitude": -74 }, { "id": 1, "name": "Barcelona", "latitude": 41.38, "longitude": 2.17 } ] }
内容的提问来源于stack exchange,提问作者Emmanuel Leicher
相关产品推荐
相关产品推荐

