0

I am currently trying to make an extension to render CLLocation codable. To do so, I am trying to replicate the example on this thread: Swift - Codable Decode array of arrays of CLLocation

I have the following structure:

struct FriendBase: Identifiable, Encodable {
    var id: UUID = UUID()
    var firstName: String
    var lastKnownLocation: CLLocation? = nil
    
    enum CodingKeys: String, CodingKey {
        case id
        case firstName
        case lastKnownLocation
    }
}

extension FriendBase: Decodable {
    init(from decoder: Decoder) throws {
        let value = try decoder.container(keyedBy: CodingKeys.self)
        
        id = try value.decode(UUID.self, forKey: .id)
        firstName = try value.decode(String.self, forKey: .firstName)
        lastKnownLocation = try value.decode(Location.self, forKey: .lastKnownLocation)
    }
}

I implemented an extension based on the thread provided above which look like this:

extension CLLocation: Encodable {
    enum CodingKeys: String, CodingKey {
        case latitude
        case longitude
        case altitude
        case horizontalAccuracy
        case verticalAccuracy
        case speed
        case course
        case timestamp
    }
    
    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(coordinate.latitude, forKey: .latitude)
        try container.encode(coordinate.longitude, forKey: .longitude)
        try container.encode(altitude, forKey: .altitude)
        try container.encode(horizontalAccuracy, forKey: .horizontalAccuracy)
        try container.encode(verticalAccuracy, forKey: .verticalAccuracy)
        try container.encode(speed, forKey: .speed)
        try container.encode(course, forKey: .course)
        try container.encode(timestamp, forKey: .timestamp)
    }
}

struct Location: Codable {
    let latitude: CLLocationDegrees
    let longitude: CLLocationDegrees
    let altitude: CLLocationDistance
    let horizontalAccuracy: CLLocationAccuracy
    let verticalAccuracy: CLLocationAccuracy
    let speed: CLLocationSpeed
    let course: CLLocationDirection
    let timestamp: Date
}

extension CLLocation {
    convenience init(model: Location) {
      self.init(coordinate: CLLocationCoordinate2DMake(model.latitude, model.longitude), altitude: model.altitude, horizontalAccuracy: model.horizontalAccuracy, verticalAccuracy: model.verticalAccuracy, course: model.course, speed: model.speed, timestamp: model.timestamp)
     }
}

I am currently getting the following error: Cannot assign value of type 'Location' to type 'CLLocation?' on line lastKnownLocation = try value.decode(Location.self, forKey: .lastKnownLocation).

Thanks for your help, I am new with Swift and I believe that I should not be so far for the final solution.

Regards

1
  • As said, I based my test on the suggested article, but without success. Commented Aug 11, 2023 at 4:07

1 Answer 1

0

On the line:

lastKnownLocation = try value.decode(Location.self, forKey: .lastKnownLocation)

the property lastKnownLocation is declared with a type of CLLocation?.

The code:

value.decode(Location.self, forKey: .lastKnownLocation)

will return a value of type Location.

Hence the error since you are trying to assign a value of type Location to a property of type CLLocation?.

You added an extension that lets you create a CLLocation from a Location. Make use of that to do the needed conversion. This means that you need to change the line:

lastKnownLocation = try value.decode(Location.self, forKey: .lastKnownLocation)

to:

let location = try value.decode(Location.self, forKey: .lastKnownLocation)
lastKnownLocation = CLLocation(model: location)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.