본문 바로가기
Learnings/Swift & iOS

[Swift] JSON을 Swift 데이터 구조로 변경하기

by abcdesong 2021. 3. 28.

Xcode 프로젝트에 불러온 JSON 파일을 Swift 내부 데이터 타입으로 변경하기

Photos 프로젝트를 진행하면서

JSON 파일을 불러오고, JSON을 파싱하여 Swift 데이터 구조로 변경하는 작업을 해보게 되었다.

 

아주 까먹기 쉽게 생겼으므로 정리하고 넘어가기!

 

 

예시 json: https://public.codesquad.kr/jk/doodle.json

//링크 중 일부 추출
[
  {
    "title": "1",
    "image": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSmETnjE9_LGsbWjeNCwlRJ4Ox1ioqxEVtWd7Z4QCKHtI7PewxvEg",
    "date": "20140116"
  },
  {
    "title": "2",
    "image": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS4XFa0i2H58farLmNpuChYmuADmvu3_dgE6aetcAmxhPAacH-32w",
    "date": "20140505"
  }
]

 

 

먼저, 파일의 경로를 파악한다.

이번 프로젝트에서는 Xcode에 JSON 파일을 불러온 상태로 시작했으므로 Bundle을 활용했다.

let jsonPath = Bundle.main.url(forResource: "image", withExtension: "json")
  • image.json 파일을 불러올 때의 예제 코드.
  • Bundle.main.url은 Xcode 프로젝트 파일 내부에 존재하는 파일의 경로를 가져올 때 사용한다.

 

그리고, 위에서 설정한 경로에서 콘텐츠를 가져와서 data 타입으로 변경해준다.

let data = try String(contentsOf: jsonPath).data(using: .utf8)
  • .utf8으로 인코딩하여 읽을 수 있는 String으로 변환한다.
  • error 처리가 필요하다.

 

JSONSerialization을 활용하여 swift 데이터 형식으로 변환해준다.

let json = try JSONSerialization.jsonObject(with: data!, options: [[]]) as? [[String: Any]]
  • 예제는 key - value 값으로 이루어진 여러 쌍의 데이터로 이루어진 json이므로 2차원 배열로 받아온 뒤, [[String: Any]]로 타입캐스팅을 해준다.
  • 역시 error 처리가 필요하다.

 

JSON 값을 한 데에 저장하기 위한 구조체를 생성해준다.

    struct ImageInfo {
        private let title: String
        private let imageURL: String
        private let date: Date

        init(title: String, imageURL: String, date: Date) {
            self.title = title
            self.imageURL = imageURL
            self.date = date
        }

        enum Keys {
            static let title = "title"
            static let imageURL = "image"
            static let date = "date"
        }
    }
  • json의 value들을 저장하기 위한 프로퍼티 생성.
  • 원하는 프로퍼티 이름과 json의 키 값이 다른 경우가 있으므로 Keys 따로 설정

 

JSON 데이터들을 구조체 초기화 시 할당하는 것으로 데이터를 저장해준다.

    jsonData.forEach({ (json) in
        let title = json[ImageInfo.Keys.title] as! String
        let imageURL = json[ImageInfo.Keys.imageURL] as! String
        let dateInString = json[ImageInfo.Keys.date] as! String

        //date는 string을 date로 변환하는 개별 메소드를 생성하여 변환해주었음 (아래 참고)
        let date = stringToDate(dateInString, withformat: "yyyyMMdd")

        let newInfo = ImageInfo(title: title,
                                imageURL: imageURL,
                                date: date)

        self.infos.append(newInfo)
    })
    func stringToDate(_ string: String, withformat format: String) -> Date {
        let formatter = DateFormatter()
        formatter.dateFormat = format
        let newDate = formatter.date(from: string) ?? Date()
        return newDate
    }

 

 

ImageInfo 프린트 결과

[PhotoApps.ImageInfoStorage.ImageInfo(title: "1", imageURL: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSmETnjE9_LGsbWjeNCwlRJ4Ox1ioqxEVtWd7Z4QCKHtI7PewxvEg", date: 2014-01-15 15:00:00 +0000),
 PhotoApps.ImageInfoStorage.ImageInfo(title: "2", imageURL: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS4XFa0i2H58farLmNpuChYmuADmvu3_dgE6aetcAmxhPAacH-32w", date: 2014-05-04 15:00:00 +0000)]

 

 

댓글