apple/iOS, UIKit, Documentation

[Swift] JSON 형태로 바꾸는 방법

lgvv 2024. 6. 18. 23:22

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