Kingfisher를 몇번 사용해보았지만 정확히 무슨 기능이 있는지도 모르는 채 이미지 띄우기만 사용해보았다. 프로젝트를 진행하면서 사용해본 것들을 정리해보려 한다!
✅ 이미지 다운로드 요청 시 헤더값을 추가하여 요청하기
프로젝트 진행하면서 서버에 저장되어 있는 이미지를 주소값을 사용하여 받아와야 했다.
분명 url도 맞는데 사진이 뜨지 않아서 오류를 탐색한 결과 kingfisher를 사용하여 서버에 이미지를 요청할 때 access token과 서버 요청을 위한 key값이 필요했던 것이다..
기존 네트워크 통신과 같게 kingfisher로 이미지 요청 시 헤더 값을 지정하면 된다!
🔎 해결
owner.mainView.imageView.kf.setImage(with: url)
을 이용하여 그냥저냥 이미지를 띄우기만 했는데 setImage 메서드 내부에 여러 파라미터가 존재했고! 그 중 option 파라미터를 사용하면 헤더 값을 추가할 수 있다.
let imgURL = BaseURL.baseURL+"/"+data.image[0]
let url = URL(string:imgURL)
let modifier = AnyModifier { request in
var r = request
r.setValue(UserDefaultsHelper.token, forHTTPHeaderField: "Authorization")
r.setValue(APIKey.key, forHTTPHeaderField: "SesacKey")
return r
}
mainView.imageView.kf.setImage(with: url, options: [.requestModifier(modifier)])
kingfisher의 옵션 중 .requestModifier를 사용하여 이미지 요청 시 헤더 값을 추가하여 요청할 수 있다.
AnyModifier를 사용하여 요청 시 보낼 헤더 값을 설정하여 해당 Modifier를 option 값으로 지정한다.
요청 결과로 이미지 뷰에 알맞게 이미지가 나타나는 것을 볼 수 있다!
✅ 이미지 에러 핸들링
owner.mainView.imageView.kf.setImage(with: url, options: [.requestModifier(ImageLoadManager.shared.getModifier())]) { result in
switch result {
case .success(let data):
owner.mainView.imageView.image = data.image
case .failure(_):
owner.mainView.imageView.image = UIImage(systemName: "person")
}
}
setImage의 파라미터 중 completionHandler를 사용하여 이미지 요청 성공과 실패에 따라 처리할 수 있다.
✅ 이미지 캐싱 사용하기
매번 이미지를 사용할 때 마다 네트워크 통신을 통해 다운을 받게되면 서버통신 비용에 부담이 되기 때문에 캐싱을 통해서 비용 부담을 줄일 수 있다.
이미 이전에 다운받은 적 있는 이미지인 경우 캐시를 통해 이미 저장되어 있는 이미지를 가지고 올 수 있고, Kingfisher는 이미지 캐싱을 쉽게 처리할 수 있는 라이브러리인 만큼 어렵지 않게 캐싱 기능을 구현할 수 있다.
UIImageView의 extension을 통해 ImageView에 이미지 설정 시 캐시가 존재하는지 여부를 파악 후 이미지를 설정하도록 구현하였다.
extension UIImageView {
func setImage(with urlString: String) {
self.kf.indicatorType = .activity
ImageCache.default.retrieveImage(forKey: urlString, options: nil) { result in
switch result {
case .success(let value):
if let image = value.image {
//캐시가 존재하는 경우
self.image = image
} else {
//캐시가 존재하지 않는 경우
guard let url = URL(string: urlString) else { return }
let resource = KF.ImageResource(downloadURL: url, cacheKey: urlString)
self.kf.setImage(
with: resource,
options: [
.requestModifier(ImageLoadManager.shared.getModifier()),
.transition(.fade(1.0))
]) { result in
switch result {
case .success(let data):
self.image = data.image
case .failure(_):
self.image = UIImage(systemName: "person")
}
}
}
case .failure(let error):
print(error.localizedDescription)
}
}
}
}
📝 참고
'iOS > 🔎 swift 정리하기' 카테고리의 다른 글
[Swift] Swift Concurrency async / await (0) | 2024.04.03 |
---|---|
[iOS/RxSwift] CombineLatest vs Observable.zip (0) | 2023.11.19 |
RxSwift 정리하기 (0) | 2023.11.08 |
[iOS/Swift] MapKit Annotation displayPriority 지정하기 (0) | 2023.10.20 |
MapKit CustomAnnotation (0) | 2023.10.10 |