[Swift] JSON 데이터를 디코딩하는 방법

Ryan (Geonhee) Son·2021년 4월 9일
0

Study Stack

목록 보기
3/34

오늘은 아래 내용들에 대해 들여다 보겠습니다!

  • JSON을 통해 데이터를 받아올 때 Swift로 디코딩하기 위한 모델 타입을 만드는 방법
  • UIKitNSDataAssetFoundationJSONDecoder를 이용하여 JSON 디코딩하는 방법

출발하시죠!


모델 타입 작성 방법

  1. JSON 데이터의 구조 (객체, 키, 값)에 맞게 타입을 정의한다. JSON으로부터 입력을 받지 못할 수 있는 프로퍼티의 타입은 ?형 옵셔널로 정의한다.
  2. 정의한 타입이 JSON으로 표현된 데이터를 형식에 맞게 디코딩할 수 있도록 Decodable 프로토콜을 채택한다.
    • 타입에 선언된 프로퍼티가 Decodable을 준수하는 기본 자료형(String, Int, Double 등)인 경우에는 별도 작업 없이 프로토콜 준수함
    • 선언된 프로퍼티 중 사용자 정의 타입이 있을 경우 해당 타입 또한 Decodable 프로토콜을 준수하도록 init(from decoder: Decoder) 이니셜라이저를 별도로 작성한다.
  3. JSON 데이터에 정의된 의 이름을 변경하고자 할 경우에는 모델 타입 내에 CodingKeys 열거형을 작성한다. CodingKeys 타입이 String 타입과 CodingKey 프로토콜을 따르도록 하여 변경하고자 하는 이름을 case에, JSON 데이터에 기록된 키 값을 rawValue에 작성한다.

예시

//JSON
[
  {
    "name": "Ryan",
    "image_name": "Ryan-Profile-Photo" ,
    "age: 10,
    "short_desc": "Enthusiastic iOS Developer, I'M ON FIRE!"
  },
  {
    "name": "Kio",
    "image_name": "Kio-Profile-Photo",
    "age: 10,
    "short_desc": "Hey, are you interested in Swift? Join us!"
}

// Model Type
struct Person: Decodable {
  let name: String
  let imageName: String
  let age: Int
  let shortDescription: String
  
  private enum CodingKeys: String, CodingKey {
    case name
    case imageName = "image_name"
    case shortDescription = "short_desc"
  }
}

완성 예시


UIKitNSDataAssetFoundationJSONDecoder를 이용한 JSON 디코딩 방법

모델 타입을 만들었으니 이어서 디코딩 방법을 알아보겠습니다. JSON 데이터를 최종적으로 디코딩하기 위해 Foundation 모듈에 내장된 JsonDecoder 타입의 인스턴스를 활용하는 경우가 많은데요, JSONDecoder 타입에는 제네릭이 활용된 decode(_:from:)이라는 멋진 인스턴스 메서드가 작성되어 있기 때문입니다. 이 인스턴스 메서드는 디코드할 데이터를 필요로 하는데 이 데이터를 NSDataAsset 타입을 통해 만들 수 있습니다!

데이터를 만들면 미리 언급한 decode(_:from:) 인스턴스 메서드를 통해 바로 디코딩 결과물을 반환 받을 수 있으니 함께 이용해보고 결과물도 print 해보겠습니다. 먼저 AssetsJSON 파일을 import 해주시는 것 잊지마세요!

저는 ViewController에서 해볼게요~!

import UIKit // UIKit 모듈에는 Foundation 모듈이 내장되어 있으니 따로 import 해주시지 않으셔도 됩니다.

class ViewController: UIViewController {

  override func viewDidLoad() {
    super.viewDidLoad()
    
    var artworks: [Artworks]?
    let jsonDecoder = JSONDecoder()
    guard let jsonData: NSDataAsset = NSDataAsset(name: "korean-artworks") else { return }
    
    do {
      artworks = try jsonDecoder.decode([Artwork].self, from: jsonData.data)
    } catch {
      print(error.localizedDescription)
    }
    
    print(artworks)
  }
}

결과물을 보시면 성공적으로 디코딩된 모습을 확인하실 수 있습니다!

profile
합리적인 해법 찾기를 좋아합니다.

0개의 댓글