Реализация Codable для ARAnchor: «не может быть автоматически синтезирован в расширении ...» - PullRequest
1 голос
/ 14 апреля 2019

Код extension ARAnchor: Codable {} выдает ошибку:

"Реализация 'Decodable' не может быть автоматически синтезирована в расширении в файле, отличном от типа".

Что это значит?Я смог реализовать Codable для другого собственного типа подобным образом без каких-либо ошибок.

Ответы [ 3 ]

2 голосов
/ 23 апреля 2019

Вы можете создать контейнерный объект, который реализует 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)
}
1 голос
/ 14 апреля 2019

Синтез соответствия Codable, Equatable и Hashable в различных исходных файлах в настоящее время не поддерживается компилятором Swift AFAICT.См. https://bugs.swift.org/browse/SR-6101 для отслеживания проблемы.

0 голосов
/ 14 апреля 2019

Поскольку Codable является псевдонимом типа для протоколов Encodable и Decodable, при его использовании в качестве типа или универсальногоограничение , оно соответствует любому типу, который соответствует обоим протоколам:

public typealias Codable = Decodable & Encodable

В настоящий момент (Xcode 10.2.1 / Swift 5.0.1) Codable в настоящее время нет 'Пока не поддерживается, если расширение в одном файле добавляет соответствие в другом файле.Проверьте это на https://bugs.swift.org/.

Надеюсь, это поможет.

...