글 작성자: HEROHJK

실무에서 앱을 개발하면서, 네트워크를 사용하지 않는 앱을 만드는 경우는 드문것 같습니다.

 

흔히 서버와 통신을 하면서, 요새는 웹 JSON으로 많이 데이터를 받으며, 보통 RestAPI를 이용해서 데이터 전송을 많이 하는데요.

 

현실적으로 Swift 개발자는 맥이라는 장벽 때문에 다른 언어에서 Swift로 옮겨오는 경우가 많아서, 보통 Java나 C# 좀 더 올라가면 C, C++등등 언어에서 옮겨올텐데요, C#같은 경우에는 요즘 최신 버전이 Json 파싱을 지원해준다고 들었습니다만, 한 3년 전 까지만해도Json.Net 이라는 외부 라이브러리를 많이 이용했던 경험이 생각 납니다.

 

그래서 Swift를 예전에 처음 공부할 때에도 Json과 통신할 일이 있으면 가장 먼저 Github에서 Json라이브러리를 찾아보았고, SwiftyJson이라는 유명한 라이브러리가 있습니다만..

 

Swift에서는 자체적으로 Json을 지원합니다. 크게 어렵지도 않구요..

 

이제 서론은 끝내고, 간단하게 예제로 한번 살펴보도록 하겠습니다.

 

먼저 이런 구조의 Json 데이터가 있다고 가정을 해 볼께요..

 

{
    "header": "SVG Viewer",
    "items": [
        {"id": "Open"},
        {"id": "OpenNew", "label": "Open New"},
        null,
        {"id": "ZoomIn", "label": "Zoom In"},
        {"id": "ZoomOut", "label": "Zoom Out"},
        {"id": "OriginalView", "label": "Original View"},
        null,
        {"id": "Quality"},
        {"id": "Pause"},
        {"id": "Mute"},
        null,
        {"id": "Find", "label": "Find..."},
        {"id": "FindAgain", "label": "Find Again"},
        {"id": "Copy"},
        {"id": "CopyAgain", "label": "Copy Again"},
        {"id": "CopySVG", "label": "Copy SVG"},
        {"id": "ViewSVG", "label": "View SVG"},
        {"id": "ViewSource", "label": "View Source"},
        {"id": "SaveAs", "label": "Save As"},
        null,
        {"id": "Help"},
        {"id": "About", "label": "About Adobe CVG Viewer..."}
    ]
}

인터넷에서 예제를 좀 찾아보면서 적당한게 있어서 가져왔습니다.

SVG Viewer라는 프로그램의 메뉴 목록인데요, 뭐 헤더는 프로그램의 제목일테고, items는 메뉴 항목들의 정보겠죠.

id는 있지만 label이 빠져있는것도 보이고요, 

null로 구분을 짓는것 같구요.. (아마 Depth가 있을것같은데, Depth의 항목은 빠져있고.. 조금 이상하긴 하네요 ㅋ.ㅋ)

 

이것을 구조체로 역직렬화 하는 방법은 이렇습니다.

 

1. 먼저 구조체를 만듭니다.

struct Menu: Codable {
    
    struct MenuItem: Codable {
        let id: String
        let displayLabel: String?
        
        enum CodingKeys: String, CodingKey {
            case id
            case displayLabel = "label"
        }
    }
    
    let name: String
    let itemList: [MenuItem?]
    
    enum CodingKeys: String, CodingKey {
        case name = "header"
        case itemList = "items"
    }
}

대략적으로 이런 구조가 됩니다.

메뉴 아이템과 메뉴는 방법은 같으니깐 간단하게 살펴보자면..

 

먼저 Swift 는 프로토콜 지향 언어답게, Codable이라는 프로토콜을 상속받습니다.

Codable은 Encodable과 Decodable이 합쳐진, 즉 인코딩과 디코딩(JSON의 직렬화와 역직렬화)을 가능하게 해주는 프로토콜입니다.

 

프로토콜의 Enumerate, 즉 열거형중에는 CodingKeys라는것이 있는데요, Swift에서 함수, 메서드, 변수등은 소문자의 카멜케이스로 작성합니다.

하지만 파이썬이나 PHP등등 일부 언어들은 snake_case를 이용하기도 합니다. (itemList -> item_list 등등)

 

따라서 이름을 맞춰줘야하는데요, 그럴 때 CodingKeys 열거형을 이용하여 저 예제처럼 사용합니다.

 

그리고 아예 null값이 있는부분도 있고, label은 빠져있는 부분도 있는데, 그런 부분이 적용되는곳에는 옵셔널을 적용시켜 줍니다.

 

이렇게 만들면 사실 다 개발한것이나 다름 없습니다.

 

디코딩은 아주간단합니다.

 

func loadJsonData(jsonString: String) -> Menu? {
    let jsonDecoder = JSONDecoder()
    
    guard let jsonData = jsonString.data(using: .utf8) else { return nil }
    
    do {
        return try jsonDecoder.decode(Menu.self, from: jsonData)
    } catch {
        print(error.localizedDescription)
        return nil
    }
}

 

이렇게하면 됩니다.

 

실행은

 

let jsonString = """
    {
        "header": "SVG Viewer",
        "items": [
            {"id": "Open"},
            {"id": "OpenNew", "label": "Open New"},
            null,
            {"id": "ZoomIn", "label": "Zoom In"},
            {"id": "ZoomOut", "label": "Zoom Out"},
            {"id": "OriginalView", "label": "Original View"},
            null,
            {"id": "Quality"},
            {"id": "Pause"},
            {"id": "Mute"},
            null,
            {"id": "Find", "label": "Find..."},
            {"id": "FindAgain", "label": "Find Again"},
            {"id": "Copy"},
            {"id": "CopyAgain", "label": "Copy Again"},
            {"id": "CopySVG", "label": "Copy SVG"},
            {"id": "ViewSVG", "label": "View SVG"},
            {"id": "ViewSource", "label": "View Source"},
            {"id": "SaveAs", "label": "Save As"},
            null,
            {"id": "Help"},
            {"id": "About", "label": "About Adobe CVG Viewer..."}
        ]
    }
    """
    
    if let menu = loadJsonData(jsonString: jsonString) {
        // menu 코드 사용
    }

이렇게 하면 되겠네요.

 

이렇게 아주 간단하게 json 데이터를 활용하는 방법을 알아보았습니다.

반응형