Why we should use Data model while parsing API. whereas we can simply get response in the ViewController class it self.
Can someone tell me why we should use Data Model to parse api response..
Thanks in advance
Imagine that you have below json response from server after calling an API:
{
"settings": {
"isUserActive": false,
"isUserAdmin": false,
"rollNumber": 10,
"userId": 2,
"userName": "John"
},
"status": 200,
"message": "Success"
}
Now how will you access the value if you are not using data model. It will be like
let name = response["settings"]["userName"]
(Assuming that you have converted the json into dictionary)
1) What if you have to use the username at multiple place, then you have to do the same thing again.
2) The above json response is simple so it will be easy to get a particular value, but imagine a json where there are nested objects, trying to retrieve a value manually can be pain.
3) If you are working in a team there is a probability that some developers can misspell the key and it can take hours to debug.
Using data model the compiler will throw error if the property is misspelled avoiding bugs.
4) You will have to typecast every time you retrieve the data from dictionary.
When using data models, need to do typecasting only once ie. when parsing the json.
All this pain can be avoided simply using data model, you only have to parse the json once and you can simply use the key as property to access value.
For example see the settings json, once you parse it to data model it can be used like this:
let data = dataModel(json: jsonResponse)
data.settings.userName // John
data.settings.rollNumber //10
data.status //200
This is a good tool to convert the json in to data models Link
Hope it helps.
Related
I have a JSON with more or less 75 keys.
I need to receive this JSON and store offline it using Realm.
I do not want to iterate through the keys, since I've heard that there are ways to save a large JSON using a few lines. How can I do this?
EDIT:
My JSON (
I saved on a server away because it's too big)
http://myjson.com/i7e6l
There is no easy, one liner to parse the JSON and store it in Realm, since each JSON response is unique and no framework can have explicit knowledge about the structure of your JSON response without you giving some information to this framework about your JSON.
You will need to write some code either to parse the response or to make a mapping between your JSON response's fields and the properties of your Realm object. If you choose the latter solution, you can use Alamofire Object Mapper to do the JSON parsing automatically, but even then you have to write code for the mapping.
I want to obtain a single value from a web service in JSON, just a file name i.e. "picture.png"; based on some parameters passed.
Can IOS (I guess NSJSONSerialization JSONObjectWithData:) handle this single value in JSON or on the server side should I have it send a dictionary key as in {"pic": "picture.gif"}
If there is no picture, I am returning "nopic" so again should I have it return "error" or {"error": "nopic"}
I gather the various JSON specifications are conflicting on this point so my interest is just practical...how best to handle this case.
Thanks for any guidance on this
When I POST a Core Data managed object using RestKit, RestKit doesn't update the existing object but creates a new object instead.
The returned JSON always contains the newly created object, but wraps it into a plural keyed array. I found that if I change this to just the one object, the updating works as expected. However, I would like to keep the array in the response so that all responses are consistently in the plural form.
Is there any way I can make RestKit update the record, even when returned from the server wrapped in an array?
Possible solution: identificationAttribute?
On my entities I have an identificationAttribute called remoteID. This is the primary unique key of the record. This will be 0 before the POST, because the object is not yet on the server. I thought that by adding a second identificationAttribute called insertionID, setting that before the POST, and then returning it in the response, would allow RK to find the existing entity in the local store. Alas, it didn't work.
What did work however, was setting the remoteID before the POST, to the next auto increment value on the server! What could explain that it works with remoteID, but not with a second insertionID?
Example request
{
"user": {
"email": "example#example.com"
}
}
Response
{
"users": [{
"email": "example#example.com"
}]
}
I would like to keep the array in the response so that all responses are consistently in the plural form.
You shouldn't, because this is an individual request and response, not a composite.
Your idea about identificationAttribute is correct, but doesn't apply when the response is an array. The array is the trigger (or one of the possible triggers) to abandon the match with the source object and create new objects. Changing this would be hard.
Without knowing more about your real situation, 2 alternatives:
Change the JSON
POST a dictionary instead of the real object and then you won't have a duplicate
When you use multiple identification attributes, all must match for the destination object to be found.
Take care - don't create multiple mappings for the same entity with different identification attributes or you will most likely be debugging the lookup cache for a long time trying to work out what's happening...
If the identity matches before the request is made then the array isn't an issue. To explain the above in more detail:
When you POST an object, RestKit expects to get that object back. So, if you POST one object and get an array back it doesn't know what to do, because it can't map an array into an object. So, it tries to lookup based on the identification attribute (if they exist). If the POSTed object didn't have an id and the returned object does then it will never match. If you set it before POSTing then it will match.
I know how to parse json object from NSString using NSData and NSDictionary, but I didn't find how to parse multiple json object if I get message like this:
{
"msg_type" : "fist_json",
"field" : "param"
}
{ "second_json_field": [
{
"name_picture": "0.png",
"data_picture":"something"
},
{
"data_values": "something"
} ]
}
{
"third_msg" : "hello"
}
It's not valid JSON, so you can't parse it. A JSON document is either a single array, or a single object (dictionary). Three objects are not valid JSON. You could put square brackets around everything, put commas in the right places, and parse it, getting an array back. Finding the places for the commas without writing a full-blown JSON parser is tricky.
If this is what the server gave you, ask the server people to fix their broken server. If your code for some reason combined three JSON messages into one, then don't do that.
I'm guessing this is not possible in one go. Your provided example text might look like JSON, but it isn't (valid).
I think the service that serves you this response should be 'fixed'.
After trying a lot sorry for asking such a trivial question.
Given below screenshot consist of a data that I have successfully received from the server.
I would like to know how to traverse through the data since whenever I try to cast it to something and try a foreach it gives an error.
The actual data sent from the server is a List() type.
I want to know how to cast it to same type and use it here.
I tried casting but it says unexpected token here.
Any help is appreciated.
JSON.parse return type depends on the String you try to parse. See the doc :
Parses json and build the corresponding parsed JSON value.
Parsed JSON values are of the types num, String, bool, Null, Lists of parsed JSON values or Maps from String to parsed JSON values.
From your screenshot, it seems that the return value is a List. You can do something like the following to use it (did you notice the typo in your commented code - .fore) :
final parsedList = JSON.parse(e.data)/*.fore*/;
parsedList.forEach((x){
query('#idData').appendText(x[0]);
query('#idData').appendText(x[1]);
query('#idData').appendText(x[2]);
query('#idData').appendText(x[3]);
});