Search code examples
jsonswiftxmlaugmented-realityarkit

ARKit 4.0 – Is it possible to convert ARWorldMap data to JSON file?


I'd like to know whether it is possible to convert a worldMap binary data (that stores a space-mapping state and set of ARAnchors) to json or xml file?

func writeWorldMap(_ worldMap: ARWorldMap, to url: URL) throws {

    let data = try NSKeyedArchiver.archivedData(withRootObject: worldMap, 
                                         requiringSecureCoding: true)
    try data.write(to: url)
}

If this possible, what tools can I use for that?


Solution

  • I am afraid that the only way to do this is by wrapping the ARWorldMap object into a Codable object like that:

    struct ARData {
        var worldMap: ARWorldMap?
    }
    
    extension ARData: Codable {
        enum CodingKeys: String, CodingKey {
            case worldMap
        }
        
        init(from decoder: Decoder) throws {
            let container = try decoder.container(keyedBy: CodingKeys.self)
    
            let worldMapData = try container.decode(Data.self, forKey: .worldMap)
            worldMap = try NSKeyedUnarchiver.unarchivedObject(ofClass: ARWorldMap.self, from: worldMapData)
        }
        
        func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            
            if let worldMap = worldMap {
                let colorData = try NSKeyedArchiver.archivedData(withRootObject: worldMap, requiringSecureCoding: true)
                try container.encode(colorData, forKey: .worldMap)
            }
        }
    }
    

    To encode an instance of that object to JSON use the encode(:) function of the JSONEncoder:

    let arData = ARData(worldMap: worldMap)
    let encoder = JSONEncoder()
    
    do {
        let jsonData = try encoder.encode(arData)
    } catch {
        print(error)
    }
    

    By default, JSONEncoder will convert the ARWorldMap data to a Base64 string that can be read using JSONDecoder:

    let decoder = JSONDecoder()
    
    do {
        let decoded = try decoder.decode(ARData.self, from: jsonData)
    } catch {
        print(error)
    }