[Swift] JSON 형태로 바꾸는 방법
JSON 형태로 바꾸는 방법
서버에서 JSON으로 만들어서 올려달라고 해서, 구조체를 특정 키 값을 지정해서 올리기 위해 학습한 부분
아래는 JSON으로 바꾸는 코드
extension Encodable {
/// 인코딩 가능한 문자열을 JSON 직렬화
var jsonSerialized: String? {
let jsonEncoder = JSONEncoder()
do {
jsonEncoder.outputFormatting = .withoutEscapingSlashes
let jsonData = try jsonEncoder.encode(self)
return String(data: jsonData, encoding: .utf8)
} catch {
return nil
}
}
}
extension Array where Element: Encodable {
/// 배열을 JSON 직렬화
func jsonSerialization() -> String {
let serialized = self.compactMap { element -> String? in
guard let data = try? JSONEncoder().encode(element),
let jsonString = String(data: data, encoding: .utf8) else {
return nil
}
return jsonString
}
return "[" + serialized.joined(separator: ",") + "]"
}
}
encoder.outputFormatting은 JSONEncoder에서 사용되는 옵션으로, JSON 데이터를 인코딩할 때 출력 형식을 설정하는 데 사용.
JSONEncoder.OutputFormatting 옵션들
1. prettyPrinted
- 설명: JSON 데이터를 보기 쉽게 포맷팅하여 출력 데이터가 들여쓰기되고 줄 바꿈이 추가.
2. sortedKeys
- 설명: JSON 객체의 키를 알파벳 순서로 정렬하여 출력.
3. withoutEscapingSlashes
- 설명: 슬래시 (/) 문자를 이스케이프 처리하지 않고 JSON으로 출력. 기본적으로 슬래시는 이스케이프되어 출력.
4. withoutEscapingNonAscii
- 설명: ASCII 이외의 문자를 이스케이프 처리하지 않고 JSON으로 출력. 기본적으로 ASCII 이외의 문자는 유니코드 이스케이프 문자로 출력.
5. prettyPrinted, sortedKeys
- 설명: 보기 쉽게 포맷팅된 JSON 데이터를 알파벳 순서로 정렬하여 출력.
- 이스케이프 처리란?
- 설명: 문자열 내의 슬래시(/)를 \/로 처리함.
// 이스케이프 처리 예시
let person = Person(name: "John/Doe")
{
"name" : "John\/Doe"
}
구조체에서 인코딩 키를 활용하여 원하는 키 값으로 JSON을 구성하는 방법
방법: CodingKeys를 활용하여 변환
아래는 샘플 구조체
struct MobileDeveloper: Encodable {
var name: String
var language: [Language]
enum Language: Encodable {
case swift
case objc
case java
case kotlin
// 사용자 정의 인코딩 방법
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
case .swift, .objc:
try container.encode("ios", forKey: .platform)
case .java, .kotlin:
try container.encode("android", forKey: .platform)
}
}
enum CodingKeys: String, CodingKey {
case platform
}
}
enum Location: String, Encodable {
case seoul
case suwon
}
// 사용자 정의 인코딩 방법
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(name, forKey: .name)
try container.encode(language, forKey: .language)
}
enum CodingKeys: String, CodingKey {
case name
case language
}
}
위의 배열을 인코딩하면
let developer = MobileDeveloper(name: "John Doe", language: [.swift, .java])
// 결과
{"name":"John Doe","language":[{"platform":"ios"},{"platform":"android"}]}
JSON 유효성 검사는 https://jsonlint.com/ 해당 사이트에서 가능
해당 코드를 사용하면 String이 아닌 것들도 모두 인코딩 가능
let developer = MobileDeveloper(name: "John Doe", language: [.swift, .java])
let strings: [String] = ["1번", "2번"]
let string: String = "문자열"
let integers: [Int] = [1, 2]
let integer: Int = 1