无法从 Swift 中的 JSON 字典数组中获取值

时间:2021-04-05 14:44:24

标签: ios json swift dictionary

json 响应: “结果”:{

   "user_images": [
        {
            "id": 113,
            "user_id": "160",
            "image": "1617349564.jpg",
            "image_title": "33"
          
        },
        {
            "id": 112,
            "user_id": "160",
            "image": "1617349541.jpg",
            "image_title": "22"
           
        },
        {
            "id": 111,
            "user_id": "160",
            "image": "1617349528.jpg",
            "image_title": "11"
        },
        ........

代码:通过这段代码,我得到了如上所示的响应,这意味着所有 user_images 数组都来了......但在这里我需要 image_title 如何得到它< /strong>.. 如果我运行 for 循环出错.. 请帮忙

  if let code = ((response.dict?["result"] as? [String : Any])){
      let userImages = code["user_images"] as? [String : Any]

   }

如何从上述字典数组中获取 image_title

2 个答案:

答案 0 :(得分:2)

溶胶 1

if let code = response.dict?["result"] as? [String : Any]  {
  if let userImages = code["user_images"] as? [[String : Any]] {
      for item in userImages {
         print(item["image_title"])
      } 
   } 
}

溶胶 2

if let code = response.dict?["result"] as? [String : Any]  { 
   do { 
       let data = try JSONSerialization.data(withJSONObject: code) 
       let decoder = JSONDecoder() 
       decoder.keyDecodingStrategy = .convertFromSnakeCase 
       let res = try decoder.decode(Result.self, from: data) 
       let titles = res.userImages.map { $0.imageTitle } 
       print(titles) 
   }
   catch {
       print(error)
   } 
}

// MARK: - Result
struct Result: Codable {
    let userImages: [UserImage]
 
} 
// MARK: - UserImage
struct UserImage: Codable {
    let id: Int
    let userId, image, imageTitle: String
}

答案 1 :(得分:1)

来自@Sh_Khan 的代码

if let code = response.dict?["result"] as? [String : Any]  {
  //You're using "as?" which means you're casting as an optional type. 
  //One simple solution to this is here where it's unwrapped using "if let"
  if let userImages = code["user_images"] as? [[String : Any]] {
      // [String:Any] is a Dictionary
      // [[String:Any]] is an Array of Dictionary
      for item in userImages {
         print(item["image_title"])
      } 
   } else {
      // We didn't unwrap this safely at all, do something else. 
}

让我们深入探讨一下。这个结构是一个JSON对象

    {
        "id": 113,
        "user_id": "160",
        "image": "1617349564.jpg",
        "image_title": "33"
    }

但是当它独立时它只是一个 JSON 对象。添加一个键,或者在这个例子中 user_images 使它成为一个字典。请注意,[ 没有环绕它。这意味着它是一个独立的字典。如果这是您的对象,并且仅此一项,您的原始代码将可以工作,但您正在处理 ArrayDictionaries

"user_images":
    {
        "id": 113,
        "user_id": "160",
        "image": "1617349564.jpg",
        "image_title": "33"
    }

这行代码实质上意味着您希望取回 ArrayDictionary。请记住,字典的每个值都不是数组值,这就是为什么您看不到类似 [[[String: Any]]] 的内容的原因,因为数据不是这样嵌套的。

if let userImages = code["user_images"] as? [[String : Any]]

关于可选项的内容是什么?

可选项基本上是可以返回的 nil 可能值。通常,在使用 JSON 时,您不能保证始终会收到给定键的值。甚至有可能完全丢失键值对。如果发生这种情况,您最终会崩溃,因为它没有得到处理。以下是处理 Optionals

的最常见方法
var someString: String? //This is the optional one
var someOtherString = "Hello, World!" //Non-optional

if let unwrappedString1 = someString {
   //This code will never be reached
} else {
   //This code will, because it can't be unwrapped.
}

guard let unwrappedString2 = someString else {
   //This code block will run
   return //Could also be continue, break, or return someValue
} 

//The code will never make it here.
print(someOtherString)

此外,您可以通过链式展开它们来处理可选项,这是一个很好的功能。

var someString: String?
var someInt: Int?
var someBool: Bool?

someString = "Hello, World!"

//someString is not nil, but an important distinction to make, if any
//fail, ALL fail.
if let safeString = someString,
   let safeInt = someInt,
   let safeBool = someBool {
      //If the values are unwrapped safely, they will be accessible here.
      //In this case, they are nil, so this block will never be hit.
      //I make this point because of scope, the guard statement saves you from the 
      //scoping issue present in if let unwrapping.
      print(safeString)
      print(safeInt)
      print(safeBool)
}

guard let safeString = someString,
      let safeInt = someInt, 
      let safeBool = someBool {
         //This will be hit if a value is null
      return
}

//However notice the scope is available outside of the guard statement, 
//meaning you can safely use the values now without them being contained
//to an if statement. Despite this example, they would never be hit.
print(safeString)
print(safeInt)
print(safeBool)