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)]
'Learnings > Swift & iOS' 카테고리의 다른 글
[iOS] clipsToBounds 란 무엇인가? (feat. 모서리를 둥글게 둥글게) (0) | 2021.03.21 |
---|---|
[iOS] UIScrollView 만들기 (0) | 2021.03.15 |
Swift Protocol - CustomStringConvertible 간단 정리 (0) | 2021.02.15 |
Swift 지연실행 실험 - NSTimer, asyncAfter, DispatchSourceTimer (0) | 2021.01.27 |
===와 !==, 참조 비교 연산자 - Swift (1) | 2021.01.13 |
댓글