0% found this document useful (0 votes)
131 views

JSON Parsing in Swift

The document discusses JSON parsing in Swift using the Codable protocol. It begins with an overview of JSON and making network requests to retrieve JSON data. It then covers parsing JSON responses using the Codable protocol and JSONDecoder, including how to define Codable model classes and handle complex JSON structures. Examples are provided of parsing JSON arrays and dictionaries and handling custom keys.

Uploaded by

Bishal Shrestha
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
131 views

JSON Parsing in Swift

The document discusses JSON parsing in Swift using the Codable protocol. It begins with an overview of JSON and making network requests to retrieve JSON data. It then covers parsing JSON responses using the Codable protocol and JSONDecoder, including how to define Codable model classes and handle complex JSON structures. Examples are provided of parsing JSON arrays and dictionaries and handling custom keys.

Uploaded by

Bishal Shrestha
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 12

JSON Parsing in Swift

medium.com/better-programming/json-parsing-in-swift-2498099b78f

October 11, 2019

Responses (19)

djvsal

What are your thoughts?​

Good one, to quickly generate codable Model class from jsoncafe.com

Hi Anand, Thanks for such a wonderful article. Thanks a ton!

Hi Anand, i have a question about complex json. I have complex json but some
structs are comes nil. An example “ActivityMedia” json datas could be nil. and i
get;

Error
valueNotFound(Swift.KeyedDecodingContainer<FFC.ClubService.CodingKeys>,
Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: “Index 0”,
intValue…
1/12
Tom

about 1 year ago

Great tutorial :)

How can i put the result of the “Complex JSON Parsing” in a table view ? is there
any tutorial ?

Thanks for replying

excellent article. well explained

Handle JSON Response with the Codable protocol in Swift 5.1

2/12
(Genchi wallpapers)

We often use JSON to send and receive data from web services. We can do this easily
with Swift.

Most applications are fully based on JSON. If your application communicates with a
web-service API, it will return a response to Dictionary(Object) , Array , String ,
Bool , or Number .

Before creating a model class, we need to keep in mind what type of response will come
from the web service. We will create the Model class based on the response. This topic
will cover most of the part-related parsing from a basic level to an advanced one.

Initially, it was hard for me to understand JSON parsing. But I realized over time that
it’s actually very easy to use. You only need to understand the Response type.

Getting Started With Network Request, URLSession


Before starting our code, we need to check our web API by typing the following into the
browser:

3/12
JSON Response

Now that we have the response in the web browser, let’s do some coding in Xcode.
Create a new project for JSON parsing.

Inside your project’s plist , navigate to Open As and then to Source Code.

Open your project’s plist

Paste the App Transport Security code inside your project’s plist .

<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>

Now make a network request with URLSessionto your web API.

We are requesting the web API handles data and errors, which is what we’ll see in its
responses. Here, I use JSONSerialization’s built-in Foundation framework. It will
convert JSON data into a foundation object.

In this part, I used the testing API from JSONPlaceholder:

4/12
guard let url = URL(string: "https://jsonplaceholder.typicode.com/todos") else {return}
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let dataResponse = data,
error == nil else {
print(error?.localizedDescription ?? "Response Error")
return }
do{
//here dataResponse received from a network request
let jsonResponse = try JSONSerialization.jsonObject(with:
dataResponse, options: [])
print(jsonResponse) //Response result
} catch let parsingError {
print("Error", parsingError)
}
}
task.resume()

The response from the web API in the JSON format looks like this. Now we need
to take values from the response. Here our response comes in our JSON array.

[
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
},
{
"userId": 1,
"id": 2,
"title": "quis ut nam facilis et officia qui",
"completed": false
}
]

Now, we’ll deal with the JSON responseobject:

guard let jsonArray = jsonResponse as? [[String: Any]] else {


return
}
print(jsonArray)//Now get title value
guard let title = jsonArray[0]["title"] as? String else { return } print(title) //compiler outout -
delectus aut autem

Let’s try to print out all of the title key values.

Currently, our JSON response is an array of the dictionary ( [[String: Any]] ). So we are
taking the dictionary from every index of the array with the help of for loop (we do
this after getting Dictionary accessing values with the keys).

5/12
for dic in jsonArray{
guard let title = dic["title"] as? String else { return }
print(title) //Output
}

Now, we can create a User structure for data handling. In response, we‘ll be getting
different types of values, such as Int , String , and Boolean , based on the values I
chose in my model structure for response management.

struct User {
var userId: Int
var id: Int
var title: String
var completed: Boolinit(_ dictionary: [String: Any]) {
self.userId = dictionary["userId"] as? Int ?? 0
self.id = dictionary["id"] as? Int ?? 0
self.title = dictionary["title"] as? String ?? ""
self.completed = dictionary["completed"] as? Bool ?? false
}
}

Use model to handle the JSON response:

var model = [User]() //Initialising Model Array


for dic in jsonArray{
model.append(User(dic)) // adding now value in Model array
}
//Printing first value for the output
print(model[0].userId) // 1211

Cool. Now you know something about JSON parsing, right?

Let’s make this same code more Swift complementary with FlatMap:

var model = [User]()


model = jsonArray.flatMap{ (dictionary) in
return User(dictionary)
}
print(model[0].userId)//make more simple
model = jsonArray.flatMap{ return User($0)}//One more time
model = jsonArray.flatMap{User($0)}//Or
model = jsonArray.flatMap(User.init)//Output
print(model[0].userId) // 1211

