Explit Conformance to Codable Removes Memberwise Initializer Generation on Structs

Explit conformance to Codable removes memberwise initializer generation on structs

You can implement the Codable conformance in an extension.

When adding any struct initializer in an extension, the memberwise initializer will not be removed.

struct MyStruct {
var name: String
}
extension MyStruct: Codable {} // preserves memberwise initializer

MyStruct(name: "Tim")

swift 4 firebase GeoPoint decode

I was able to extend the GeoPoint class and make it Codable. That is how I solved it.

import UIKit

final class MyGeoPoint: GeoPoint, Codable
{
override init(latitude: Double, longitude: Double)
{
super.init(latitude: latitude, longitude: longitude)
}

private enum CodingKeys: String, CodingKey
{
case latitude = "_latitude"
case longitude = "_longitude"
}

init(from decoder: Decoder) throws
{
let container = try decoder.container(keyedBy: CodingKeys.self)
var lat:Double = 0
var lon:Double = 0

do
{
lat = try container.decode(Double.self, forKey: .latitude)
}
catch
{
print("no latitude for MyGeoPoint")
}

do
{
lon = try container.decode(Double.self, forKey: .longitude)
}
catch
{
print("no longitude for MyGeoPoint")
}

super.init(latitude: lat, longitude: lon)
}

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

}

Now I can use my original Data class to consume the JSON response from Google, using my extended MyGeoPoint class (instead of Google's GeoPoint directly)

final class Data: Codable
{
var location:MyGeoPoint = MyGeoPoint(latitude:0,longitude:0)
private enum CodingKeys: String, CodingKey
{
case geoloc
}
init(from decoder: Decoder) throws
{
let values = try decoder.container(keyedBy: CodingKeys.self)

do
{
//no error here anymore
location = try values.decode(MyGeoPoint.self, forKey: .geoloc)
}
catch
{
print("data has location in server response\n")
}

}

func encode(to encoder: Encoder) throws
{
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(location, forKey: .geoloc)

}
}


Related Topics



Leave a reply



Submit