Kakao Video API를 이용해서 검색을 하던중
Alamofire + SwiftyJSON을 이용했던 코드를
Alamofire + Codable로 리팩토링하는 작업이 있었다.
func callRequest(type: EndPoint, query: String, page: Int, completionHandler: @escaping (JSON) -> () ) {
// 한글에 대한 인식이 안되기 때문에 한글에 대한 처리를 해줘야함
let text = query.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
let url = type.requestURL + text + "&page=\(page)"
// 카카오는 .validate(statusCode: 200...500) : 실패 코드를 상세적으로 볼 수 있음
print("prefetchRowsAt - url",url)
AF
.request(url, method: .get, headers: header)
.responseJSON { response in
switch response.result {
case .success(let value):
let json = JSON(value)
print("JSON: \(url)")
completionHandler(json)
case .failure(let error):
print(error)
}
}
}
이러한 코드를 Codable를 사용해서 바꾸면 이렇게 바꿀 수 있다.
import Foundation
// MARK: - KakaoVideo
struct KakaoVideo: Codable {
var documents: [Document]
}
// MARK: - Document
struct Document: Codable {
let author: String
let datetime: String
let playTime: Int
let thumbnail: String
let title: String
let link: String
var contents: String {
return "\(author) | \(playTime)회\n \(datetime)"
}
enum CodingKeys: String, CodingKey {
case author, datetime
case playTime = "play_time"
case thumbnail, title
case link = "url"
}
}
func callRequest(type: EndPoint, query: String, page: Int, completionHandler: @escaping (KakaoVideo?) -> () ) {
// 한글에 대한 인식이 안되기 때문에 한글에 대한 처리를 해줘야함
let text = query.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
let url = type.requestURL + text + "&page=\(page)"
// 카카오는 .validate(statusCode: 200...500) : 실패 코드를 상세적으로 볼 수 있음
print("prefetchRowsAt - url",url)
AF
.request(url, method: .get, headers: header)
.validate(statusCode: 200...500)
.responseDecodable(of: KakaoVideo.self) { response in
print("APIManger: \(response.value)")
// @escaping 클로저를 사용해서 KakaoVideo? 타입을 넘겨 줄 수 있다.
completionHandler(response.value)
}
}
과정만 알면 크게 어렵지 않았다.
VC에서 클로저를 활용해서 적용해보자
클로저로 넘어오는 result가 KakoVideo? "타입이니까 변수를 KakoVideo? 으로 만들고 append 해주면
videoList.documents에 하나씩 쌓이겠지?" 라고 생각하면서 만들었다...
var videoList: KakaoVideo?
func callRequest(query: String, page: Int) {
KakaoAPIManager.shared.callRequest(type: .video, query: query, page: page) { result in
guard let result else { return }
self.videoList?.documents.append(contentsOf: result.documents)
self.tableView.reloadData()
}
}
결과는... nil 이었다...
nil
어디서 부터 잘못된걸까? 자료형이 같으면 쓸 수 있을 거 같은데...
해서 플레이그라운드에 똑같이 만들어봤다.
같은 자료형의 옵셔널끼리 계산하고 있지만 컴파일 오류가 발생하는 것을 알 수 있다.
nil은 값이 없음을 의미하는 것이기 때문에
같은 자료형 옵셔널값이 오더라도 계산 할 수 없음
코드로 다시 돌아와서 그렇다면 어떻게 개선 할 수 있을까?
답은 아주 쉽다. 사용하려고 하는 변수의 자료형을 옵셔널로 처리하지 않고 빈값으로 만들면 된다.
var videoList: KakaoVideo = KakaoVideo(documents: [])
func callRequest(query: String, page: Int) {
KakaoAPIManager.shared.callRequest(type: .video, query: query, page: page) { result in
guard let result else { return }
self.videoList.documents.append(contentsOf: result.documents)
self.tableView.reloadData()
}
}
이렇게 하면 스크롤을 내려 page + 1을 했을때
append 시킬 수 있다.
'새싹' 카테고리의 다른 글
ScrollView안에 TableView생성시 스크롤 문제 (0) | 2023.08.21 |
---|---|
DispatchGroup에 대해 알아보자 part 1. (0) | 2023.08.21 |
API 호출제한 기억해두자 (0) | 2023.08.11 |
비슷하지만 다른 화면 전환의 공통점과 차이점 (0) | 2023.07.24 |
@IBOutlet Colletion으로 연결시 weak을 사용하지 못하는 이유 (0) | 2023.07.23 |