GeoPoint+Codable.swift 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. /*
  2. * Copyright 2018 Google
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. import FirebaseFirestore
  17. /**
  18. * A protocol describing the encodable properties of a GeoPoint.
  19. *
  20. * Note: this protocol exists as a workaround for the Swift compiler: if the GeoPoint class
  21. * was extended directly to conform to Codable, the methods implementing the protocol would be need
  22. * to be marked required but that can't be done in an extension. Declaring the extension on the
  23. * protocol sidesteps this issue.
  24. */
  25. private protocol CodableGeoPoint: Codable {
  26. var latitude: Double { get }
  27. var longitude: Double { get }
  28. init(latitude: Double, longitude: Double)
  29. }
  30. /** The keys in a GeoPoint. Must match the properties of CodableGeoPoint. */
  31. private enum GeoPointKeys: String, CodingKey {
  32. case latitude
  33. case longitude
  34. }
  35. /**
  36. * An extension of GeoPoint that implements the behavior of the Codable protocol.
  37. *
  38. * Note: this is implemented manually here because the Swift compiler can't synthesize these methods
  39. * when declaring an extension to conform to Codable.
  40. */
  41. extension CodableGeoPoint {
  42. public init(from decoder: Decoder) throws {
  43. let container = try decoder.container(keyedBy: GeoPointKeys.self)
  44. let latitude = try container.decode(Double.self, forKey: .latitude)
  45. let longitude = try container.decode(Double.self, forKey: .longitude)
  46. self.init(latitude: latitude, longitude: longitude)
  47. }
  48. public func encode(to encoder: Encoder) throws {
  49. var container = encoder.container(keyedBy: GeoPointKeys.self)
  50. try container.encode(latitude, forKey: .latitude)
  51. try container.encode(longitude, forKey: .longitude)
  52. }
  53. }
  54. /** Extends GeoPoint to conform to Codable. */
  55. extension GeoPoint: CodableGeoPoint {}