Swift 解码和编码自定义类型
Swift Decode and Encode Custom Types
我在 Swift 中对我的 class 之一进行解码和编码时遇到困难。我尝试按照 Encoding and Decoding Custom Types 文档进行操作,但没有成功。
我的class布局如下:
public struct MapLocation: Identifiable, Codable {
@DocumentID public var id: String?
let originLocation: [MapLandmark]
let destinationLocation: [MapLandmark]
enum CodingKeys: String, CodingKey {
case originLocation
case destinationLocation
}
}
import Foundation
import MapKit
struct MapLandmark: Codable {
let placemark: MKPlacemark
var id: UUID {
return UUID()
}
var name: String {
self.placemark.name ?? ""
}
var title: String {
self.placemark.title ?? ""
}
var coordinate: CLLocationCoordinate2D {
self.placemark.coordinate
}
}
我已经尝试从上面 link 添加编码和解码 classes,但保持 运行 错误。实施解决方案的最佳方式是什么?
编辑:
我忘了提到我得到的错误是:
"Type 'MapLandmark' does not conform to protocol 'Decodable'"
"Type 'MapLandmark' does not conform to protocol 'Encodable"
MKPlacemark
符合NSSecureCoding
。您可以只使用 NSKeyedArchiver
和 NSKeyedUnarchiver
到 encode/decode 它。 UUID
已经符合 Codable
。尝试如下:
import MapKit
extension NSSecureCoding {
func archived() throws -> Data {
try NSKeyedArchiver.archivedData(withRootObject: self, requiringSecureCoding: false)
}
}
extension Data {
func unarchived<T: NSSecureCoding>() throws -> T? {
try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(self) as? T
}
}
struct MapLandmark: Codable {
let placemark: MKPlacemark
let id: UUID
func encode(to encoder: Encoder) throws {
var unkeyedContainer = encoder.unkeyedContainer()
try unkeyedContainer.encode(placemark.archived())
try unkeyedContainer.encode(id)
}
public init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
placemark = try container.decode(Data.self).unarchived()!
id = try container.decode(UUID.self)
}
}
我在 Swift 中对我的 class 之一进行解码和编码时遇到困难。我尝试按照 Encoding and Decoding Custom Types 文档进行操作,但没有成功。
我的class布局如下:
public struct MapLocation: Identifiable, Codable {
@DocumentID public var id: String?
let originLocation: [MapLandmark]
let destinationLocation: [MapLandmark]
enum CodingKeys: String, CodingKey {
case originLocation
case destinationLocation
}
}
import Foundation
import MapKit
struct MapLandmark: Codable {
let placemark: MKPlacemark
var id: UUID {
return UUID()
}
var name: String {
self.placemark.name ?? ""
}
var title: String {
self.placemark.title ?? ""
}
var coordinate: CLLocationCoordinate2D {
self.placemark.coordinate
}
}
我已经尝试从上面 link 添加编码和解码 classes,但保持 运行 错误。实施解决方案的最佳方式是什么?
编辑: 我忘了提到我得到的错误是:
"Type 'MapLandmark' does not conform to protocol 'Decodable'"
"Type 'MapLandmark' does not conform to protocol 'Encodable"
MKPlacemark
符合NSSecureCoding
。您可以只使用 NSKeyedArchiver
和 NSKeyedUnarchiver
到 encode/decode 它。 UUID
已经符合 Codable
。尝试如下:
import MapKit
extension NSSecureCoding {
func archived() throws -> Data {
try NSKeyedArchiver.archivedData(withRootObject: self, requiringSecureCoding: false)
}
}
extension Data {
func unarchived<T: NSSecureCoding>() throws -> T? {
try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(self) as? T
}
}
struct MapLandmark: Codable {
let placemark: MKPlacemark
let id: UUID
func encode(to encoder: Encoder) throws {
var unkeyedContainer = encoder.unkeyedContainer()
try unkeyedContainer.encode(placemark.archived())
try unkeyedContainer.encode(id)
}
public init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
placemark = try container.decode(Data.self).unarchived()!
id = try container.decode(UUID.self)
}
}