Reputation: 89
I make iOS app that has a chats. It's built on ActionCable. I use ActionCableClient library to work with it. Everything works great. The only problem with parsing a received message. It has type Any:
Optional({
data = {
author = {
"avatar_url" = "<null>";
name = "\U0410\U043b\U043b\U0430";
uid = "eb1b5fe6-5693-4966-bf72-a30596353677";
};
"created_at" = "1598446059.511528";
file = "<null>";
image = "<null>";
quote = "<null>";
status = red;
text = "test message";
type = OperatorMessage;
uid = "30b4d5ed-639d-46fb-9be3-b254de3b1203";
};
type = "operator_message";
})
And cast Any type to Data doesn't work. I can't JSONDecode it through this. I can get String out of it.
String(describing: data)
But I don't know how to use it anymore. How do you get a data model out of it?
Upvotes: 0
Views: 55
Reputation: 26066
That's the print of a NSDictionary
.
So you can do:
guard let dict = that as? NSDictionary else { return }
or, in a more Swift way:
guard let dict = that as? [String: Any] else { return }
And for instance, retrieving some values:
let type = dict["type"] as? String
if let subdata = dict["data"] as? [String: Any] {
let text = subdata["text"] as? String
let kid = subdata["uid"] as? String
...
}
If you want to retrieve (NS)Data
back, you can use JSONSerialization
to transform it back, and use a JSONDecoder
, but since there was already a
Data ----(through JSONSerialization)----> Dictionary
Going back to Data would mean
Data ----(through JSONSerialization)----> Dictionary ----(through JSONSerialization)----> Data ----(through JSONDecoder)----> CustomStruct
While, you could have a CustomStruct init with your dictionary.
So if you have a codable struct:
struct Response: Codable {
let data: CustomData
let type: String
}
struct CustomData: Codable {
let uid: String
let text: String
...
}
The quickest way would be then to add:
extension Response {
init?(dict: [String;: Any] {
guard let type = dict["type"] as? String?
let data = dict["data"] as? [String: Any] else { return nil }
self.type = type
self.data = data
}
}
extension CustomData {
init?(dict: [String;: Any] {
guard let uid = dict["did"] as? String?
let text = dict["text"] as? String else { return nil }
self.uid = uid
self.text = text
...
}
}
Upvotes: 1