

[String : Any]の結合方法

swiftで開発しております。  
jsonファイルを作成する処理を作成しているのですが

[code]

    class ResultJson {
        func string(result: Result, size: CGPoint) -> String {
            let tracked = result.bodies?.first { $0.joints3D != nil }
            let bodies = [tracked].compactMap { $0 }
            let point2DGroups = bodies.map { $0.point2DDictionary }
            let point3DGroups = bodies.map { $0.point3DDictionary }
            let dict: [String : Any] = ["point2DGroups": point2DGroups,
                                        "point3DGroups": point3DGroups,
                                        "cameraResolution": size.dictionary
            ]
            
            var jsonString = ""
            do {
                let data = try JSONSerialization.data(withJSONObject: dict)
                jsonString = String(bytes: data, encoding: .utf8)!
            } catch {
                print(error)
            }
            return jsonString
        }
    }
    
[/code]

上記のように構造体データを1データのみjsonファイルに変換するのではなく、  
全データをjsonファイルに変更すべく以下のようにコードを編集しました。

[code]

    class ResultJson {
        func string(result: Result, size: CGPoint) -> String {
            let trackeds = result.bodies?.filter { $0.joints3D != nil }
            let point2DGroups[String : Any];
            let point3DGroups[String : Any];
            trackeds.forEach { tracked in
                let bodies += [tracked].compactMap { $0 }
                point2DGroups += bodies.map { $0.point2DDictionary }
                point3DGroups += bodies.map { $0.point3DDictionary }
            }
            let dict: [String : Any] = ["point2DGroups": point2DGroups,
                                        "point3DGroups": point3DGroups,
                                        "cameraResolution": size.dictionary
            ]
            
            
            var jsonString = ""
            do {
                let data = try JSONSerialization.data(withJSONObject: dict)
                jsonString = String(bytes: data, encoding: .utf8)!
            } catch {
                print(error)
            }
            return jsonString
        }
    }
    
[/code]

しかし、[String : Any]でビルドエラーが出ている状態です。  
[String : Any]の結合はどのように行えばよいのでしょうか。


CC BY-SA 4.0
2023-07-27T12:04:56.047
95780
2023-07-31T09:10:33.893
29606
question
swift json
[String : Any]の結合方法


全体像、期待している結果がわからないため、基本的なSwiftのエラー(構文)を直しました。  
これで少しエラーがわかりやすいと思います。

[code]

    class ResultJson {
      func string(result: Result, size: CGPoint) -> String {
        let trackeds = result.bodies?.filter { $0.joints3D != nil }
        let point2DGroups: [String: Any] = [:]
        let point3DGroups: [String: Any] = [:]
        
        trackeds?.forEach { tracked in
          let bodies = [tracked].compactMap { $0 }
          point2DGroups += bodies.map { $0.point2DDictionary }
          point3DGroups += bodies.map { $0.point3DDictionary }
        }
        
        let dict: [String : Any] = [
          "point2DGroups": point2DGroups,
          "point3DGroups": point3DGroups,
          "cameraResolution": size.dictionary
        ]
        
        var jsonString = ""
        do {
          let data = try JSONSerialization.data(withJSONObject: dict)
          jsonString = String(bytes: data, encoding: .utf8)!
        } catch {
          print(error)
        }
        return jsonString
      }
    }
    
[/code]

## 別解: Codable(Encodable, JSONEncoder)

SwiftではJSONを扱う際には、Codableがおすすめです。  
以下のように型安全を使いつつJSONを出力(Encode)することが可能です。

[code]

    class ResultJson {
      func string() -> String {
        let output = OutputResult(
          point2D: .init(x: 1, y: 2),
          point3D: .init(x: 1, y: 2, z: 3),
          cameraResolution: .init(x: 1, y: 2)
        )
        
        let encoder = JSONEncoder()
        let data = try! encoder.encode(output)
        
        let jsonString = String(data: data, encoding: .utf8)!
        
        return jsonString
    //  {
    //    "point3D": {
    //      "x": 1,
    //      "z": 3,
    //      "y": 2
    //    },
    //    "point2D": {
    //      "x": 1,
    //      "y": 2
    //    },
    //    "cameraResolution": {
    //      "x": 1,
    //      "y": 2
    //    }
    //  }
      }
    }
    
    struct Point2D: Encodable {
      let x: Int
      let y: Int
    }
    
    struct Point3D: Encodable {
      let x: Int
      let y: Int
      let z: Int
    }
    
    struct OutputResult: Encodable {
      let point2D: Point2D
      let point3D: Point3D
      let cameraResolution: Point2D
    }
    
[/code]


CC BY-SA 4.0
2023-07-31T08:59:43.620
95811
2023-07-31T09:10:33.893
2023-07-31T09:10:33.893
40856
40856
95780
answer