[Swift] JSONDecoder

코르피·2022년 10월 20일
0

JSONDecoder

JsonDecoder란?

json 파일을 객체로 변환 시켜주는 class이다.

사용방법

struct sportItem: Decodable {
    let name: String
    let image_name: String
    let short_desc: String
    let desc: String
}

let json = """
[
    {
        "name":"골프",
        "image_name":"golf",
        "short_desc":"골프골프골프",
        "desc":"스포츠스포츠스포츠스포츠"
    },
    {
        "name":"볼링",
        "image_name":"balling",
        "short_desc":"볼링볼링볼링",
        "desc":"스포츠스포츠스포츠스포츠"
    },
]
""".data(using: .utf8)!

let decoder = JSONDecoder()
let sports = try decoder.decode([sportItem].self, from: json)

sports.forEach { sport in
    print("""
        \(sport.name),
        \(sport.image_name),
        \(sport.short_desc),
        \(sport.desc)
        
        """)
}
// prints 
// 골프,
// golf,
// 골프골프골프,
// 스포츠스포츠스포츠스포츠

// 볼링,
// balling,
// 볼링볼링볼링,
// 스포츠스포츠스포츠스포츠

decoder.decode(type: Decodable.Protocol, from: Data)
json 파일을 양식에 따라
utf8 포맷을 사용해서 디코드 할 타입을 Data타입으로 바꾸어주었다.

앞의 type에는 Decode시 필요한 프로토콜인 Decodable을 채택한 타입을 넣어준다.

CodingKeys

사용하다보면 json 파일마다 양식이 다를 수 있는데
대표적으로 camelCase와 snake-Case가 있다.

기본적으로 변수명과 json의 키 값이 동일해야 객체를 성공적으로 만들 수 있는데
기본적으로 CamelCase를 사용하는 swift는 snake-case가 불편할 수 있는데

snake-case 를 camelCase로 바꾸어서 사용할 수 있는 방법이 CodingKeys이다.

사용방법

struct sportItem: Decodable {
    let name: String
    let imageName: String
    let shortDesc: String
    let desc: String
    
    enum CodingKeys: String, CodingKey {
        case name
        case imageName = "image_name"
        case shortDesc = "short_desc"
        case desc
    }
}

원하는 변수명을 설정해주고 프로토콜에 선언되어있는 CodingKeys enum을 생성해 준 후 값을 변환 전 값을 작성해준다.
rawValue로 String 또는 Int를 받을 수 있다.

keyDecodingStrategy

변환을 할 수 있는 방법 중에 애플에서 제공하는 방법이 있다.

  • useDefaultKeys
    • 아무것도 지정하지 않았을 때 기본으로 디코딩하는 방법이다.
  • convertFromSnakeCase
    • snake-case 인 양식을 CamelCase로 바꾸어주는 디코딩 방법이다
  • custom()

사용방법

간단하다.
decode 하기 전에

decoder.keyDecodingStrategy = .convertFromSnakeCase

를 사용해주면 된다.
custom일 경우

struct sportItem: Decodable {
    let name: String
    let image: String
    let shortdesc: String
    let desc: String
}

struct MyKey: CodingKey {
    var stringValue: String
    var intValue: Int?
    
    init(stringValue: String) {
        self.stringValue = stringValue
        self.intValue = nil
    }
    
    init(intValue: Int) {
        self.stringValue = String(intValue)
        self.intValue = intValue
    }
}

decoder.keyDecodingStrategy = .custom { keys in
    print(keys)
    let key = keys.last!.stringValue.split(separator: "-").joined()
    print(key)
    return MyKey(stringValue: String(key))
}
  1. CodingKey를 채택한 객체를 생성하고 string, int를 초기화 한다.
  2. .custom에 후행클로저를 이용해서 key를 다듬는다.
  3. 다듬은 key를 CodingKey 인스턴스로 생성해서 반환한다.

keys.last를 사용하는데
[_JSONKey(stringValue: "Index 0", intValue: 0), _JSONKey(stringValue: "im-age", intValue: nil)]
이런 형태로 오기 때문에 마지막 의 JSONKey를 가져온다.

profile
행복합시다!!

0개의 댓글