How to print array of dictionary value in swift

Viewed 602

Hello i getting api response from backend like following.

here i need to retrive the "userId" from following [Any] type.

[{
  "userId" : "5e633967c04aff49e5e22c5b",
  "onlineStatus" : 1
}]

i tried with the following code but in my case it gives error.

let data = Array(chatdataArray) as? [[String:Any]]
print(data)
5 Answers

First convert Array[Any] to array of dictionary [[String: Any]], using guard let or if let.

guard let arrChatData = chatdataArray as? [[String: Any]] else { return }

print("User Id :: ", arrChatData[0]["userId"])

Or

Use Model for API responses using ObjectMapper for map data.

Usage:

Create models.

import Foundation
import ObjectMapper

//MARK: - ChatDetails
struct ChatDetails: Mappable {

    var chatDataArray: [ChatDataArray]?

    init?(map: Map) {}

    mutating func mapping(map: Map) {

        self.chatdataArray <- map["chatdataArray"]
    }
}

//MARK: - ChatDataArray
struct ChatDataArray: Mappable {

    var onlineStatus: Int?
    var userId: String?

    init?(map: Map) {}

    mutating func mapping(map: Map) {

        self.onlineStatus <- map["onlineStatus"]
        self.userId <- map["userId"]
    }
}

After setUp of Models map API response.

if let responseDict = response as? [String: Any], responseDict.keys.count > 0 {
    if let chatDetails = Mapper<ChatDetails>().map(JSON: responseDict) {

        var arrChatList = chatDetails.chatdataArray
        print("User ID :: ", arrChatList[0].userId)
    }
}
class Model:NSObject,Codable{
    var userId: String?
    var onlineStatus: Int?
}

do{

    let object = [["userId":"123"],["userId":"456"]]

    let jsonData = try JSONSerialization.data(withJSONObject: object, options: [])
    let array = try JSONDecoder().decode(Array<Model>.self, from: jsonData)

    let model = array[0]
    let userId = model.userId

    print(array)
    print(model)
    print(userId)

}catch{
    print(error)
}

You can use this.

import Foundation

extension Data {
    var prettyPrintedJSONString: NSString? { /// NSString gives us a nice sanitized debugDescription
        guard let object = try? JSONSerialization.jsonObject(with: self, options: []),
              let data = try? JSONSerialization.data(withJSONObject: object, options: [.prettyPrinted]),
              let prettyPrintedString = NSString(data: data, encoding: String.Encoding.utf8.rawValue) else { return nil }

        return prettyPrintedString
    }
}


let str = "[{\"userId\" : \"5e633967c04aff49e5e22c5b\", \"onlineStatus\" : 1 }]".data(using: .utf8)!.prettyPrintedJSONString!
debugPrint(str)

First I initalize it as Array of dictionary, then I fetched the desired item.

if let data = chatdataArray as? [[String: Any]]{
      for item in data{
       if let userId = item["userId"] as? String{
           print(userId)
      }
     }
}

If I understood OP criteria correctly this looks like a nice case for using Swift higher order function approach.

let dic: [Any] = [["userId": "5e633967c04aff49e5e22c5b",
                    "onlineStatus": 1],
                  ["userId": "aaaa",
                    "onlineStatus": 0]]
let userIdValues = dic.compactMap{ ($0 as? [String: Any])?["userId"] }
print(userIdValues) 

yielding

["5e633967c04aff49e5e22c5b", "aaaa"]

The compactMap will filter out nil entries if the Any element will not cast to [String: Any] during the as?

Related