【问题标题】:How can I make Firestore's GeoPoint conform to Swifts Codable protocol?如何使 Firestore GeoPoint 符合 Swift Codable 协议?
【发布时间】:2025-12-15 02:25:01
【问题描述】:

我正在尝试使来自 firestore 查询的响应符合 swift 4 可编码协议。但是我无法使GeoPoint 符合Codable,因为该类已在 Firestore 库中声明。感谢您的帮助。

struct Landmark:Codable {
let name:String
let location:GeoPoint 
}

【问题讨论】:

  • 您找到解决方案或变通方法了吗?
  • @Zonker.in.Geneva 不幸的是,我没有使用 geohashes 来代替
  • 我正在查看上面的 GitHub 链接。 CodableGeoPoint 的代码看起来很有希望。你试过吗?发生了什么?

标签: ios swift firebase google-cloud-firestore


【解决方案1】:

您可以像这样将您的声明保留为地理点:

struct Landmark: Codable {
    let name: String
    let location: GeoPoint
}

但是你必须在你的文件中添加这个扩展,让 Swift 知道 Firebase 的地理点的结构。

import FirebaseFirestore

fileprivate protocol CodableGeoPoint: Codable {
  var latitude: Double { get }
  var longitude: Double { get }

  init(latitude: Double, longitude: Double)
}

fileprivate enum GeoPointKeys: String, CodingKey {
  case latitude
  case longitude
}

extension CodableGeoPoint {
  public init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: GeoPointKeys.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)
  }

  public func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: GeoPointKeys.self)
    try container.encode(latitude, forKey: .latitude)
    try container.encode(longitude, forKey: .longitude)
  }
}

extension GeoPoint: CodableGeoPoint {}

【讨论】:

    【解决方案2】:

    您是否尝试过扩展?

    extension GeoPoint: Codable {
    // custom codable implementation
    }
    

    基本上,扩展允许您向现有类/结构添加函数、计算属性和协议一致性

    【讨论】:

    • 感谢您的回复,我已经尝试过此操作并在尝试构建时收到以下错误>“无法在与类型不同的文件的扩展中自动合成 'Decodable' 的实现”和“'Encodable' 的实现不能自动合成到与类型不同的文件的扩展中”
    • 对正确的方法很感兴趣,我遇到了同样的问题