iOS/UIKIT

공공 API를 통해 데이터 불러오기 (TMDB)

밤새는 탐험가89 2024. 7. 4. 13:06

'

 

구현 내용

  • TMDB 라는 영화 사이트 내에서 제공하는 API를 통해 외부 데이터를 갖고 왔다. 

구현 코드

APICaller.swift 라는 클래스 생성한다.

import Foundation


struct Constants {
    static let API_KEY = "개인 API_KEY"
    static let baseURL = "https://api.themoviedb.org"
}

enum APIError: Error {
    case failedtogetData
}

class APICaller {
    
    static let shared = APICaller()
    
    func getTrendingMovies(completion: @escaping (Result<[Movie], Error>) -> Void) {
        
        guard let url = URL(string: "\(Constants.baseURL)/3/trending/all/day?api_key=\(Constants.API_KEY)") else { return }
        
        let task = URLSession.shared.dataTask(with: URLRequest(url: url)) { data, _, error in
            guard let data = data, error == nil else { return }
            
            do {
                // 데이터 확인용
//                let results = try JSONSerialization.jsonObject(with: data, options: .fragmentsAllowed)
                
                let results = try JSONDecoder().decode(TrendingMoviesResponse.self, from: data)
                completion(.success(results.results))
            } catch {
                completion(.failure(error))
            }
        }
        task.resume()
    }
}

 

  • APICaller라는 클래스를 사용하여 TMDb(The Movie Database) API에서 트렌딩 영화를 가져오는 기능을 구현한 것이다. 
  • Constants 구조체는 API 키와 기본 URL을 저장했다. 이러한 상수 값을 코드에서 직접 사용하지 않고 구조체에 저장함으로써 코드의 가독성을 높이고 유지보수를 용이하다.

 

 

  • APIError 열거형은 API 호출 중 발생할 수 있는 오류를 정의했다. 여기서는 데이터 가져오기 실패 시의 오류(failedtogetData)만 일단 정의했다. 

 

 

  • APICaller 클래스의 인스턴스를 싱글톤 패턴으로 제공한다. 이를 통해 여러 곳에서 동일한 인스턴스를 사용할 수 있다. 

 

  • 트렌딩 영화를 가져오는 비동기 함수를 정의한다. 결과는 Result<[Movie], Error> 타입의 클로저로 반환된다.

 

  • Constants 구조체에 저장된 baseURL과 API_KEY를 사용하여 API 엔드포인트 URL을 생성한다. URL 생성이 실패하면 함수가 종료된다.
guard let url = URL(string: "\(Constants.baseURL)/3/trending/all/day?api_key=\(Constants.API_KEY)") else { return }

 

 

  • URLSession.shared.dataTask를 사용하여 비동기적으로 데이터를 가져온다.
  • 데이터가 존재하고 오류가 없는 경우, JSON 데이터를 TrendingMoviesResponse 타입으로 디코딩한다.
  • 디코딩이 성공하면 completion 클로저를 통해 성공 결과를 반환하고, 실패하면 오류를 반환한다.

 

let task = URLSession.shared.dataTask(with: URLRequest(url: url)) { data, _, error in
    guard let data = data, error == nil else { return }
    
    do {
        // 데이터 확인용
//        let results = try JSONSerialization.jsonObject(with: data, options: .fragmentsAllowed)
        
        let results = try JSONDecoder().decode(TrendingMoviesResponse.self, from: data)
        completion(.success(results.results))
    } catch {
        completion(.failure(error))
    }
}
task.resume()

 

 

Movie라는 데이터 모델을 생성한다. 

import Foundation

struct TrendingMoviesResponse: Codable {
    let results: [Movie]
}

struct Movie: Codable {
    let id: Int
    let media_type: String?
    let original_name: String?
    let original_title: String?
    let poster_path: String?
    let overviews: String?
    let vote_count: Int
    let release_date: String?
    let vote_average: Double
}

 

 

HomeViewController.swift 파일 내에 APICaller에서 생성한 함수 호출 한다.

import UIKit

class HomeViewController: UIViewController {
    ...
    // MARK: Life Cycle
    override func viewDidLoad() {
        ...
        // API를 통해 데이터 호출하는 함수 
        getTrendingMovies()
    }
    ...   
    private func getTrendingMovies() {
        APICaller.shared.getTrendingMovies { results in
            switch results {
            case .success(let movies):
                print(movies)
            case .failure(let error):
                print(error.localizedDescription)
            }
        }
    }
}