URLSession 실습(3) - 데이터 파싱

2022. 4. 29. 23:05·iOS/iOS 개념

멈춰!!! 선행 학습이 필요한 글이니 앞선 글들을 읽고 학습해보자!

URLSession 이란?

URL 생성하기

URLSession 적용하기

Codable 개념 파악하기

선행학습을 끝냈으니 드디어 API를 통해 원하는 데이터를 가져와보자잇!

Codable 프로토콜을 채택한 구조체 선언

  • 우선 구조체를 정의하기 전에 API를 호출했을때 데이터가 어떻게 날아오는지 먼저 확인하자
  • 주소창에 API 호출 주소를 입력하고 표시된 내용을 복사하여 https://jsonlint.com 이곳에서 확인해보자
  • 내용을 확인해보니 위와 같은 데이터로 Json 형태가 호출된다
  • 여기서 [ 평점, 제목, 줄거리, 포스터 경로 ] 네개만 일단 받아와 보자!
struct Response: Codable {
    let page: Int?
    let result: [MovieInfo]
    
    enum CodingKeys: String, CodingKey {
        case page
        case result = "results"
    }
}

struct MovieInfo: Codable {
    let title: String?
    let rating: Double?
    let summary: String?
    let post: String?
    
    enum CodingKeys: String, CodingKey {
        case title
        case rating = "vote_average"
        case summary = "overview"
        case post = "poster_path"
    }
}
  • Response 구조체를 Page 정보와, 정보를 배열로 담고있는 results를 정의한다
  • MovieInfo 구조체에는 [ 영화제목, 평점, 개요, 영화 포스터 ] 의 정보를 담는다
  • 구조체의 형태와 CodingKey 가 뭔지 이해하려면 본 글 제일 위에있는 선행학습을 하자! → Codable

Json 을 Model 로 Decode

// 데이터 파싱하기
    do {
        let decoder = JSONDecoder()
        let respons =  try decoder.decode(Response.self, from: resultData)
        let searchMovie = respons.result
        
        print("영화 제목 : \(searchMovie[0].title ?? "")")
        print("영화 평점 : \(searchMovie[0].rating ?? 0)")
        print("영화 줄거리 : \(searchMovie[0].summary ?? "")")
        print("포스터 경로 : \(searchMovie[0].post ?? "")")
    } catch let error {
        print(error.localizedDescription)
    }
  • JSONDecoder 를 통해 파싱을 시도하고, 이때 Error가 발생하면 Catch로 이동 할 것이다
  • 파싱이 완료 된후, 첫번째 인덱스의 정보들을 출력해 본다
