Swift4에서 JSON 데이터를 손쉽게 파싱이 가능한 기술이 나왔다고 한다.
그 기술이 바로 'Codable'이다.
Swift 공식 홈페이지에서 말하는 정의는 다음과 같다.
"A type that can convert itself into and out of an external representation."
자신을 변환하거나 외부표현(external representation)으로 변환할 수 있는 타입입니다.
여기서 말하는 Decodable, Encodable 이란 무엇일까요?
- Decodable : 자신을 외부표현(external representation)에서 디코딩 할 수 있는 타입
- Encodable : 자신을 외부표현(external representation)으로 인코딩 할 수 있는 타입
참고 블로그 : https://zeddios.tistory.com/373 [ZeddiOS]
실무에서는 Decodable을 보다 많이 사용한다.
아래처럼 서버 URL로부터 전달받은 JSON 데이터 파일을 파싱해서 사용하고자 한다.
- 목표 : 트랙리스트 오브젝트 가져오기
// 하고 싶은 목록
// - Data -> Track 목록으로 가져오고 싶다
// - Track 오브젝트를 만들자
// - Data에서 struct로 파싱하고 싶다. > Codable을 이용해서 만들기
// - JSON 파일 데이터 > 오브젝트 (Codable 이용)
// - Response, Track 이렇게 2개가 만들어졌다.
// 해야할 일
// - Response, Track, struct
// - struct의 프로퍼티 이름과 실제 데이터 키와 맞추기 (Codable에 이용)
// - 파싱하기 (Decoding)
// - 트랙리스트 가져오기
1. Response, Track 의 struct 구조를 생성한다.
struct Response: Codable {
let resultCount: Int
let tracks: [Track]
enum CodingKeys: String, CodingKey {
case resultCount
case tracks = "results"
}
}
struct Track: Codable {
let title: String
let artistName: String
let thumbnailPath: String
// 정의된 CodingKey 값을 매칭
enum CodingKeys: String, CodingKey {
case title = "trackName"
case artistName
case thumbnailPath = "artworkUrl30"
}
}
2. 서버 URL에서 전달받은 JSON 데이터를 Deocdable로 파싱하여 출력한다.
// 파싱 및 트랙리스트 가져오기
do {
let decorder = JSONDecoder()
let response = try decorder.decode(Response.self, from: resultData)
let tracks = response.tracks
print("---> trackts : \(tracks.count) - \(tracks.last?.title) | \(tracks.last?.thumbnailPath)")
}catch let error {
print("---> error : \(error.localizedDescription)")
}
<전체코드>
import UIKit
// URLSession
// 1. URLSessionConfiguration
// 2. URLSession
// 3. URLSessionTask를 이용하여 서버와 네트워킹
// URLSessionTask
// - dataTask
// - uploadTask
// - downloadTask
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
// URLComponents
var urlComponents = URLComponents(string: "https://itunes.apple.com/search?")!
let mediaQuery = URLQueryItem(name: "media", value: "music")
let entityQuery = URLQueryItem(name: "entity", value: "song")
let termQuery = URLQueryItem(name: "term", value: "지드래곤")
// urlCompnents에 파라미터 Query 할당
urlComponents.queryItems?.append(mediaQuery)
urlComponents.queryItems?.append(entityQuery)
urlComponents.queryItems?.append(termQuery)
// Codable 기준을 준수
struct Response: Codable {
let resultCount: Int
let tracks: [Track]
enum CodingKeys: String, CodingKey {
case resultCount
case tracks = "results"
}
}
// Codable 기준을 준수
struct Track: Codable {
let title: String
let artistName: String
let thumbnailPath: String
// 정의된 CodingKey 값을 매칭
enum CodingKeys: String, CodingKey {
case title = "trackName"
case artistName
case thumbnailPath = "artworkUrl30"
}
}
let requestURL = urlComponents.url!
let dataTask = session.dataTask(with: requestURL) { (data, response, error) in
guard error == nil else { return }
guard let statusCode = (response as? HTTPURLResponse)?.statusCode else { return }
let successRange = 200..<300
guard successRange.contains(statusCode) else {
// handle error response
return
}
guard let resultData = data else { return }
let resultString = String(data: resultData, encoding: .utf8)
// print("---> resultData : \(resultData)")
// print("---> result : \(resultString)")
// 목표 : 트랙리스트 오브젝트 가져오기
// 하고 싶은 목록
// - Data -> Track 목록으로 가져오고 싶다
// - Track 오브젝트를 만들자
// - Data에서 struct로 파싱하고 싶다. > Codable을 이용해서 만들기
// - JSON 파일 데이터 > 오브젝트 (Codable 이용)
// - Response, Track 이렇게 2개가 만들어졌다.
// 해야할 일
// - Response, Track, struct
// - struct의 프로퍼티 이름과 실제 데이터 키와 맞추기 (Codable에 이용)
// - 파싱하기 (Decoding)
// - 트랙리스트 가져오기
// 파싱 및 트랙리스트 가져오기
do {
let decorder = JSONDecoder()
let response = try decorder.decode(Response.self, from: resultData)
let tracks = response.tracks
print("---> trackts : \(tracks.count) - \(tracks.last?.title) | \(tracks.last?.thumbnailPath)")
}catch let error {
print("---> error : \(error.localizedDescription)")
}
}
dataTask.resume()
'iOS' 카테고리의 다른 글
[29일차] Protocol이란? (0) | 2020.08.27 |
---|---|
[28일차] SearchBar와 키보드 숨김 처리 (0) | 2020.08.22 |
[26일차] URLSession (꼭 알아야 할 개념) (0) | 2020.08.16 |
[25일차] Concurrency 동시성 (sync/Async) (0) | 2020.08.15 |
[24일차] Network 통신 (0) | 2020.08.14 |
댓글