【问题标题】:How to filter JSON and get value in iOS Swift?如何在 iOS Swift 中过滤 JSON 并获取价值?
【发布时间】:2021-12-10 15:05:54
【问题描述】:

我正在尝试过滤 JSON 并获取键和值来解析它。这里所有的 JSON 值都是动态的。现在我需要找到“type = object”,如果找到的类型为真,那么我需要检查 value ={“contentType”&“URL”}。

这是我的 JSON:

{
    "date": {
        "type": "String",
        "value": "03/04/1982",
        "valueInfo": {}
    },
    "Scanner": {
        "type": "Object",
        "value": {
            "contentType": "image/jpeg ",
            "url": "https://www.pexels.com/photo/neon-advertisement-on-library-glass-wall-9832438/",
            "fileName": "sample.jpeg"
        },
        "valueInfo": {
            "objectTypeName": "com.google.gson.JsonObject",
            "serializationDataFormat": "application/json"
        }
    },
    "startedBy": {
        "type": "String",
        "value": "super",
        "valueInfo": {}
    },
    "name": {
        "type": "String",
        "value": "kucoin",
        "valueInfo": {}
    },
    "ScannerDetails": {
        "type": "Json",
        "value": {
            "accountNumber": "ANRPM2537J",
            "dob": "03/04/1982",
            "fathersName": "VASUDEV MAHTO",
            "name": "PRAMOD KUMAR MAHTO"
        },
        "valueInfo": {}
    }
}

解码代码:

          AF.request(v , method: .get, parameters: nil, encoding: URLEncoding.default, headers: headers).responseJSON { (response:AFDataResponse<Any>) in
        
        
        print("process instance id api document view list::::",response.result)
        
        
        
        switch response.result {
        case .success:
            
            let matchingUsers = response.value.flatMap { $0 }.flatMap { $0. == "object" }
            
            print("new object doc:::", matchingUsers)
            
            guard let data = response.value  else {
                return
            }
           
            
            print("new object doc:::", matchingUsers)
            
            if let newJSON = response.value {
                
                let json = newJSON as? [String: [String:Any]]
                                    print("new object doc:::", json as Any)
        
  //                    let dictAsString = self.asString(jsonDictionary: json)
                
                let vc = self.stringify(json: json ?? [])
                
                print("dictAsString ::: dictAsString::::==",vc)
                
                let data = vc.data(using: .utf8)!
                   do{
                       let output = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: [String:String]]
                       print ("demo:::==\(String(describing: output))")
                   }
                   catch {
                       print (error)
                   }
                
            
                do {
                    if let jsonArray = try JSONSerialization.jsonObject(with: data, options : .allowFragments) as? [String: [String:String]]
                    {
                        print("json array::::",jsonArray) // use the json here
                    } else {
                        print("bad json")
                    }
                } catch let error as NSError {
                    print(error)
                }
                
                
            }
            
            self.view.removeLoading()
            
        case .failure(let error):
            print("Error:", error)
            self.view.removeLoading()
        }
        
    }

如何从 JSON 中获取特定值?非常感谢任何帮助...

【问题讨论】:

  • "here is my son" 你的“儿子”不是 JSON 格式。
  • @ElTomato 更新了 JSON。帮我解决这个问题。
  • @PvUIDev 您需要重新解码value 的内容,因为它仍然是字符串格式。如果您仍然遇到问题,我可以向您展示您需要执行此操作的代码。但我认为你应该先尝试一下
  • @Jacob 你能举个例子吗?
  • 不要在 Swift 中使用 JSONSerialization,使用 JsonDecoder。有数百个关于这个确切用例的教程。

标签: json swift alamofire


【解决方案1】:

这是来自我的游乐场的代码以及您的 json 示例:

import Foundation

let json = """
{
    "date": {
        "type": "String",
        "value": "03/04/1982",
        "valueInfo": {}
    },
    "Scanner": {
        "type": "Object",
        "value": {
            "contentType": "image/jpeg ",
            "url": "https://www.pexels.com/photo/neon-advertisement-on-library-glass-wall-9832438/",
            "fileName": "sample.jpeg"
        },
        "valueInfo": {
            "objectTypeName": "com.google.gson.JsonObject",
            "serializationDataFormat": "application/json"
        }
    },
    "startedBy": {
        "type": "String",
        "value": "super",
        "valueInfo": {}
    },
    "name": {
        "type": "String",
        "value": "kucoin",
        "valueInfo": {}
    },
    "ScannerDetails": {
        "type": "Json",
        "value": {
            "accountNumber": "ANRPM2537J",
            "dob": "03/04/1982",
            "fathersName": "VASUDEV MAHTO",
            "name": "PRAMOD KUMAR MAHTO"
        },
        "valueInfo": {}
    }
}
"""

let data = json.data(using: .utf8, allowLossyConversion: false)!

struct ObjectScanner: Decodable {
    let contentType: String
    let url: String
    let fileName: String
}

enum ObjectScannerType {
    case object(ObjectScanner)
}

struct Scanner: Decodable {
    enum ScannerType: String, Decodable {
        case object = "Object"
    }

    enum CodingKeys: String, CodingKey {
        case type, value
    }

    let scanner: ObjectScannerType

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let type = try container.decode(ScannerType.self, forKey: .type)

        switch type {
        case .object:
            let value = try container.decode(ObjectScanner.self, forKey: .value)
            scanner = .object(value)
        }
    }
}

struct DateResponse: Decodable {
    let type: String
    let value: String
    // let valueInfo // Not enough information in sample for me to decode this object
}

struct Response: Decodable {
    enum CodingKeys: String, CodingKey {
        case date
        case scanner = "Scanner"
    }

    let date: DateResponse
    let scanner: Scanner
}

let decoder = JSONDecoder()

do {
    let response = try decoder.decode(Response.self, from: data)
    print(response)
} catch {
    print("Error decoding: \(error.localizedDescription)")
}

注意:这个例子非常无情。任何不支持的缺失值或类型都将导致DecodingError。由您决定所有可能的类型以及哪些是可选的,哪些不是。

我也没有解码所有内容,也没有充分处理date 对象

这是一个非常复杂的例子。其中的所有内容都是多态的:dateScannerScannerDetails 等。您需要非常小心如何解码并确保处理所有可能性。我建议如果你刚开始,你应该探索更简单的例子。

我也选择使用枚举。不是每个人都会选择,但我更喜欢解码这些多态类型。

您可以在此处阅读我关于处理多态类型以及未知类型的文章:https://medium.com/@jacob.sikorski/awesome-uses-of-swift-enums-2ff011a3b5a5

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-27
    • 2021-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-14
    • 2021-02-12
    • 1970-01-01
    相关资源
    最近更新 更多