Swift 4+SwiftyJson convert/generate objects from JSON automatically - ios

I'm using SwiftyJSON to get a JSON from my web service. What's the easiest way to convert this into a swift object represenation?
I mean maybe a website like http://www.jsonschema2pojo.org/ which does the same for Java.
I so far found generators which work from String or Dictionary but not SwiftyJSON?
Thanks

You can see JSON Master, Here you can generate you code directly from JSON for SwiftyJSON, Codable framework or classical Dictionary. It can also generate struct or class.
Also it has support for Java, Kotlin and C#

You can use json4swift
Online JSON to Swift Models Generator
Our motive is simple, in this age of technology; convenience and automation, working with JSON for Swift shouldn't be complicated anymore. Without dependency on other tools and framework, this free online utility maps your web service responses to appropriate models. It makes working with JSON easier and manageable.
Free Utility
This online free utility generates a Swift 2.0 and Swift 4.0 compatible models which can be simply dragged & used in your project.
Map Response
Simply map your web service response with your models with a single line.
Dictionary Representation
The objects can be referred to as a dictionary anytime should you need them with the current state and same key-value pairs.

Let's say for example you have a Student Model and you want to map the JSON Object to Student Object. You can try like this:
struct Student {
let id: Int!
let name: String!
init(param: JSON) {
id = param["id"].intValue
name = param["name"].stringValue
}
/* JSON Response
{
"id": 168,
"name": "KoingDev"
}
*/
}
Hope it is useful! :)

Related

What is the use of Data Model while API Parsing in swift

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.

Swift: I want to read a list of countries with many attributes from a csv files and use this for my app. How can I implement this?

I am developing an iOS app using Swift (still new to swift).
I have a databank saved as a csv file and that is primarily the core of the app. The databank contains a table divided into a list of all countries (rows) each with many attributes/descriptors (the columns). Really there is no relationship between the countries.
What I would like to do is to be able to display this information for the (selected) country in my app. As well as do other things like search/filtering/sorting based on the attribute/property chosen.
The databank might be updated in the future with the release of app updates but other than that I think I want it to be read once from the csv file and then the app uses that data.
Am I right in thinking that the best way to implement this is by using Core Data with ONE entity (country) with the different attributes? So then all I have to do is read the csv file once and persistent store all the data and use it from there.
Or is Core Data not the best implementation? Shall I just create a class Country with the many attributes and use that? But then that means the app will have to read the csv every time it opens and save the data to arrays etc if I wanted to filter or sort?
So I guess in summary my questions are:
1. Use Core Data or not? If not then what do you think the best implementation is?
2. If using Core Data, am I just creating ONE entity (so no relationships etc).
What would see this as is that you would want to load this into your database of choice; Thus CoreData or SQLite or even Realm would work.
In case you don't have the data available for any of them yet and you want to load them in using swift this is a parser that I wrote for a similar situation where CSV is my raw datasource that I need to parse:
if let listFile = try? String(contentsOfFile: path) {
let lines = listFile.components(separatedBy: "\n")
// NOTE: There is also a CSV format that uses ',' as a separator
// So verify if yours uses ';' or ','
let rows: [[String: String]] = lines.flatMap() {
(item) -> [String: String]? in
let components = item.components(separatedBy: ";")
if components.count != 3 {
return nil
}
// Modify this part to parse the X amount of columns
// you have in your countries.csv
let dict = [
"identity": components[0],
"description": components[1].lowercased(),
"points": components[2]
]
return dict
}
}
}
Then after you have the data in an [[String: String]] format you could parse that row by row and insert them into the database you chose to use.
I believe in Swift4 it should be possible to use the new Codable protocols in order to achieve a result that would look a lot cleaner; but I have not written an Encoder/Decoder for CSV files ( yet ) that would allow you to do this. If there is one available I'll post it here.
There is also a CSV parser available on github here:
SwiftCSV
I have never used it, but who knows; might be helpful to you.

Save a large JSON to Realm using Swift 3

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.

How to use inheritance with Swift and ObjectMapper?

I'm new to Swift and I have to serialize an object structure into a JSON string in my iOS( iOS >= 8) project.
So I decided to use the ObjectMapper library (I integrated it with Cocoapod).
But my problem is that the structure is the following.
ObjectA can have a list of children objects as an array stored in an instance variable.
Objects that can be stored in the instance array can be of multiple types, say ObjectB and ObjectC. So, in Java with GSON I would have created an InterfaceD and made both of my classes implement it and made the array in ObjectA store InterfaceD types, but I can't figure how to do this with Swift object model as it results in empty {} JSON objects.
The resulting JSON should look like this.
{"children":[
{"type":"ObjectB", "value1":"foo"},
{"type":"ObjectC", "value1":"bar", "value2":"baz"}
]}
and I get
{"children":[
{},
{}
]}
Notice that the two entries that have to be serialized from objectA and ObjectC should have different structures.
I tried multiple things but each times I'm stuck in a dead end.
I tried using generics, tried to use Mappable protocol as my array type, I tried classic class inheritence but any one failed.
Have you any idea how I can achieve this ?
Note that I know that I could add a serialization function to each object and retrieve the strings recursively and concatenate them. But I really want to avoid implementing a JSON serializer by myself as I already use on successfully as Alamofire is already used in the project). Also implementing a new serializer is error prone and not a clean way to solve the problem IMO.
Thanks a lot.
I never had the solution but as a workaround I just made my objects produce a dictionnary from all its values. Then I recursively add child objects dictionnaries as the current dictionnary values.
It adds a toDict() function to each object that I forced with a protocol.
When the resulting object is only made of a tree of dictionnaries, the ObjectMapper serialization works fine...

RestKit : How to parse the JSON response to NSDictionary without mapping any entity or class?

I just want the RestKit to parse the JSON data into NSDictionary, but not a class. This is because the attributes of the JSON data is dynamic, means the number of fields is not fixed and field count can be large. So I don't want to create a huge class to map the json data. Just keep that in NSDictionary. Does RestKit provide this functionality or we have to work out some other way.Guidance Needed.
Thanks.
Have to modify the Restkit to support the ability ....
RKObjectRequestOperation.HTTPRequestOperation.responseData
then parse the json data to dictionary or array
Either use AFNetworking (which RestKit is built on top of) or use a dynamic mapping (depending on your destination class needs).
If you have large arbitrary data then you should just avoid using RestKit as it will only slow your performance.

Resources