Looks good, but let’s do something more.

Codable Protocol
The new protocol introduced by Apple in Swift 4 provides built-in Encodable and
Decodable features. It makes JSON parsing easier. It can convert itself into and out of
an external representation.

The Codable model looks like the following. It’s pretty easy to understand, and we can
6/12
manage it with very little code.

This is the sample Codable model. You need to make your own structure model based
on your JSON response.

struct User: Codable{


var userId: Int
var id: Int
var title: String
var completed: Bool
}

JSON Parsing with JSONDecoder


After making a network request, convert the web-application response raw data into
your array model.

The rest of the JSON network request will be the same for this process. However, we
need to handle the network response data for the JSONDecoder. No significant changes
are needed for this protocol.

do {
//here dataResponse received from a network request
let decoder = JSONDecoder()
let model = try decoder.decode([User].self, from:
dataResponse) //Decode JSON Response Data
print(model)
} catch let parsingError {
print("Error", parsingError)
}

I have used the model [User].self because we’re getting the response in an array
format. If your response will be getting into the Dictionary , only then will the output
from the network request look like this:

{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}

We need to set our model class to User.self for the Dictionary response:

7/12
do {
//here dataResponse received from a network request
let decoder = JSONDecoder()
//Decode JSON Response Data
let model = try decoder.decode(User.self,
from: dataResponse)
print(model.userId) //Output - 1221
} catch let parsingError {
print("Error", parsingError)
}

Custom key names


We can modify our Codable key with custom string keys, but they should match your
JSON response keys. Otherwise, you’ll get an error message:

Error message at the bottom

Here’s how to add custom keys for the Codable model:

struct User: Codable{


var userId: Int
var id: Int
var title: String
var completed: Bool//Custom Keys
enum CodingKeys: String, CodingKey {
case userId
case id = "serviceId" //Custom keys
case title = "titleKey" //Custom keys
case completed
}
}

Let’s make code more Swift friendly. I made an initialization process here through the
extension of the model. The CodingKeys enum will confirm with the CodingKey
protocol.

8/12
struct User: Codable {
var userId: Int
var id: Int
var title: String
var completed: Bool
}extension User{
enum CodingKeys: String, CodingKey {
case userId
case id
case title
case completed
}
}

Complex JSON parsing with the Codable protocol


Now we have a complex JSON file, which has a Dictionary array:

{
"branch": {
"subject": 5,
"total_students": 110,
"total_books": 150
},
"Subject": [
{
"subject_id": 301,
"name": "EMT",
"pratical": false,
"pratical_days": [
"Monday",
"Friday"

},
{
"subject_id": 302,
"name": "Network Analysis",
"pratical": true,
"pratical_days": [
"Tuesday",
"Thursday"
]
}
]
}

I have written the Struct model for the JSON Response like this:

9/12
struct Students : Codable {
struct Branch : Codable {
let subject: Int
let totalStudents: Int
let totalBooks: Int
private enum CodingKeys : String, CodingKey {
case subject
case totalStudents = "total_students"
case totalBooks = "total_books"
}
}
struct Subject : Codable {
let subject_id: Int
let name: String
let pratical: Bool
let pratical_days: [String]
}
let branch: Branch
let subject: [Subject]
}

I don’t want to make the above model more complex. I’ve kept everything simple for
easy understanding.

Parsing data from the JSON response


Our struct model here is Student .

The following is what it looks like after making the network request to the web API. We
handle network response data directly through our Codable model. There aren’t any big
differences here.

do {
// data we are getting from network request
let decoder = JSONDecoder()
let response = try decoder.decode(Students.self, from: data)
print(response.subject[0].name) //Output - EMT
} catch { print(error) }

Finally, we have finished our JSON parsing. This is a very easy process for handling any
network response data or JSON object data in your code. It’ll allow you to handle your
UI based on response data. We need to map all of the required values from the response
as per requirements.

Conclusion
We now understand JSON parsing — from the web-service network request to data
handling based on the response.

Here I’ve covered how to create the model for the JSON response to manage the JSON
response properly in your iOS application.
10/12
I think using the normal model Struct and the Codable protocol is the easiest way to
manage any JSON response. You can manage it by yourself per your requirements. The
Codable protocol is a powerful feature in the Foundation library.

I personally recommend you set up SDK to make the network request in Swift. This will
help launch an awesome network request inside your application.

You can use Alamofire to make the network request in your application. This is a very
useful HTTP networking library, and it’s easy to use. If you want to do more advanced
functionality in your project, that’s completely up to you.

Now you can easily create your model class with the help of quicktype. You’ll be able to
generate your Swift code painlessly.

I hope you liked this. Thanks for reading!

Better Programming

Advice for programmers.

Written by

Anand Nimje

I am Swift developer and makes iOS apps

Better Programming

Advice for programmers.

Discover Medium

Welcome to a place where words matter. On Medium, smart voices and original
ideas take center stage - with no ads in sight. Watch

Make Medium yours

Follow all the topics you care about, and we’ll deliver the best stories for you to
your homepage and inbox. Explore
11/12
Become a member

Get unlimited access to the best stories on Medium — and support writers while
you’re at it. Just $5/month. Upgrade

12/12

You might also like