URLSession (2)
response 받은 데이터를 object로 만들어 볼 것이다.
블로그 내의 데이터를 받아와보려고 했으나, 구조가 많이 달라 우선 강의과 같은 조건으로 진행해보자.
우선 기존에 작성했던 것 처럼 urlComponents를 생성한다.
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
// URL
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: "카더가든")
urlComponents.queryItems?.append(mediaQuery)
urlComponents.queryItems?.append(entityQuery)
urlComponents.queryItems?.append(termQuery)
let requestURL = urlComponents.url!
그리고 Codable을 사용하여 data에서 struct로 파싱해보자.
json 형식의 파일을 object로 만들 때에는 Codable이 매우 유용하게 사용된다고 한다.
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
enum CodingKeys: String, CodingKey {
case title = "trackName"
case artistName
case thumbnailPath = "artworkUrl30"
}
// 페이지 내 실제 이름
//trackName
//artistName
//artworkUrl30
}
데이터를 받아오고자 하는 apple의 itunes에서는 기존에 명명하고 있는 Key와 이름이 다른 것을 볼 수 있다. (response내 key 값 확인)
이에 Key값을 매칭시켜주기 위해 작업을 해준 것이다.
let dataTask = session.dataTask(with: requestURL) { (data, response, error) in
// target URL과 네트워킹 후행작업들(response에 대한 handler)을 completionHandler에 적어줘야 한다.
guard error == nil else { return } // error가 있으면 끝내고, nil이어야만 다음 작업 수행
// status 코드가 2xx이어야 성공적인 네트워킹을 했단느 것을 알 수 있다.
guard let statusCode = (response as? HTTPURLResponse)?.statusCode else { return }
let successRange = 200..<300 // 200에서 300전까지
guard successRange.contains(statusCode) else {
// 포함시 성공
// handle response error
return
}
guard let resultData = data else { return }
let resultString = String(data: resultData, encoding: .utf8)
// 목표 : 트랙리스트 오브젝트로 가져오기
// 하고 싶은 목록
// - Data -> 게시글 목록 가져오기 [Track]
// - Track 오브젝트 만들고싶음
// - Data에서 struct로 파싱하고싶음 ( Codable 이용해서 만들자 )
// - json 형식의 파일을 object로 만들어낼 때는 Codable을 사용하면 편하다!
// - Response 구조를 만들고 그 안에 게시글들이 여럿 있는 것 Response, Track 두 개를 만들어야 함
// 해야할 일
// - Response, Track struct 만들기
// - struct의 프로퍼티 이름과 실제 데이터의 Key와 맞추기 (Codable 디코딩하게 하기 위해서)
// - 파싱하기 (Decoding)
// - 트랙리스트 가져오기
// 파싱 및 트랙 가져오기
do {
let decoder = JSONDecoder()
let response = try decoder.decode(Response.self, from: resultData)
let tracks = response.tracks
print("--> tracks : \(tracks.count) -\(tracks.first?.title), \(tracks.first?.thumbnailPath)")
} catch let error {
print("--> error : \(error.localizedDescription)") // 에러 설명이 나옴
}
// print("result data ---> \(resultString)")
}
dataTask.resume()
// 위 Key가 맞지 않을 경우 오류 반환 ( --> error : The data couldn’t be read because it is missing.)
먼저 파싱을 하게 되는데 이 때에, JSONDecoder()를 사용해준다. 또한 항상 값을 가져오지는 않는 경우가 있을 수 있기에 try catch 구문을 활용해준다.
그리고 실제로 tracks의 개수와 타이틀, 썸네일을 확인해보자.
//--> tracks : 50 -Optional("6 To 9 (feat. Loco)"), Optional("https://is2-ssl.mzstatic.com/image/thumb/Music3/v4/38/b2/20/38b22010-c4b0-c4fb-afbc-19485adb228a/source/30x30bb.jpg")
--> tracks : 50 -Optional("6 To 9 (feat. Loco)"), Optional("https://is2-ssl.mzstatic.com/image/thumb/Music3/v4/38/b2/20/38b22010-c4b0-c4fb-afbc-19485adb228a/source/30x30bb.jpg")
--> tracks : 50 -Optional("6 To 9 (feat. Loco)"), Optional("https://is2-ssl.mzstatic.com/image/thumb/Music3/v4/38/b2/20/38b22010-c4b0-c4fb-afbc-19485adb228a/source/30x30bb.jpg")
카더가든의 노래 제목과 링크를 타고 들어가면 앨범아트를 확인해 볼 수 있다.
이 노래의 타이틀과 앨범아트를 가져와 본 것이다!
실제로 현업에서는 위 처럼, Key 값을 매칭시켜줄 필요가 없다고 한다. 왜냐하면 처음부터 Key값을 정해놓고, 알고 시작하기에 바로 해당 Key값을 사용하면 된다.
또한 위처럼 복잡한 response 데이터가 아닌, 필요한 부분만 정제해서 내려받기 때문에 조금 더 수월하게 파싱할 수 있다고 한다!
** 패스트캠퍼스 iOS 앱 개발 올인원 패키지 : URLSession