无法解析字符串中的字典数组

时间:2019-05-30 10:04:13

标签: ios json swift

目前,我正在开发公交车预定模块。在用户设置了他的出发和到达城市以及旅行日期之后,将向用户显示可用公共汽车的列表。我已经成功完成了这一部分。但是我面临的问题是,每个总线都有自己的取消策略,即字符串内的字典数组。我无法解析它。在每个“ apiAvailableBuses”字典中,都有一个“ cancellationPolicy”键,该键具有字符串作为值,其中包含字典数组。我已经从“ apiAvailableBuses”中删除了其他键值对。

可用公交JSON响应列表:

"apiAvailableBuses":[
   {
      "cancellationPolicy":"[{\"cutoffTime\":\"5\",\"refundInPercentage\":\"90\"}]"
   },
   {
      "cancellationPolicy":"[{\"cutoffTime\":\"9-12\",\"refundInPercentage\":\"25\"},{\"cutoffTime\":\"12-24\",\"refundInPercentage\":\"35\"},{\"cutoffTime\":\"24-48\",\"refundInPercentage\":\"50\"},{\"cutoffTime\":\"48-60\",\"refundInPercentage\":\"75\"},{\"cutoffTime\":\"60\",\"refundInPercentage\":\"90\"}]"
   },
   {
      "cancellationPolicy":"[{\"cutoffTime\":\"5\",\"refundInPercentage\":\"90\"}]"
   },
   {
      "cancellationPolicy":"[{\"cutoffTime\":\"5\",\"refundInPercentage\":\"90\"}]"
   },
   {
      "cancellationPolicy":"[{\"cutoffTime\":\"5\",\"refundInPercentage\":\"90\"}]"
   },
   {
      "cancellationPolicy":"[{\"cutoffTime\":\"5\",\"refundInPercentage\":\"90\"}]"
   },
   {
      "cancellationPolicy":"[{\"cutoffTime\":\"5\",\"refundInPercentage\":\"90\"}]"
   },
   {
      "cancellationPolicy":"[{\"cutoffTime\":\"6-24\",\"refundInPercentage\":\"70\"},{\"cutoffTime\":\"24\",\"refundInPercentage\":\"85\"}]"
   }
]

有人可以帮助我解决这个问题吗?如果有人听不懂我的问题,请告诉我。

注意:我没有在项目中使用Codable。

谢谢。

3 个答案:

答案 0 :(得分:0)

您可以使用以下方法解析JSON字符串:

// JSON Format
    let jsonResponse = ["apiAvailableBuses": [
        [
            "cancellationPolicy": "[{\"cutoffTime\":\"5\",\"refundInPercentage\":\"90\"}]"
        ],
        [
            "cancellationPolicy": "[{\"cutoffTime\":\"9-12\",\"refundInPercentage\":\"25\"},{\"cutoffTime\":\"12-24\",\"refundInPercentage\":\"35\"},{\"cutoffTime\":\"24-48\",\"refundInPercentage\":\"50\"},{\"cutoffTime\":\"48-60\",\"refundInPercentage\":\"75\"},{\"cutoffTime\":\"60\",\"refundInPercentage\":\"90\"}]"
        ],
        [
            "cancellationPolicy": "[{\"cutoffTime\":\"5\",\"refundInPercentage\":\"90\"}]"
        ],
        [
            "cancellationPolicy": "[{\"cutoffTime\":\"5\",\"refundInPercentage\":\"90\"}]"
        ],
        [
            "cancellationPolicy": "[{\"cutoffTime\":\"5\",\"refundInPercentage\":\"90\"}]"
        ],
        [
            "cancellationPolicy": "[{\"cutoffTime\":\"5\",\"refundInPercentage\":\"90\"}]"
        ],
        [
            "cancellationPolicy": "[{\"cutoffTime\":\"5\",\"refundInPercentage\":\"90\"}]"
        ],
        [
            "cancellationPolicy": "[{\"cutoffTime\":\"6-24\",\"refundInPercentage\":\"70\"},{\"cutoffTime\":\"24\",\"refundInPercentage\":\"85\"}]"
        ]
        ]
    ]

// Function Calling
        setBuses(json: jsonResponse)

// Function to Parse JSON
func setBuses(json: Dictionary<String,Any>) {
    guard let buses = json["apiAvailableBuses"] as? [Dictionary<String,Any>] else { return }
    for (index, bus) in buses.enumerated() {
        print("\n\nBus #\(index+1)")
        guard let policies = convertToDictionary(text: bus["cancellationPolicy"] as! String) else { return }
        for (index, policy) in policies.enumerated() {
            print("\nPolicy #\(index+1)")
            print("cutoffTime #\(index+1) \(String(describing: policy["refundInPercentage"]))")
            print("refundInPercentage #\(index+1) \(String(describing: policy["cutoffTime"]))")
        }
    }
}

func convertToDictionary(text: String) -> [Dictionary<String,Any>]? {
    let data = text.data(using: .utf8)!
    do {
        if let jsonObj = try JSONSerialization.jsonObject(with: data, options : .allowFragments) as? [Dictionary<String,Any>] {
            return jsonObj
        } else {
            print("JSON Error")
        }
    } catch let error as NSError {
        print(error)
    }
    return nil
}

答案 1 :(得分:0)

使用 Codable 解析以上JSON response

如果您的JSON response具有以下格式:

{
  "apiAvailableBuses": [
    {
      "cancellationPolicy": [
        {
          "cutoffTime": "5",
          "refundInPercentage": "90"
        }
      ]
    }
  ]
}

创建Codable types来解析上述响应。

struct AvailableBuses: Codable {
    var apiAvailableBuses: [Bus]
}

struct Bus: Codable {
    var cancellationPolicy: [CancellationPolicy]
}

struct CancellationPolicy: Codable {
    var cutoffTime: String
    var refundInPercentage: String
}

在上面的代码中,我创建了3个符合struct-Codable protocol

AvailableBuses, Bus, CancellationPolicy

用法:

data获得API response后,您可以像上面创建的parse一样structs

if let data = jsonStr.data(using: .utf8) {
    do {
        let availableBuses = try JSONDecoder().decode(AvailableBuses.self, from: data)
        print(availableBuses)
    } catch {
        print(error)
    }
}

答案 2 :(得分:0)

如果由于某种原因不想使用Codable,则可以使用JSONSerialization

let input = "[{\"cutoffTime\":\"5\",\"refundInPercentage\":\"90\"}]"
let data = input.data(using: .utf8)!
let parsed = try! JSONSerialization.jsonObject(with: data, options: []) as! Array<Dictionary<String, Any>>

print(parsed) // [["refundInPercentage": 90, "cutoffTime": 5]]