호댕의 iOS 개발

[iOS] JSON 데이터를 만들고 parsing하기 본문

Software Engineering/iOS

[iOS] JSON 데이터를 만들고 parsing하기

호르댕댕댕 2021. 12. 12. 12:00

JSON은 무엇일까?

JSON은 Javascript Object Notation의 줄인 말이다. 

 

그럼 분명 나는 Swift로 개발을 공부하고 있는데 왜 Javascript에서 객체를 표기하는 방법을 배워야 하는 것일까?

그 이유는 단순하다.

최근 JSON을 데이터를 전달하고 저장하는 대표적인 방법으로 사용하고 있기 때문이다. 

 

컴퓨터의 데이터는 전부 0과 1로 구성이 되어 있는데, 컴퓨터 간에 데이터를 전달하려면 서로 0과 1을 해석하는 방식이 동일해야 한다. 

그래서 HTML과 유사한 XML이라는 방식을 사용하기도 했다.

 

하지만 데이터를 주고 받을 때 사람도 보다 읽기 쉽도록 하길 원했고, 현재는 사람도 읽기 편한 JSON을 대부분 사용하게 되었다. 

 


JSON 데이터의 표기 방법

{} : 객체 (딕셔너리)
[] : 배열
"" : 문자열
0 : 수
true/false : Boolean
null : 빈 값

 

빈 값을 nil이 아닌 null이라고 표현하는 것 빼면 Swift에서 사용하는 것과 거의 유사하다. 

 

실제로 표기되는 것을 보면 다음과 같다. 

 

[
    {
        "닉네임": "호댕",
        "소유한 야아 포인트": 38
    },
    {
        "닉네임": "예거",
        "소유한 야아 포인트": 38
    },
    {
        "닉네임": "제인",
        "소유한 야아 포인트": 73
    },
    {
        "닉네임": "애플사이다",
        "소유한 야아 포인트": 37
    },
    {
        "닉네임": "요한",
        "소유한 야아 포인트": 55
    },
]

그렇다면 어떻게 JSON 파일을 생성할 수 있을까?

터미널에서 JSON 파일을 생성할 수 있다. 

1. 일단 cd ~/Desktop 으로 가서 파일을 생성하고 싶은 곳으로 디렉토리를 설정한다. 

2. touch 원하는파일명.json 명령어를 사용한다. 

3. 지정한 폴더에 가면 빈 JSON 파일을 볼 수 있다. 

4. 파일을 열어 JSON 표기방법대로 작성을 해주면 된다. 

5. Asset에 JSON 데이터를 등록하면 끝!

 

위와 같은 방법으로 간단하게 JSON 파일을 생성할 수 있다. 

 


어떻게 JSON 파일을 parsing할까?

JSON 파일을 iOS에서 사용하려면 데이터를 parsing하는 과정이 필요하다. 

 

이를 위해선 일단 데이터를 어떻게 parsing할 지 구조를 정해줘야 한다. 

 

위 예시에서 보면 딕셔너리에 들어있는 key 값이 "닉네임", "소유한 야아 포인트"로 구성이 되어 있다. 

하지만 한글로 네이밍을 하는 것은 권장되지 않고 한글을 코드에 너무 많이 작성하면 Xcode가 튕기는 상황도 있었다. 

 

그럼 한글로 된 key 값을 다른 이름으로 변경하려면 어떻게 해야 할까?

 

이는 공식문서 Encoding and Decoding Custom Types에 나와 있다. 

결론부터 말하자면 Codingkey 프로토콜을 채택하면 된다.  

struct StudentsList: Decodable {
    var name: String
    var point: Int
    
    enum CodingKeys: String, CodingKey {
        case name = "닉네임"
        case point = "소유한 야아 포인트"
    }
}
CodingKeys라는 바꿀 이름을 모아둔 열거형을 선언해주고 CodingKey 프로토콜을 채택한 다음, 바꾸고 싶은 이름을 case로 작성해주면 된다. 또한 기존의 keys를 작성해주면 된다. (기존 key들이 String이여서 String으로 작성)
 
 
 
이렇게 데이터의 구조를 잡아주었다면 decoding을 해야 한다. 
 
Codable 프로토콜을 채택하면 encoding과 decoding 모두 가능하지만 일단 예시에선 Decoding만 하기 때문에 Decodable 프로토콜만 채택했다. 
 
 
이 때 JSON 데이터를 상수에 저장할 때 NSDataAsset이라는 클래스에 저장하게 된다. 
 
여기서 NSDataAsset은 Asset catalog에서 데이터를 저장하는 객체이다. 
 

예시에선 하나의 JSON 데이터를 parsing하기 때문에 데이터의 이름을 미리 적어놨지만 여러 JSON 데이터가 있는 경우 파일 이름을 매개변수로 입력받을 때 잘못 받을 수 있기 때문에 에러를 throw하도록 했다. 

 

struct JSONParser: Decodable {
    func decode(fileName: String) throws -> [StudentsList] {
        guard let jsonData = NSDataAsset(name: "{JSONTest}") else {
            throw ParsingError.wrongFileName
        }
        
        let jsonDecoder = JSONDecoder()
        
        guard let decodedData = try? jsonDecoder.decode([StudentsList].self, from: jsonData.data) else {
            throw ParsingError.failDecoding
        }

        return decodedData
    }
}

또한 Swift에서 정의한 decode를 사용해 decoding할 타입, 데이터를 넣어주어 decoding 된 데이터를 반환해주면 된다! 

Comments