我不知道如何在由JSON响应构造的嵌套的可选NSSingleObjectArrayI中访问'duration'值。如何访问此数据结构中的嵌套值?
当我调用print(firstRow [“ elements”])时,得到以下输出:
Optional(<__NSSingleObjectArrayI 0x60000120f920>(
{
distance = {
text = "1.8 km";
value = 1754;
};
duration = {
text = "5 mins";
value = 271;
};
"duration_in_traffic" = {
text = "4 mins";
value = 254;
};
status = OK;
}
))
我尝试了字符串索引(firstRow ['elements'] ['duration']),但出现错误。
fetchData { (dict, error) in
if let rows = dict?["rows"] as? [[String:Any]]{
if let firstRow = rows[0] as? [String:Any]{
print("firstRow is")
print(firstRow["elements"])
// Trying to access duration within firstRow['elements'] here
}
}
}
作为参考,这是fetchData函数:
func fetchData(completion: @escaping ([String:Any]?, Error?) -> Void) {
let url = getRequestURL(origin: "test", destination: "test")!;
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let data = data else { return }
do {
if let array = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String:Any]{
completion(array, nil)
}
} catch {
print(error)
completion(nil, error)
}
}
task.resume()
}
一个示例HTTP JSON请求在这里:
https://maps.googleapis.com/maps/api/distancematrix/json?destinations=77%20Massachusetts%20Ave,%20Cambridge,%20MA&departure_time=now&key=AIzaSyB65D4XHv6PkqvWJ7C-cFvT1QHi9OkqGCE&origins=428%20Memorial%20Dr,%20Cambridge,%20MA
答案 0 :(得分:0)
看到您的输出,您的firstRow["elements"]
是可选的,因此您需要对其进行包装。它实际上是一个具有单个元素的NSArray,其中唯一的元素是Dictionary,具有4个条目-“距离”,“持续时间”,“ duration_in_traffic”和“状态”。您可能需要将元素强制转换为Dictionary才能访问每个条目。
您可以为此目的在as?
-casting中使用可选绑定:
fetchData { (dict, error) in
if let rows = dict?["rows"] as? [[String: Any]] {
if let firstRow = rows.first {
print("firstRow is")
print(firstRow["elements"])
//Unwrap and cast `firstRow["elements"]`.
if let elements = firstRow["elements"] as? [[String: Any]] {
//The value for "duration" is a Dictionary, you need to cast it again.
if let duration = elements.first?["duration"] as? [String: Any] {
print(duration["text"] as? String)
print(duration["value"] as? Int)
}
}
}
}
}
嵌套太深的if
很难阅读,所以有人会这样想:
fetchData { (dict, error) in
if
let rows = dict?["rows"] as? [[String: Any]],
let firstRow = rows.first,
let elements = firstRow["elements"] as? [[String: Any]],
let duration = elements.first?["duration"] as? [String: Any]
{
print(duration["text"] as? String)
print(duration["value"] as? Int)
}
}
或者使用guard
可能是更好的解决方案。
否则,如果您可以以可读的格式向我们展示整个JSON文本,那么有人会向您展示如何使用Codable,这是在Swift中使用JSON的现代方式。