Dictionary → JSON으로 내보내기

ellyheetov·2021년 7월 24일
1

JSONParsing

목록 보기
2/2
post-thumbnail

Encode A Struct To JSON Using JSONDecoder

class Candidate: Codable {
    var name: String
    var skill: String
}

let candidate = Candidate(
    name: "Elly",
    skill: "Swift"
)

Candidate라는 구조체가 있다. 이 데이터를 JSON 으로 내보내려고 한다.
놀랍게도 단 한줄이면 충분하다.

let candidateData = try? JSONEncoder().encode(candidate)

Codable을 채택 할 수 없는 객체의 경우

JSONDecoder를 이용하면 내가 생성한 객체를 쉽게 JSON 형식으로 내보낼 수 있다.
그런데 만약 Codable(Encodable, Decodable)을 채택 할 수 없는 객체의 경우 어떻게 JSON으로 내보 낼 수 있을까?

class Candidate {
    var name: String
    var skill: String
    var age: Int?
    var birthday: Date?
}

Candidate 클래스는 위와 같이 선언 되어있다. Optional 타입이 있을 뿐더러 Codable을 채택할 수 없는 Date 타입이 있다.

이러한 경우 각 데이터를 먼저 Dictionary 타입으로 Serialize하는 과정이 필요하다.

func serialize() -> [AnyHashable : Any] {
    return [
        "name" : self.name,
        "skill" : self.skill,
        "age" : self.age ?? "" ,
        "birthday" : self.birthday ?? ""
   ]
}

Opional 타입을 처리할 수 있는 방법이 달리 없어 임의로 빈 스트링을 반환하도록 하였다. (혹시 다른 방법이 있다면 알려주시면 감사하겠습니다.)

그럼 이제, 이 [AnyHashable: Any] 타입의 객체를 어떻게 JSON으로 내보낼 수 있을까?

Dictionary and NSDictionary to JSON

serialize 과정을 거쳤다면 간단해진다.
JSONSerialization.data(withJSONObject: options:) 메소드를 사용할 수 있다.

let object = try? JSONSerialization.data(withJSONObject: candidate.serialization(), options: [.prettyPrinted])

JSON 객체로 잘 파싱이 되었는지 확인하기 위해서 json파일을 저장하고 불러와 보았다.

{
  "name" : "Elly",
  "birthday" : "",
  "skill" : "Swift",
  "age" : ""
}

아래와 같이 잘 파싱이 된 것을 확인 할 수 있었다.

결론

  • Codable을 채택할 수 없는 경우 JSON으로 내보낼 수 있는 방법
    • DictionaryType으로 변경
    • JSONSerialization.data() 메소드를 이용

참고

https://www.advancedswift.com/swift-json-without-swiftyjson/#encode-an-nsdictionary-to-json

profile
 iOS Developer 좋아하는 것만 해도 부족한 시간

2개의 댓글

comment-user-thumbnail
2022년 9월 14일

안녕하세요. 글 잘 보았습니다. 그런데 "Optional 타입이 있을 뿐더러 Codable을 채택할 수 없는 Date 타입이 있다." 라고 하셨는데 struct의 프로퍼티에 Date타입이 있으면 Codable 채택을 못하나요?
https://ios-development.tistory.com/939
김종권님의 블로그에서는 그렇게 하고 있고 제 기억에도 Codable 채택 가능 했던 것 같은데... 혹시 제가 뭔가 잘못알고 있는 걸까요?

1개의 답글