/*
 영화 제목 : 어벤져스 오브 저스티스
 영화 평점 : 4.1
 영화 줄거리 : 은하계 최강의 빌런 조크스터는 태양을 없애 지구에 새로운 빙하기를 불러일으키고자 한다. 슈퍼히어로 슈퍼배트는 히어로 동료들과 함께 조크스터에 맞서 지구를 지켜내야만 한다. 이제 전 인류의 운명이 걸린 최후의 대결이 시작된다.
 포스터 경로 : /yymsCwKPbJIF1xcl2ih8fl7OxAa.jpg
 */
  • 정보를 잘 가져온 것을 확인할수 있다!
  • print 문에서 nil 병합 연산자 ( \\(searchMovie[0].title ?? "" ) 를 사용한 이유는 해당 데이터가 Optional로 오기 때문에 사용하였다, 실제 iOS 앱에서는 적절한 바인딩을 해야한다!
  • nil 병합 연산자는 해당 변수 및 상수가 nil이 아니면 원래 값을 반환하고, nil 일 경우 ?? 뒤에 오는 Default 값을 반환한다

⇒ 포스터 경로의 경우 TMDB의 API 문서를 보면 되는데

https://www.themoviedb.org/t/p/[포스터 사이즈]/[포스터 경로]

형태로 들어가면 img 파일을 볼수 있다

 

예시 아래 주소를 들어가보자!

https://www.themoviedb.org/t/p/w220_and_h330_face/yymsCwKPbJIF1xcl2ih8fl7OxAa.jpg

전체코드

// 구조체 선언
struct Response: Codable {
    let page: Int?
    let result: [MovieInfo]
    
    enum CodingKeys: String, CodingKey {
        case page
        case result = "results"
    }
}

struct MovieInfo: Codable {
    let title: String?
    let rating: Double?
    let summary: String?
    let post: String?
    
    enum CodingKeys: String, CodingKey {
        case title
        case rating = "vote_average"
        case summary = "overview"
        case post = "poster_path"
    }
}

let API_KEY = "발급받은 API KEY"
var movieSearchURL = URLComponents(string: "https://api.themoviedb.org/3/search/movie?")

// 쿼리 아이템 정의
let apiQuery = URLQueryItem(name: "api_key", value: API_KEY)
let languageQuery = URLQueryItem(name: "language", value: "ko-KR")
let searchQuery = URLQueryItem(name: "query", value: "어벤져스")

// URLComponents 에 쿼리 아이템 추가
movieSearchURL?.queryItems?.append(apiQuery)
movieSearchURL?.queryItems?.append(languageQuery)
movieSearchURL?.queryItems?.append(searchQuery)

// 옵셔널 바인딩
guard let requestMovieSearchURL = movieSearchURL?.url else { throw NSError() }

// configuration 설정 -> default
let config = URLSessionConfiguration.default

// session 설정
let session = URLSession(configuration: config)

// dataTask 설정
let dataTask = session.dataTask(with: requestMovieSearchURL) { (data, response, error) in
    guard error == nil else { return }
    
    guard let statusCode = (response as? HTTPURLResponse)?.statusCode else { return }
    let successRange = 200..<300
    guard successRange.contains(statusCode) else { return }
    
    guard let resultData = data else { return }

    // 데이터 파싱하기
    do {
        let decoder = JSONDecoder()
        let respons =  try decoder.decode(Response.self, from: resultData)
        let searchMovie = respons.result
        
        print("영화 제목 : \(searchMovie[0].title ?? "")")
        print("영화 평점 : \(searchMovie[0].rating ?? 0)")
        print("영화 줄거리 : \(searchMovie[0].summary ?? "")")
        print("포스터 경로 : \(searchMovie[0].post ?? "")")
    } catch let error {
        print(error.localizedDescription)
    }
}

dataTask.resume()
'iOS/iOS 개념' 카테고리의 다른 글
  • Combine - Intro WWDC2019 시청 (1) - Publisher
  • Codable 을 알아보자
  • URLSession 실습(2) - URLSession 적용
  • URLSession 실습(1) - URL
Jeohong
Jeohong
기억 보단 기록을
  • Jeohong
    Chikong Devlog
    Jeohong
  • 전체
    오늘
    어제
    • 분류 전체보기 (186)
      • ---- 개발 컨텐츠 ---- (0)
      • iOS (30)
        • Swift 문법 (1)
        • iOS 개념 (12)
        • HIG (5)
        • SwiftUI (7)
        • UIKit (4)
      • Side Project (0)
      • 개발서적 (4)
        • 객체지향 사실과 오해 (4)
      • 알고리즘 (74)
        • 자료구조 개념 (2)
        • Swift (25)
        • JavaScript (47)
      • ---- 회고 계획 컨텐츠 ---- (0)
      • 계획 및 일기 (10)
      • 회고록 (1)
      • 컨퍼런스 탐방 (1)
      • 미드로 영린이 탈출하기 (1)
      • ---- Previous content ---- (0)
      • Frontend (2)
        • HTML & CSS (2)
      • KITRI 수업 (17)
        • 리눅스 (14)
        • 네트워크 (2)
      • 42seoul (17)
        • Bonr2code (9)
        • 넋두리 (7)
        • 멘토특강 (1)
      • 해킹 실습 (20)
        • 해커스쿨 - F.T.Z (19)
        • WebGoat (1)
      • Tensorflow로 시작하는 NLP (1)
        • 예제 (1)
      • 자연어처리 입문 (1)
        • 이론 (1)
      • 텐서플로로 배우는 딥러닝 (7)
        • 이론 (2)
        • 예제 (5)
  • 블로그 메뉴

    • 홈
    • 태그
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    자료구조
    IOS
    본과정
    네트워크
    javascript
    42서울
    스위프트
    백준
    hig
    개발자
    SwiftUI
    Algorithm
    42seoul
    swift
    라피신
    boj
    1서클
    코딩
    프로그래머스
    알고리즘
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
Jeohong
URLSession 실습(3) - 데이터 파싱
상단으로

티스토리툴바