Home > Back-end >  How to map json data using codable and populate to table view?
How to map json data using codable and populate to table view?

Time:11-01

I made a network request using urlsession and got json data , but don't know how to map the data and populate into table view . I am a beginner please help me out.

Here is the json data :

{
page = 1;
results =     (
            {
        adult = 0;
        "backdrop_path" = "/w2PMyoyLU22YvrGK3smVM9fW1jj.jpg";
        "genre_ids" =             (
            28,
            12,
            878
        );
        id = 299537;
        "original_language" = en;
        "original_title" = "Captain Marvel";
    }) }

Here is my code so far:

var movies = [Movies]()

do {
            let json = try JSONSerialization.jsonObject(with: data!, options: [])
            print(json)
            self.parse(json: json as! Data)
            
        } catch {
            print("JSON error: \(error.localizedDescription)")
        }

func parse(json: Data) {
    let decoder = JSONDecoder()
    if let jsonUsers = try? decoder.decode([Movies].self, from: json) {
        self.movies = jsonUsers
        print(movies[0].request)
    }
}

CodePudding user response:

Welcome to Swift. If you search here on Stack Overflow (and elsewhere around the web) you will find a great many examples on how to decode JSON Swift.

Apple's documentation on the subject can be found here:

Encoding and Decoding Custom Types

With a code sample here:

Using JSON with Custom Types

Generally speaking, you will need to create a struct to represent the decoded data. That struct will derive from decodable. You should give it a "CodingKeys" value that will define how the fields in your struct map to the keys in the JSON. You then use the decoder to create and fill out that struct.

JSONDecoder is the more recent and type-safe mechanism for decoding JSON. JSONSerialization will be more challenging for a beginner because of typecasting so I recommend you stick with JSONDecoder

CodePudding user response:

Based on the json data I assume that you're using TMDB's API.

Firstly, you should create a decodable struct for the results:

struct SearchResult: Decodable {
    let page: Int
    let results: [Movie]
    let totalPages: Int
    let totalResults: Int
}

Secondly, you should fetch the results from the API. I suggest that you do it with the following code:

func searchURL(withQuery query: String) -> URL? {
    var components = URLComponents()
    components.scheme = "https"
    components.host = "api.themoviedb.org"
    components.path = "/3/search/movie"
    components.queryItems = [
        URLQueryItem(name: "query", value: query),
        URLQueryItem(name: "api_key", value: "YOUR-API-KEY")
    ]
    return components.url
}

This function will return an optional URL to the search results, if you'll call it with "Pulp Fiction" as a query, it'll return:

https://api.themoviedb.org/3/search/movie?query=Pulp Fiction&api_key=YOUR-API-KEY

You can use it to actually fetch the searched phrase from the API:

func search(_ text: String, completion: @escaping (Result<[Movie], Error>) -> Void) {
    if let url = getSearchURL(withQuery: text) {
        let request = URLRequest(url: url)
        URLSession.shared.dataTask(with: request) { data, _, _ in
            if let data = data {
                do {
                    let decoder = JSONDecoder()
                    decoder.keyDecodingStrategy = .convertFromSnakeCase

                    let decodedSearchResult = try decoder.decode(SearchResult.self, from: data)
                    completion(.success(decodedSearchResult.results))
                } catch {
                    completion(.failure(error))
                }
            }
        }.resume()
    }
}

The following code:

search("Pulp Fiction") { result in
    switch result {
    case .success(let items):
        for item in items {
            print(item.title)
        }
    case .failure(let error):
        print(error.localizedDescription)
    }
}

will print:

Pulp Fiction
Pulp Fiction: The Facts
Pulp Fiction Art
Stealing Pulp Fiction
Pulp Fiction: the Golden Age of Storytelling
UFOTV Presents: Pulp Fiction: The Golden Age of Storytelling
Pulpe Fiction

If you want to populate a tableView with the search results, you should replace the .success case with:

search("Pulp Fiction") { [weak self] result in
    switch result {
    case .success(let items):
        self?.searchResults = items
        DispatchQueue.main.async {
           self?.tableView.reloadData()
        }
  • Related