Swift - CLOcation 数组的可编码解码数组
Swift - Codable Decode array of arrays of CLLocation
我有一个包含 CLLocation 数组的结构。这是为了支持多折线(换句话说,一堆可能不连续的线)。我希望编码和解码这些数据。我在编写编码和解码方法时遇到问题,因为默认情况下 CLLocation 不可编码。
struct MyTrack {
let coords: [[CLLocation]]?
enum CodingKeys: String, CodingKey {
case coords
}
}
extension MyTrack: Decodable {
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
coords = try values.decodeIfPresent([[CLLocation]].self, forKey: .coords)?
.map { ([=11=] as AnyObject).map { CLLocation(model: [=11=]) } }
}
}
它目前在 Xcode 中抛出两个错误:
无法将类型“[[CLLocation]].Type”的值转换为预期的参数类型“[Any?].Type”
类型 'AnyObject' 的值没有成员 'map'
非常感谢任何帮助!
因为 CLLocation 默认情况下是不可编码的,所以我按照教程围绕它创建了一个包装器结构,代码如下:
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)
}
}
您正在解码 CLLocation
,而不是您的包装器结构。您应该改为解码包装器结构。另外,你不应该转换为 AnyObject
.
extension MyTrack: Decodable {
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
coords = try values.decodeIfPresent([[Location]].self, forKey: .coords)?
.map { [=10=].map(CLLocation.init) }
}
}
我有一个包含 CLLocation 数组的结构。这是为了支持多折线(换句话说,一堆可能不连续的线)。我希望编码和解码这些数据。我在编写编码和解码方法时遇到问题,因为默认情况下 CLLocation 不可编码。
struct MyTrack {
let coords: [[CLLocation]]?
enum CodingKeys: String, CodingKey {
case coords
}
}
extension MyTrack: Decodable {
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
coords = try values.decodeIfPresent([[CLLocation]].self, forKey: .coords)?
.map { ([=11=] as AnyObject).map { CLLocation(model: [=11=]) } }
}
}
它目前在 Xcode 中抛出两个错误:
无法将类型“[[CLLocation]].Type”的值转换为预期的参数类型“[Any?].Type”
类型 'AnyObject' 的值没有成员 'map'
非常感谢任何帮助!
因为 CLLocation 默认情况下是不可编码的,所以我按照教程围绕它创建了一个包装器结构,代码如下:
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)
}
}
您正在解码 CLLocation
,而不是您的包装器结构。您应该改为解码包装器结构。另外,你不应该转换为 AnyObject
.
extension MyTrack: Decodable {
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
coords = try values.decodeIfPresent([[Location]].self, forKey: .coords)?
.map { [=10=].map(CLLocation.init) }
}
}