Ios 在Swift中解析动态可选键值JSON

Ios 在Swift中解析动态可选键值JSON,ios,json,xcode,swift4,swift5,Ios,Json,Xcode,Swift4,Swift5,如何解析动态密钥(!papLZgcMalaVpYzStU:com.matrix.in):值或修改这两个结构以进行动态密钥处理 struct Join : Codable { let papLZgcMalaVpYzStUcommatrixin : !papLZgcMalaVpYzStU:com.matrix.in? enum CodingKeys: String, CodingKey { case papLZgcMalaVpYzS

如何解析动态密钥(!papLZgcMalaVpYzStU:com.matrix.in):值或修改这两个结构以进行动态密钥处理

struct Join : Codable {

        let papLZgcMalaVpYzStUcommatrixin : !papLZgcMalaVpYzStU:com.matrix.in?

        enum CodingKeys: String, CodingKey {
                case papLZgcMalaVpYzStUcommatrixin = "!papLZgcMalaVpYzStU:com.matrix.in"
        }
    
        init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                papLZgcMalaVpYzStUcommatrixin = !papLZgcMalaVpYzStU:com.matrix.in(from: decoder)
        }

}
struct !papLZgcMalaVpYzStU:com.matrix.in : Codable {

        let timeline : Timeline?

        enum CodingKeys: String, CodingKey {
                case timeline = "timeline"
        }
    
        init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                timeline = Timeline(from: decoder)
        }

}
用于下面的JSON。

{
"rooms": {
    "join": {
        "!papLZgcMalaVpYzStU:com.matrix.in": {
            "timeline": {
                "events": [{
                    "type": "m.room.message",
                    "sender": "@de1212138007:com.matrix.in",
                    "origin_server_ts": 1587395955315,
                    "content": {
                        "body": "thinks this is an example emote",
                        "msgtype": "m.emote"
                    },
                    "unsigned": {
                        "age": 7576335895
                    },
                    "event_id": "$$WLGTSEFSEF:localhost"
                }, {
                    "type": "m.room.message",
                    "sender": "@de3212138007:com.matrix.in",
                    "origin_server_ts": 1587395955315,
                    "content": {
                        "body": "filename.jpg",
                        "info": {
                            "h": 398,
                            "mimetype": "image/jpeg",
                            "size": 31037,
                            "w": 394
                        },
                        "msgtype": "m.image",
                        "url": "mxc://localhost/JWEIFJgwEIhweiWJE"
                    },
                    "unsigned": {
                        "age": 7576335895
                    },
                    "event_id": "$$WLGTSEFSEF:localhost"
                }, {
                    "type": "m.room.message",
                    "sender": "@de4212138007:com.matrix.in",
                    "origin_server_ts": 1587395955315,
                    "content": {
                        "body": "something-important.doc",
                        "filename": "something-important.doc",
                        "info": {
                            "mimetype": "application/msword",
                            "size": 46144
                        },
                        "msgtype": "m.file",
                        "url": "mxc://localhost/FHyPlCeYUSFFxlgbQYZmoEoe"
                    },
                    "unsigned": {
                        "age": 7576335895
                    },
                    "event_id": "$$WLGTSEFSEF:localhost"
                }],
                "prev_batch": "t16-12345_96395_1234_33138_4166_522_140_82600_1",
                "limited": true
            }


        },
        "!SecondRoomYzStU:com.matrix.in": {
            "prev_batch": "t16-98262_96395_3402_33138_4166_522_140_82600_1",
            "limited": true
        }
    }
}
}

我试过了

import Foundation

struct RootClass : Codable {

        let rooms : Room?

        enum CodingKeys: String, CodingKey {
                case rooms = "rooms"
        }
    
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            rooms = try! Room(from: decoder)
        }

}
struct Room : Codable {

        let join : Join?

        enum CodingKeys: String, CodingKey {
                case join = "join"
        }
    
        init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
            join = try! Join(from: decoder)
        }

}

struct Join : Codable {

        let papLZgcMalaVpYzStUcommatrixin : !papLZgcMalaVpYzStU:com.matrix.in?

        enum CodingKeys: String, CodingKey {
                case papLZgcMalaVpYzStUcommatrixin = "!papLZgcMalaVpYzStU:com.matrix.in"
        }
    
