Skip to content

Instantly share code, notes, and snippets.

@magicien
Created August 23, 2017 08:01
Show Gist options
  • Save magicien/918772c9f04f23a413d8d53e25d7e7e7 to your computer and use it in GitHub Desktop.
Save magicien/918772c9f04f23a413d8d53e25d7e7e7 to your computer and use it in GitHub Desktop.
import Foundation
let json = """
{
"nodes": [
{
"extensions": {
"KHR_materials_common": {
"light": 0
}
}
}
],
"materials": [
{
"extensions": {
"KHR_materials_common": {
"technique": "BLINN"
}
}
}
]
}
""".data(using: .utf8)!
struct KHRMaterialsCommon_NodeExtension: Codable {
let light: Int
}
struct KHRMaterialsCommon_MaterialExtension: Codable {
let technique: String
}
struct KHRMaterialsCommon: Codable {
let data: Any
init(from decoder: Decoder) throws {
// 上の階層が nodes なら NodeExtension、materials なら MaterialExtension を読み込みたい。
// codingPath[3] は KHR_materials_common、[2] は extensions、[1] は nil、[0] は nodes か materials
let level = decoder.codingPath.count
guard level >= 4 else {
throw DecodingError.typeMismatch(KHRMaterialsCommon.self, .init(codingPath: decoder.codingPath, debugDescription: "something is wrong"))
}
guard let parentName = decoder.codingPath[level - 4]?.stringValue else {
throw DecodingError.typeMismatch(KHRMaterialsCommon.self, .init(codingPath: decoder.codingPath, debugDescription: "something is wrong"))
}
switch parentName {
case "nodes":
self.data = try KHRMaterialsCommon_NodeExtension(from: decoder)
case "materials":
self.data = try KHRMaterialsCommon_MaterialExtension(from: decoder)
default:
throw DecodingError.typeMismatch(KHRMaterialsCommon.self, .init(codingPath: decoder.codingPath, debugDescription: "unknown parent: \(parentName)"))
}
}
func encode(to encoder: Encoder) throws {
// do something
}
}
struct Extensions: Codable {
let materialsCommon: KHRMaterialsCommon?
enum CodingKeys: String, CodingKey {
case materialsCommon = "KHR_materials_common"
}
}
struct Material: Codable {
let extensions: Extensions?
}
struct Node: Codable {
let extensions: Extensions?
}
struct GLTF: Codable {
let nodes: [Node]
let materials: [Material]
}
do {
let decoder = JSONDecoder()
let gltf = try decoder.decode(GLTF.self, from: json)
if let nodeExtension = gltf.nodes[0].extensions?.materialsCommon?.data as? KHRMaterialsCommon_NodeExtension {
print("light: \(nodeExtension.light)")
}
if let materialExtension = gltf.materials[0].extensions?.materialsCommon?.data as? KHRMaterialsCommon_MaterialExtension {
print("technique: \(materialExtension.technique)")
}
} catch DecodingError.keyNotFound(let key, let context) {
print("keyNotFound: \(key): \(context)")
} catch DecodingError.typeMismatch(let type, let context) {
print("typeMismatch: \(type): \(context)")
} catch {
print("\(error.localizedDescription)")
}
/*
light: 0
technique: BLINN
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment