Movie App Using JSON Parsing In Swift

Introduction

Movies are the best source of entertainment that we use when we get bored. Generally, when we want to watch movies we cannot decide which movie we should watch or what are popular movies currently, So we search online websites to find the best movies to watch. In this article, we will create an app where we can find popular movies according to their rating on TMDB. 

What is TMDB?

TMDB is a movie database as its name suggests "The Movie Database". It is a viral user editable database for movies and TV shows. In TMDB we can find movie information like how many ratings are, the cast of the film, the release date of a movie, and many more things. TMDB provides APIs by using those APIs we can get all the information about the movies by using JSON parsing.

To know more about TMDB click here.

What is an API?

API is an acronym for "Application Programming Interface". It works as an interface between two applications, Suppose we want to create an application and we need some information from another application, then that application will give us an API. We can use it in our application to get the information related to the application. For example suppose you’re sitting in a restaurant, with a menu list and you have to order a dish, A chef in the kitchen will prepare your order. There is a need for a medium that communicates with the chef, takes your order to the kitchen, and delivers your food back to your table. That medium is the API. The waiter is the messenger or API that takes your request or order and tells the chef in the kitchen what to do. The waiter delivers the food in response to your requested food. The data comes from an API in the form of JSON format, when we have to read that data in our application we use JSON parsing.

JSON Parsing

JSON stands for JavaScript Object Notation. It is a lightweight language-independent data interchange format derived from JavaScript. Many programming languages have their code to generate and read JSON data. JSON files use extension .json. We cannot easily read JSON data but every programming language has its way of parsing JSON data. JSON parsing is a method to read or write JSON data. Now we have understood all the terms related to JSON parsing, Let's start with the code.

Creating a User Interface for the application

Open Xcode and create a Single View Application, name the project, click next done, and we are ready to go. 

Now we will go to the storyboard and click on the ViewController icon.

We will add a NavigationController to our ViewController, For doing this click on the down arrow in the bottom navigation bar and add a navigation controller.

At this stage, we have added a NavigationController to our application. The navigation controller is used to navigate to other ViewController when we click on a button in our ViewController. Here we have a navigation controller attached to our ViewController.

Now we will add here a TableView, TableView is a subclass of UITableView and is used to represent items in row form, each row in TableView is called a cell.

Here we have added a TableView to our application. Now we will create a custom prototype cell, for doing this, Click on the prototype cell in the attribute inspector and increase the prototype cell number from zero to one. We have a prototype cell in our TableView. We will go to the identifier section and give the name "cell". 

In our custom cell, we will add an ImageView to display, where we will show our movie title. For adding these we will search for ImageView and simply place it in our cell, again we will search for a Label and place it behind ImageView. Here we will add a disclosure in our cell. This will indicate a user to click on the cell and go to details of that movie. For adding disclosure click on cell go to attribute inspector click an accessory, and select disclosure.

Here we have created the first screen UI but our work is not done for the first screen. We have to create a file of subclass UITableViewCell because we cannot simply create our outlet for these components. In ViewController for creating a new file click on the file or type command of the keyboard (⌘ + N), select for CocoaTouch class select for TableViewCell name the file and we have created a new file for TableViewCell. Now click on cell go to identity inspector and give the class name as the file name we created earlier.

We have created a new file DetailsTableViewCell. Now we have to create outlets for components, For ImageView and Label so that we can provide values to these components programmatically. For doing this just open a tab DetailsViewController file by clicking alt + DetailsViewController file. To create outlets click on that component press control and drag to the DetailsViewController file, Name that outlet, and done. We have added an ImageView outlet in this file to do the same for Label.

DetailsViewController.swift File

import UIKit

class TableViewCell: UITableViewCell {

    @IBOutlet weak
    var titleLabel: UILabel!
        @IBOutlet weak
    var movieImage: UIImageView!
        @IBOutlet weak
    var releaseDate: UILabel!
        override func awakeFromNib() {
            super.awakeFromNib()
            // Initialization code
            movieImage.layer.cornerRadius = movieImage.bounds.width / 8
            movieImage.clipsToBounds = true
        }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }
}

We have done the work for the first screen now we have to create our second screen, Where we will show details of each movie. its rating, title, release date, and description. For creating the second screen we have to add a new ViewController to our application. Search for UIView Controller and simply drag and drop it to our storyboard.

 Now we have to create a new file for our second ViewController. So let's create, press ⌘ + N click on CocoaTouch class, and select UIViewController as a subclass name. This ViewController as I have given here "DetailsViewController" and create. Now we have a swift file "DetailsViewController". Click on DetailsViewController in the storyboard. Go to identity inspector and give the class name "DetailsViewController". We have created and also given the storyboard id same so that we can remember our storyboard id(important to navigate on the second screen).

Here we have created a second screen for our application. Now we will add components to our second screen, to show details of movies. We will add ImageView to display movie images and add Labels to show the title and release date. We will also add UIView to show ratings for movies and add TextView to show the details for movies.

Here we have created UI for our application now we will code to fetch data from TMDB and show it in our application.

Fetching data for the application

We have created our UI for the app now we have to fetch movie data that we can show in our application. We want to fetch our data from TMDB that's why we have to create an account on TMDB just click here  

Now we have to login in TMDB app for the API key. It is a unique code provided by platforms that are used for authentication or identification of a user, to use the data from that platform. To login into an app just go to log in on the top navigation bar and click.

