안녕하세요. Skillist입니다.
이번엔 Unsplash API를 활용하여, 사진 목록 받아오기를 해볼게요
dataTask를 통해서 받아올건데요, 한번 볼게요. 생각보다 복잡해요??가 아니라 간단해요~~
13라인 : Unsplach의 기본 url은 변경되지 않을거기 때문에, 저는 따로 URLComponent로 구현했습니다. 뒤에 API마다 path가 달라지는 것이지, scheme이나, host는 고정돼있잖아요.
22라인 : pageNum은 변경되기 때문에, 전달 받도록 했고, completionHandler 또한 넘겨 받습니다.
url에 대한 path와 api에 필요한 쿼리파람을 추가했어요.
아!!! "client_di"에는 본인의 unsplash key를 등록하세요!!
그리고, dataTask를 수행합니다.
dataTask 작업 결과에 대한 로직은 fetchPhotos를 호출한 곳에 있겠죠?
저는 PhotoListViewController에서 호출합니다.
62라인 : 데이터를 가져옵니다.
72라인 : statusCode가 성공 범위(200번대)에 속하면, json을 파싱하고, 파싱에 성공하면 데이터를 추가 및 reload 합니다.
63, 96, 102 라인 : 실패한 경우 실패에 대한 alert을 보여줍니다. UI작업이니, 메인쓰레드에서 수행하도록 DispatchQueue.main.async를 사용했습니다.
statusCode가 성공 범위(200번대) 외인 경우 error 케이스를 더 쪼갤수 있지만, 하나도 퉁쳤습니다.
참고로, 현업에선 에러를 파악할 수 있게끔, 에러 종류를 쪼개서 error 코드를 보여주거나, 관련 상세 정보를 보여주기도 합니다.
참고로 Photo는 Decodable struct입니다.
json을 디코딩 할수 있죠.
다음과 같이 작성하는데요, 어떤식으로 작성해야 하는지 알고있다면, 엄청 귀찮은 부분이기도 합니다.
그래서 저는 Codable을 생성해주는 툴을 소개할게요.
다음 URL에서 확인해주세요.
https://skillist.tistory.com/266
잘못되거나 부족한 내용 등, 피드백 감사합니다!
Skillist의 Unsplash 프로젝트
https://github.com/DeveloperSkillist/UnsplashCloneCode
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 전체 코드 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
import Foundation
class UnsplashAPI {
//unsplash 기본 URLComponent
//https://api.unsplash.com/photos?page=1
static var unsplashURLComponent: URLComponents {
var urlComponents = URLComponents()
urlComponents.scheme = "https"
urlComponents.host = "api.unsplash.com"
return urlComponents
}
//photo 목록 fetch
//https://unsplash.com/documentation#list-photos
static func fetchPhotos(pageNum: Int, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) {
var urlComponents = unsplashURLComponent
urlComponents.path = "/photos"
urlComponents.queryItems = [
URLQueryItem(name: "page", value: String(pageNum)),
URLQueryItem(name: "per_page", value: "30"),
//본인의 accesskey를 입력하세요.
URLQueryItem(name: "client_id", value: APIKeys.accesskey)
]
guard let url = urlComponents.url else {
return
}
var request = URLRequest(url: url)
request.httpMethod = "GET"
let dataTask = URLSession.shared.dataTask(with: url, completionHandler: completionHandler)
dataTask.resume()
}
//category 목록 fetch
//https://api.unsplash.com/topics
static func fetchCategories(completionHandler: @escaping (Data?, URLResponse?, Error?) ->Void ) {
var urlComponents = unsplashURLComponent
urlComponents.path = "/topics"
urlComponents.queryItems = [
//본인의 accesskey를 입력하세요.
URLQueryItem(name: "client_id", value: APIKeys.accesskey)
]
guard let url = urlComponents.url else {
return
}
var request = URLRequest(url: url)
request.httpMethod = "GET"
let dataTask = URLSession.shared.dataTask(with: url, completionHandler: completionHandler)
dataTask.resume()
}
}
//이미지 fetch 구현
private func fetchPhotos(isRefresh: Bool = false) {
if isFetching {
return
}
isFetching = true
//현재 페이지에 1을 더하여 다음 페이지 가져오기
UnsplashAPI.fetchPhotos(pageNum: pageNum + 1) { [weak self] data, response, error in
self?.isFetching = false
guard error == nil,
let response = response as? HTTPURLResponse,
let data = data else {
DispatchQueue.main.async { //에러 발생 시 에러 보여주기
self?.showNetworkErrorAlert(error: .networkError)
}
return
}
switch response.statusCode {
//response 성공 시, 목록 설정하기
case (200...299):
do {
let fetchedPhotos = try JSONDecoder().decode([Photo].self, from: data)
if self?.pageNum == 0 { //첫페이지를 가져온 경우 목록 설정
self?.photos = fetchedPhotos
} else { //첫페이지 외 다음페이지를 가져온 경우 목록 설정
self?.photos.append(contentsOf: fetchedPhotos)
}
DispatchQueue.main.async {
//리프레시 한 경우 refreshControl 종료
if isRefresh {
self?.collectionView.refreshControl?.endRefreshing()
}
//다음 페이지 번호 설정
self?.pageNum += 1
self?.collectionView.reloadData()
}
} catch {
DispatchQueue.main.async { //에러 발생 시 에러 보여주기
self?.showNetworkErrorAlert(error: .jsonParsingError)
}
}
default:
DispatchQueue.main.async { //에러 발생 시 에러 보여주기
self?.showNetworkErrorAlert(error: .networkError)
}
return
}
}
}
'iOS 개발 > Unsplash 클론 코딩' 카테고리의 다른 글
Unsplash - 8. 사진 상세 화면(PhotoDetailViewController, Cell)의 메인 로직 (0) | 2021.12.01 |
---|---|
Unsplash - 7. 사진 목록 구현하기 (0) | 2021.11.30 |
Unsplash - 5. 다운로드 가능한 이미지뷰와 이미지 캐싱 (1) | 2021.11.30 |
Unsplash - 4. 메인 사진 목록에 대한 Cell 구성 (0) | 2021.11.29 |
Unsplash - 3. SceneDelegate와 TabBarController (0) | 2021.11.29 |