使 CLCircularRegion 可编码
Making CLCircularRegion Codable
我正在尝试(在操场上)使 CLCircularRegion Codable。但是我有一个我无法修复的错误:错误:初始化程序要求 'init(from:)' 只能由非最终 class 'CLCircularRegion' 定义中的 'required' 初始化程序满足。有什么想法吗?
import UIKit
import MapKit
// MARK: - CLLocationCoordinate2D
extension CLLocationCoordinate2D: Codable {
public func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(longitude)
try container.encode(latitude)
}
public init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
let longitude = try container.decode(CLLocationDegrees.self)
let latitude = try container.decode(CLLocationDegrees.self)
self.init(latitude: latitude, longitude: longitude)
}
}
// MARK: - CLLocationCoordinate2D
extension CLCircularRegion : Codable {
public func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(identifier)
try container.encode(center)
try container.encode(radius)
}
public required init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
let identifier = try container.decode(String.self)
let center = try container.decode(CLLocationCoordinate2D.self)
let radius = try container.decode(CLLocationDistance.self)
self.init(center: center, radius: radius, identifier: identifier)
}
}
let coordinate = CLLocationCoordinate2D(latitude: 45.123, longitude: 5.678)
let region = CLCircularRegion(center: coordinate, radius: 100, identifier: "identifierTest")
// encode
if let jsonData = try? JSONEncoder().encode(region), let jsonString = String(data: jsonData, encoding: .utf8) {
print(jsonString)
// decode
if let decodedRegion = try? JSONDecoder().decode(CLCircularRegion.self, from: jsonData) {
print(decodedRegion)
}
}
一种解决方案是将 class 包装在符合 Codable
的结构中
struct CodableCircularRegion : Codable {
var region: CLCircularRegion?
public func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(region?.identifier)
try container.encode(region?.center)
try container.encode(region?.radius)
}
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
let identifier = try container.decode(String.self)
let center = try container.decode(CLLocationCoordinate2D.self)
let radius = try container.decode(CLLocationDistance.self)
region = CLCircularRegion(center: center, radius: radius, identifier: identifier)
}
init(_ region: CLCircularRegion) {
self.region = region
}
}
和encoding/decoding差不多
if let jsonData = try? JSONEncoder().encode(CodableCircularRegion(region)), let jsonString = String(data: jsonData, encoding: .utf8) {
print(jsonString)
// decode
if let decodedRegion = try? JSONDecoder().decode(CodableCircularRegion.self, from: jsonData) {
print(decodedRegion.region)
}
}
你不能这样做。 CLCircularRegion
不是 final
class。当你扩展一个非最终的 class 时,你只能在扩展中编写 convenience
初始值设定项。 Decodable
指定必须声明初始化器 required
。
但我们刚刚看到您不能这样做,因为 Swift 不允许您在扩展中声明 required
个初始化程序。
顺便说一句,一般来说,扩展其他人的类型以使其符合 Codable
并不是一个好主意,因为在将来某个时候编写该类型的人也可能会添加 Codable
一致性,并且很可能他们的实现与您的实现不匹配,这将导致一些很难诊断的错误。
如前所述,最好的办法是将 CLCircularRegion
包装在符合 Codable
.
的结构中
我正在尝试(在操场上)使 CLCircularRegion Codable。但是我有一个我无法修复的错误:错误:初始化程序要求 'init(from:)' 只能由非最终 class 'CLCircularRegion' 定义中的 'required' 初始化程序满足。有什么想法吗?
import UIKit
import MapKit
// MARK: - CLLocationCoordinate2D
extension CLLocationCoordinate2D: Codable {
public func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(longitude)
try container.encode(latitude)
}
public init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
let longitude = try container.decode(CLLocationDegrees.self)
let latitude = try container.decode(CLLocationDegrees.self)
self.init(latitude: latitude, longitude: longitude)
}
}
// MARK: - CLLocationCoordinate2D
extension CLCircularRegion : Codable {
public func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(identifier)
try container.encode(center)
try container.encode(radius)
}
public required init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
let identifier = try container.decode(String.self)
let center = try container.decode(CLLocationCoordinate2D.self)
let radius = try container.decode(CLLocationDistance.self)
self.init(center: center, radius: radius, identifier: identifier)
}
}
let coordinate = CLLocationCoordinate2D(latitude: 45.123, longitude: 5.678)
let region = CLCircularRegion(center: coordinate, radius: 100, identifier: "identifierTest")
// encode
if let jsonData = try? JSONEncoder().encode(region), let jsonString = String(data: jsonData, encoding: .utf8) {
print(jsonString)
// decode
if let decodedRegion = try? JSONDecoder().decode(CLCircularRegion.self, from: jsonData) {
print(decodedRegion)
}
}
一种解决方案是将 class 包装在符合 Codable
的结构中struct CodableCircularRegion : Codable {
var region: CLCircularRegion?
public func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(region?.identifier)
try container.encode(region?.center)
try container.encode(region?.radius)
}
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
let identifier = try container.decode(String.self)
let center = try container.decode(CLLocationCoordinate2D.self)
let radius = try container.decode(CLLocationDistance.self)
region = CLCircularRegion(center: center, radius: radius, identifier: identifier)
}
init(_ region: CLCircularRegion) {
self.region = region
}
}
和encoding/decoding差不多
if let jsonData = try? JSONEncoder().encode(CodableCircularRegion(region)), let jsonString = String(data: jsonData, encoding: .utf8) {
print(jsonString)
// decode
if let decodedRegion = try? JSONDecoder().decode(CodableCircularRegion.self, from: jsonData) {
print(decodedRegion.region)
}
}
你不能这样做。 CLCircularRegion
不是 final
class。当你扩展一个非最终的 class 时,你只能在扩展中编写 convenience
初始值设定项。 Decodable
指定必须声明初始化器 required
。
但我们刚刚看到您不能这样做,因为 Swift 不允许您在扩展中声明 required
个初始化程序。
顺便说一句,一般来说,扩展其他人的类型以使其符合 Codable
并不是一个好主意,因为在将来某个时候编写该类型的人也可能会添加 Codable
一致性,并且很可能他们的实现与您的实现不匹配,这将导致一些很难诊断的错误。
如前所述,最好的办法是将 CLCircularRegion
包装在符合 Codable
.