        init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                papLZgcMalaVpYzStUcommatrixin = !papLZgcMalaVpYzStU:com.matrix.in(from: decoder)
        }

}
struct !papLZgcMalaVpYzStU:com.matrix.in : Codable {

        let timeline : Timeline?

        enum CodingKeys: String, CodingKey {
                case timeline = "timeline"
        }
    
        init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                timeline = Timeline(from: decoder)
        }

}

   struct Timeline : Codable {

                let events : [Event]?
                let limited : Bool?
                let prevBatch : String?

                enum CodingKeys: String, CodingKey {
                        case events = "events"
                        case limited = "limited"
                        case prevBatch = "prev_batch"
                }
            
                init(from decoder: Decoder) throws {
                        let values = try decoder.container(keyedBy: CodingKeys.self)
                        events = try values.decodeIfPresent([Event].self, forKey: .events)
                        limited = try values.decodeIfPresent(Bool.self, forKey: .limited)
                        prevBatch = try values.decodeIfPresent(String.self, forKey: .prevBatch)
                }

        }
struct Event : Codable {

        let content : Content?
        let eventId : String?
        let originServerTs : Int?
        let sender : String?
        let type : String?
        let unsigned : Unsigned?

        enum CodingKeys: String, CodingKey {
                case content = "content"
                case eventId = "event_id"
                case originServerTs = "origin_server_ts"
                case sender = "sender"
                case type = "type"
                case unsigned = "unsigned"
        }
    
        init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
            content = try! Content(from: decoder)
                eventId = try values.decodeIfPresent(String.self, forKey: .eventId)
                originServerTs = try values.decodeIfPresent(Int.self, forKey: .originServerTs)
                sender = try values.decodeIfPresent(String.self, forKey: .sender)
                type = try values.decodeIfPresent(String.self, forKey: .type)
            unsigned = try! Unsigned(from: decoder)
        }

}

struct Unsigned : Codable {

        let age : Int?

        enum CodingKeys: String, CodingKey {
                case age = "age"
        }
    
        init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                age = try values.decodeIfPresent(Int.self, forKey: .age)
        }

}
struct Content : Codable {

        let body : String?
        let info : Info?
        let msgtype : String?
        let url : String?

        enum CodingKeys: String, CodingKey {
                case body = "body"
                case info = "info"
                case msgtype = "msgtype"
                case url = "url"
        }
    
        init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                body = try values.decodeIfPresent(String.self, forKey: .body)
            info = try! Info(from: decoder)
                msgtype = try values.decodeIfPresent(String.self, forKey: .msgtype)
                url = try values.decodeIfPresent(String.self, forKey: .url)
        }

}
struct Info : Codable {

    let duration : Int?
    let mimetype : String?
    let size : Int?

    enum CodingKeys: String, CodingKey {
            case duration = "duration"
            case mimetype = "mimetype"
            case size = "size"
    }
}

JSON中有两种类型的
键值

  • 已知

  • 未知

  • 您应该使用已知结构解析已知
    键值
    s,并使用简单的
    字典
    解析未知
    键值
    s

    对于这个简化的JSON:

    {
       "a":{
          "RandomKey1":{
             "a":"Some required value",
             "b":"Some optional value here",
             "c":12345
          },
          "RandomKey2":{
             "a":"Another required value"
          }
       }
    }
    
    结构将是:

    struct KnownTypeRandom: Codable {
        let a: String
        let b: String?
        let c: Int?
    }
    
    struct KnownTypeA: Codable {
        let a: [String: KnownTypeRandom]
    }
    
    然后,您可以通过枚举未知键来查找未知键,如:

    for unknown in knownObjectA.a {
        print(unknown.key)
    }
    
    这将打印出:

    RandomKey1
    RandomKey2
    

    请展示您目前拥有的代码,这不是一个代码编写服务。还有,请。有很多相关问题。谢谢,但我基本上想知道如何解析所有动态密钥,非常简单,只需解码字典
    [字符串:某物]
    并枚举密钥。请检查我是否优化了代码无法获取所有密钥值!papLZgcMalaVpYzStU:com.matrix.in of rooms etc可以自由提问。如果RandomKey1 RandomKey2等中有另一个字典数组?具有可选值?你能帮我吗?所以我接受这个答案o将出现另一个
    已知
    未知
    状态。然后您可以重试这些步骤。对于可选,一个
    就足够处理了。让我试试,并检查我是否添加了
    可选
    支持示例。