Parse data JSON from Firebase Swift with Node - json

I have the following structure in Firebase as shown in the photo.
But I can't get the json format. Everything only works if I enter the node name in the model as below.
Working model for json (LNiTKMpNKHYVqTwyyY52k36Aqvo1 is entered only to show the working example)
struct SearchedUser: Decodable {
let LNiTKMpNKHYVqTwyyY52k36Aqvo1: SearchedPerson
}
struct SearchedPerson: Decodable {
let uid: String
var username: String
var name: String
var bio: String
var avatarUrl: String
let avatarBackgroundHex: String
}

Related

decoding and parsing nested json Swift

I want to parse this json file and decode and add them into list. However, couldn't find a way to that. I tried this:
struct flightsPost: Codable {
var data: flightDate
}
struct flightDate: Codable {
var origin: String
var destination: String
var price: Int
var airline: String
var flight_number: String
var departure_at: String
var return_at: String
var transfers: String
var expires_at: String
}
Couldn't find a place and how to put dates these structs. Please help I am really struggling.
Your structure is wrong. The data child is not a single object but a collection of type [String:flightDate] or if you decode it with a custom dateformatter [Date:flightDate].
struct flightsPost: Codable {
var data: [String:flightDate]
}

Parse Json to nested Struct using Swift

I am trying to parse a JSON that I am receiving in my Application. The JSON Syntax is correct but I am unable to parse it into a nested Struct.
Here is my code that can be run in Playground:
let message = "{\"type\":\"something\",\"data\":{\"one\":\"first\",\"two\":\"second\",\"three\":\"third\"}}"
let jsonData = message.data(using: .utf8)!
struct Message: Decodable {
let type: String
struct data: Decodable {
var one: String
var two: String
var three: String
}
}
let receivedMessage: Message = try! JSONDecoder().decode(Message.self, from: jsonData)
The printed Result is Message(type: "something") but the data is not parsed.
How can I parse the data correctly to use it afterwards.
The nested struct/dictionary is the value for key data
struct Message: Decodable {
let type: String
let data: Nested
struct Nested: Decodable {
var one: String
var two: String
var three: String
}
}

Decode JSON file from API Swift Special Type Problem

I'm trying to decode some JSON data from a URL and display it in a list. My Json data include special type like in example. How can I solve it?
struct Post : Decodable {
var author : String
var wp:featuredmedia : String // i problem in this line because of json type
}
A little part of the JSON:
[
{
"author":"Asil Arslan",
"wp:featuredmedia":"https://developer.apple.com/assets/elements/icons/swiftui/swiftui-96x96_2x.png"
}
]
You can use custom CodingKeys to create a mapping between the model and the JSON:
struct Post: Decodable {
enum CodingKeys: String, CodingKey {
case author, featuredmedia = "wp:featuredmedia"
}
var author: String
var featuredmedia: String
}

Swift 5 Parsing strange json format