Here we have logged in now in the footer. We will click on API here we may discover examples of some URLs, like what movies are in theaters?, some popular movies, highest rated movies. In this application, we will fetch the most popular movies, but we can explore more examples and can create more apps.

For the API key go to profile ---> Setting---> API. In the overview here you can find your API key and an example of how to use an API key. In the example here we have given a movie whose id is 550. We can paste it on google and can get information in the form of JSON data. Here I have hidden my API key by using this API key only I can get information. We will copy our APY key and will go to some popular movie URL and will fetch data for that.

URL for popular movies

Here we have URLs for the most popular movies on TMDB. At the place of "Your API" will paste our API key then our URL will be complete.

https://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=Your API

Now we will code in the ViewController file to display our data.

Fetching data from TMDB

Here we have created a function fetch data()  that we will call in ViewDidLoad(). Which always runs whenever our screen will load. We are creating a variable named "URL". Where we are passing our URL as a string in the URL function. It will generate an URL. We are creating here a URL session where we are passing our URL as a parameter and getting our data in data, response and error. We are checking here if we have no error then we are decoding our data by JSON decoder and giving it to jsonData which is in the form of our JSON. It will give us an exception so we are doing this work to try-catch block. We have successfully fetched our data.

func fetchData() {
    let url = URL(string: "https://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=3775a9ddfcccf51c01dc3b8e109ecb21")
    URLSession.shared.dataTask(with: url!) {
        (data, response, error) in
        guard
        let data = data
        else {
            return
        }
        do {
            if error == nil {
                let jsonData =
                    try JSONDecoder().decode(Data.self, from: data)
                arrData = jsonData.results
                DispatchQueue.main.async {
                    self.myTable.reloadData()
                }
            }
        } catch {
            print("Error")
        }
    }.resume()
}

Displaying movie data in TableView

We have fetched our data from TMDB, Now we have to display our movie data in our TableView. We have created a UiTableView in our first screen where we will display our fetched data.

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) - > Int {
    return arrData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) - > UITableViewCell {
    let cell: TableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell") as!TableViewCell
    let inputFormatter = DateFormatter()
    inputFormatter.dateFormat = "YYYY-MM-dd"
    let outputFormatter = DateFormatter()
    outputFormatter.dateFormat = "MMM d, yyy"
    let date = inputFormatter.date(from: arrData[indexPath.row].release_date)
    let dateString = outputFormatter.string(from: date!)
    DispatchQueue.main.async {
        cell.titleLabel.text = arrData[indexPath.row].title
        cell.releaseDate.text = dateString
    }
    print(arrData[indexPath.row].title)
    let path = URL(string: "https://image.tmdb.org/t/p/original\(arrData[indexPath.row].poster_path)")
    print("https://image.tmdb.org/t/p/original\(arrData[indexPath.row].poster_path)")
    URLSession.shared.dataTask(with: path!) {
        (data, response, error) in
        guard
        let data = data
        else {
            return
        }
        DispatchQueue.main.async {
            cell.movieImage.image = UIImage(data: data)
        }
    }.resume()

    return cell

}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let details: DetailsViewController = self.storyboard?.instantiateViewController(identifier: "DetailsViewController") as!DetailsViewController
    navigationController?.pushViewController(details, animated: true)

    let path = URL(string: "https://image.tmdb.org/t/p/original\(arrData[indexPath.row].poster_path)")
    URLSession.shared.dataTask(with: path!) {
        (data, response, error) in
        guard
        let data = data
        else {
            return
        }
        DispatchQueue.main.async {
            details.backgroundImage.image = UIImage(data: data)
        }
    }.resume()

    DispatchQueue.main.async {
        details.movieName.text = arrData[indexPath.row].title
        details.movieDetails.text = arrData[indexPath.row].overview
        details.rating.rating = Double(arrData[indexPath.row].vote_average / 2)
        let inputFormatter = DateFormatter()
        inputFormatter.dateFormat = "YYYY-MM-dd"
        let outputFormatter = DateFormatter()
        outputFormatter.dateFormat = "MMM d, yyy"
        let date = inputFormatter.date(from: arrData[indexPath.row].release_date)
        let dateString = outputFormatter.string(from: date!)
        details.date.text = dateString
    }

}
}

Here we have to implement three TableView protocols that will use to display our movie data.

Number of rows at

This protocol is for how many rows are there in a TableView. This function returns an Integer here we are passing arrData where our result is there. Here the number of rows will equal how many data in arrData.

Cell of row at

This function returns a cell. We have created components in our cell while we have created our TableView. Here in each cell, we are providing data for each cell for the release date we are using DateFormatter to format our data which are coming from URL. We are passing the movie title and release date in each cell. We are getting movie image URLs that's why we have created another URL session to fetch movie images as poster paths. On the first screen, we have displayed all movie data now we have to display details of each movie on the second screen that's why we are using the third protocol for displaying movie details.

Did select a row

This protocol is used when a user clicks on a particular row. It returns the index for that row that we can use this function to navigate to other screens. Here we are using NavigationController to navigate to another screen in the second ViewController we are passing movie Image and other details for the movie and displaying it on the second screen.

For rating, we can use Cosmos pod to show the rating we can pass the value of the movie review and pass it value. We are using a UIView to display ratings as stars. Here we have successfully fetched our data and displayed it in our application.

Result

Conclusion

We have created an application that displays popular movie data in our application. Here we have used JSON parsing to parse JSON data. We can create different UI screens to display. We learned a lot about how to fetch data. Now it's your turn to explore more go on TMDB and create more applications.

Thanks for reading this article.