为 ARAnchor 实施 Codable:"cannot be automatically synthesized in an extension..."
Implementing Codable for ARAnchor: "cannot be automatically synthesized in an extension..."
代码 extension ARAnchor: Codable {}
产生错误:
"Implementation of 'Decodable' cannot be automatically synthesized in an extension in a different file to the type".
这是什么意思?我能够以类似的方式为另一种本机类型实现 Codable
,没有任何错误。
Swift 编译器 AFAIK 目前不支持在不同的源文件中综合符合 Codable
、Equatable
和 Hashable
。有关跟踪此问题的信息,请参阅 https://bugs.swift.org/browse/SR-6101。
由于 Codable
是 Encodable
和 Decodable
协议的类型别名,当您将它用作 type 或 泛型约束 ,它匹配符合两种协议的任何类型:
public typealias Codable = Decodable & Encodable
At the moment (Xcode 10.2.1 / Swift 5.0.1) Codable
currently isn't supported yet if an extension in one file adds conformance in a different file. Check this out at https://bugs.swift.org/.
希望对您有所帮助。
您可以创建一个实现 Codable
的容器对象,然后使用它来编码和解码锚点。我在操场上试过这段代码,它对我有用。您需要根据需要从锚点获得的数据对其进行调整;例如,我编码了 name
但这对你来说可能没用,如果你的锚是在没有名字的情况下初始化的,它甚至可能会中断。你也可以用 simd_float4x4
.
做同样的事情
import Foundation
import ARKit
class AnchorContainer: Codable {
let anchor: ARAnchor
init(anchor: ARAnchor) {
self.anchor = anchor
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let name = try container.decode(String.self, forKey: .name)
let transform0 = try container.decode(simd_float4.self, forKey: .transform0)
let transform1 = try container.decode(simd_float4.self, forKey: .transform1)
let transform2 = try container.decode(simd_float4.self, forKey: .transform2)
let transform3 = try container.decode(simd_float4.self, forKey: .transform3)
let matrix = simd_float4x4(columns: (transform0, transform1, transform2, transform3))
anchor = ARAnchor(name: name, transform: matrix)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(anchor.name, forKey: .name) // Might want to make sure that the name is not nil here
try container.encode(anchor.transform.columns.0, forKey: .transform0)
try container.encode(anchor.transform.columns.1, forKey: .transform1)
try container.encode(anchor.transform.columns.2, forKey: .transform2)
try container.encode(anchor.transform.columns.3, forKey: .transform3)
}
enum CodingKeys: String, CodingKey {
case name
case transform0
case transform1
case transform2
case transform3
}
}
// EXAMPLE:
let anchor = ARAnchor(name: "Bill", transform: simd_float4x4(float4(repeating: 4), float4(repeating: 5), float4(repeating: 6), float4(repeating: 7))) // Make a arbitrary anchor
print(anchor) // Figure out what it's value is
do {
let data = try JSONEncoder().encode(AnchorContainer(anchor: anchor))
let anchorDecode = try JSONDecoder().decode(AnchorContainer.self, from: data)
print(anchorDecode.anchor) // Print the value after decoding to make sure that the result is the same
} catch {
print(error.localizedDescription)
}
代码 extension ARAnchor: Codable {}
产生错误:
"Implementation of 'Decodable' cannot be automatically synthesized in an extension in a different file to the type".
这是什么意思?我能够以类似的方式为另一种本机类型实现 Codable
,没有任何错误。
Swift 编译器 AFAIK 目前不支持在不同的源文件中综合符合 Codable
、Equatable
和 Hashable
。有关跟踪此问题的信息,请参阅 https://bugs.swift.org/browse/SR-6101。
由于 Codable
是 Encodable
和 Decodable
协议的类型别名,当您将它用作 type 或 泛型约束 ,它匹配符合两种协议的任何类型:
public typealias Codable = Decodable & Encodable
At the moment (Xcode 10.2.1 / Swift 5.0.1)
Codable
currently isn't supported yet if an extension in one file adds conformance in a different file. Check this out at https://bugs.swift.org/.
希望对您有所帮助。
您可以创建一个实现 Codable
的容器对象,然后使用它来编码和解码锚点。我在操场上试过这段代码,它对我有用。您需要根据需要从锚点获得的数据对其进行调整;例如,我编码了 name
但这对你来说可能没用,如果你的锚是在没有名字的情况下初始化的,它甚至可能会中断。你也可以用 simd_float4x4
.
import Foundation
import ARKit
class AnchorContainer: Codable {
let anchor: ARAnchor
init(anchor: ARAnchor) {
self.anchor = anchor
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let name = try container.decode(String.self, forKey: .name)
let transform0 = try container.decode(simd_float4.self, forKey: .transform0)
let transform1 = try container.decode(simd_float4.self, forKey: .transform1)
let transform2 = try container.decode(simd_float4.self, forKey: .transform2)
let transform3 = try container.decode(simd_float4.self, forKey: .transform3)
let matrix = simd_float4x4(columns: (transform0, transform1, transform2, transform3))
anchor = ARAnchor(name: name, transform: matrix)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(anchor.name, forKey: .name) // Might want to make sure that the name is not nil here
try container.encode(anchor.transform.columns.0, forKey: .transform0)
try container.encode(anchor.transform.columns.1, forKey: .transform1)
try container.encode(anchor.transform.columns.2, forKey: .transform2)
try container.encode(anchor.transform.columns.3, forKey: .transform3)
}
enum CodingKeys: String, CodingKey {
case name
case transform0
case transform1
case transform2
case transform3
}
}
// EXAMPLE:
let anchor = ARAnchor(name: "Bill", transform: simd_float4x4(float4(repeating: 4), float4(repeating: 5), float4(repeating: 6), float4(repeating: 7))) // Make a arbitrary anchor
print(anchor) // Figure out what it's value is
do {
let data = try JSONEncoder().encode(AnchorContainer(anchor: anchor))
let anchorDecode = try JSONDecoder().decode(AnchorContainer.self, from: data)
print(anchorDecode.anchor) // Print the value after decoding to make sure that the result is the same
} catch {
print(error.localizedDescription)
}