Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Codable extension to CoreLocation classes

I need to add Codable to two classes. One is CLLocationCoordinate2D and the second one CLCircularRegion.

I have no issue with CLLocationCoordinate2D and it works by doing that:

extension CLLocationCoordinate2D: Codable {
    public enum CodingKeys: String, CodingKey {
        case latitude
        case longitude
    }

    public 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)
        }

    public init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        latitude = try values.decode(Double.self, forKey: .latitude)
        longitude = try values.decode(Double.self, forKey: .longitude)
    }
}

But I have a lot of issues trying to do the same thing with CLCircularRegion. Since radius and center are read-only properties I cannot really create them in the same way. The other problem is why I was able to create public init in CLLocationCoordinate2D and for Codable extension in CLCircularRegion I'm getting error:

enter image description here

I see the point of public, but required? And of course required will fail beacouse it's extension not a class. So one solution for this issue will be create abstraction class that will contain all fields and build region in initializer I know that, but there is any other way to extend Codable to existing class that's not support by Apple yet?

like image 384
Jakub Avatar asked Jan 03 '23 15:01

Jakub


2 Answers

Inspired by Artem answer I solved my issue by storing in the object latitude and longitude in Double format. The CLLocation is then returned as computed property reading the two stored values:

private var latitude: Double = 0.0
private var longitude: Double = 0.0    

var location: CLLocation {
    return CLLocation(latitude: latitude, longitude: longitude)
}

In your case with CLCircularRegion you will also need to save radius and center in a similar fashion.

like image 149
Nicholas Allio Avatar answered Jan 05 '23 16:01

Nicholas Allio


I moved CLCircularRegion to computed variable, and it automatically works with Codable now:

var region: CLCircularRegion { return CLCircularRegion(center: self.coordinates, radius: 10.0, identifier: identifier) }
like image 22
Artem Katlenok Avatar answered Jan 05 '23 18:01

Artem Katlenok