如何在 iOS Swift 中过滤 JSON 并获取价值?

Posted

技术标签:

【中文标题】如何在 iOS Swift 中过滤 JSON 并获取价值?【英文标题】:How to filter JSON and get value in iOS Swift? 【发布时间】: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。有数百个关于这个确切用例的教程。 【参考方案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

【讨论】:

以上是关于如何在 iOS Swift 中过滤 JSON 并获取价值?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS swift 中使用文本字段过滤日期数组?

如何在 iOS Swift 中使用段控制从模型中过滤名称、日期?

如何在 swift iOS 中使用 swift 高阶函数从本地 json 创建 ViewModel

如何在 Swift 4 ios 中编码 json 数组

如何在ios目标c中过滤Json数据

IOS - 如何在 Swift 3 中从 JSON 中捕获动态数组维度