Implementing Codable for ARAnchor: “cannot be automatically synthesized in an extension…”

后端 未结 3 1322
無奈伤痛
無奈伤痛 2021-01-16 03:59

The code extension ARAnchor: Codable {} produces the error:

\"Implementation of \'Decodable\' cannot be automatically synthesized in an extension in a d

3条回答
  •  再見小時候
    2021-01-16 04:45

    You could create a container object that implements Codable and then use that to encode and decode the anchor. I tried this code in a playground and it work for me. You'll want to adapt it for which data you want from the anchor; for example I encoded name but that might be useless to you and it might even break if your anchor was initialized without a name. You could also do the same thing with 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)
    }
    

提交回复
热议问题