I'm trying to parse JSON but keep getting incorrect format error. The JSON I get back from FoodData Central (the USDA's Nutrition API) is as follows:
{
dataType = "Survey (FNDDS)";
description = "Chicken thigh, NS as to cooking method, skin not eaten";
fdcId = 782172;
foodNutrients = (
{
amount = "24.09";
id = 9141826;
nutrient = {
id = 1003;
name = Protein;
number = 203;
rank = 600;
unitName = g;
};
type = FoodNutrient;
},
{
amount = "10.74";
id = "9141827";
nutrient = {
id = 1004;
name = "Total lipid (fat)";
number = 204;
rank = 800;
unitName = g;
};
type = FoodNutrient;
}
);
}
My Structs:
struct Root: Decodable {
let description: String
let foodNutrients: FoodNutrients
}
struct FoodNutrients: Decodable {
// What should go here???
}
From the JSON, it looks like foodNutrients is an array of unnamed objects, each of which has the values amount: String, id: String, and nutrient: Nutrient (which has id, name etc...) However, forgetting the Nutrient object, I can't even parse the amounts.
struct FoodNutrients: Decodable {
let amounts: [String]
}
I don't think its an array of string, but I have no idea what the () in foodNutrients would indicate.
How would I go about parsing this JSON. I'm using Swift 5 and JSONDecoder. To get the JSON I use JSONSerializer, then print out the JSON above.
This is not a JSON. This is a property list in the openStep format.
This is how it can be modelled (use String instead of Int):
struct Root: Decodable {
let description: String
let foodNutrients: [FoodNutrient]
}
struct FoodNutrient: Decodable {
let id: String
let amount: String
let nutrient: Nutrient
}
struct Nutrient: Decodable {
let name: String
let number: String
let rank: String
let unitName: String
}
And then decode it like this:
try PropertyListDecoder().decode(Root.self, from: yourStr)
The () in foodNutrients indicates that it holds an array of objects - in that case FoodNutrient objects. Therefore your root object should look like this:
struct Root: Decodable {
let description: String
let foodNutrients: [FoodNutrient]
}
Now the foodNutrient is except for the nutrient object straightforward:
struct FoodNutrient: Decodable {
let id: Int // <-- in your example it is an integer and in the second object a string, choose the fitting one from the API
let amount: String
let nutrient: Nutrient
}
And the nutrient object should look like this:
struct Nutrient: Decodable {
let name: String
let number: Int
let rank: Int
let unitName: String
}
Using Decodable is a good and easy way to serialize JSON. Hope that helps. Happy coding :)

Swift 4 - How to convert Json to swift Object automatically like Gson in java

I am new in Swift 4 and trying to figure out How to convert Json to swift Object automatically like Gson in java. Is there is any plugin i can use which can convert my json to object and vice versa. I have tried to use SwiftyJson Library but couldnt understand what is syntax for directly converting the json to object mapper.
In Gson conversion is as follow :
String jsonInString = gson.toJson(obj);
Staff staff = gson.fromJson(jsonInString, Staff.class);
Can you please suggest some really simple example for beginner like me . below is my swift person class :
class Person {
let firstName: String
let lastName: String
init(firstName: String, lastName: String) {
self.firstName = firstName
self.lastName = lastName
}
}
below is method call to fetch response from server :
let response = Helper.makeHttpCall(url: "http://localhost:8080/HttpServices/GetBasicJson", method: "PUT", param: interestingNumbers)
In response variable I am getting json:
{
"firstName": "John",
"lastName": "doe"
}
There's no need for external libraries in Swift anymore. As of Swift 4, there are 2 protocols that can achieve what you are looking for: Decodable and Encodable which are grouped into the Codable typealias, as well as JSONDecoder.
You just need to create an entity that conforms to Codable (Decodable should be enough in this example).
struct Person: Codable {
let firstName, lastName: String
}
// Assuming makeHttpCall has a callback:
Helper.makeHttpCall(url: "http://localhost:8080/HttpServices/GetBasicJson", method: "PUT", param: interestingNumbers, callback: { response in
// response is a String ? Data ?
// Assuming it's Data
let person = try! decoder.decode(Person.self, for: response)
// Uncomment if it's a String and comment the line before
// let jsonData = response.data(encoding: .utf8)!
// let person = try! decoder.decode(Person.self, for: jsonData)
print(person)
})
More info:
Apple's sample code: Using JSON with Custom Types
SE-0167: Swift Encoders
In-depth guide to JSON parsing in Swift 4
JSON with Encoder and Encodable
JSON to Swift with Decoder and Decodable
As #nathan Suggested
"There's no need for external libraries in Swift anymore."
But If you still want to go with the third party library like ObjectMapper
class Person : Mappable {
var firstName: String?
var lastName: String?
required init?(map:Map) {
}
func mapping(map:Map){
//assuming the first_name and last_name is what you have got in JSON
// e.g in android you do like #SerializedName("first_name") to map
firstName <- map["first_name"]
lastName <- map["last_name"]
}
}
let person = Mapper<Person>().map(JSONObject:response.result.value)
and extending the answer by #nathan to demonstrate #SerializedName annotation equivalent in iOS using Codable
struct Person : Codable {
let firstName : String?
let lastName : String?
enum CodingKeys: String, CodingKey {
case firstName = "first_name"
case lastName = "last_name"
}
}