[iOS/Kingfisher] 네트워크 통신으로 이미지 받아오기

2023. 11. 26. 19:33·iOS/UIKit&SwiftUI

 

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를 사용하여 이미지 요청 시 헤더 값을 추가하여 요청할 수 있다.

Untitled.png

AnyModifier를 사용하여 요청 시 보낼 헤더 값을 설정하여 해당 Modifier를 option 값으로 지정한다.

Untitled.png

요청 결과로 이미지 뷰에 알맞게 이미지가 나타나는 것을 볼 수 있다!

✅ 이미지 에러 핸들링

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)
            }
        }
    }
}

 

📝 참고

https://duwjdtn11.tistory.com/594

https://ios-development.tistory.com/793

'iOS > UIKit&SwiftUI' 카테고리의 다른 글

[iOS/SwiftUI] Text 더보기 버튼 만들기 - ViewThatFits  (1) 2024.04.19
[iOS/UIKit] 토글되는 컬렉션뷰 만들기 - NSDiffableDataSourceSectionSnapshot  (0) 2024.02.22
View의 Drawing Cycle  (0) 2023.11.11
[iOS/Swift] MapKit Annotation displayPriority 지정하기  (0) 2023.10.20
MapKit CustomAnnotation  (1) 2023.10.10
'iOS/UIKit&SwiftUI' 카테고리의 다른 글
  • [iOS/SwiftUI] Text 더보기 버튼 만들기 - ViewThatFits
  • [iOS/UIKit] 토글되는 컬렉션뷰 만들기 - NSDiffableDataSourceSectionSnapshot
  • View의 Drawing Cycle
  • [iOS/Swift] MapKit Annotation displayPriority 지정하기
김졀니
김졀니
🍎 iOS 개발
  • 김졀니
    졀니의 개발 공부✨
    김졀니
  • 전체
    오늘
    어제
    • 분류 전체보기
      • iOS
        • Swift
        • UIKit&SwiftUI
        • RxSwift&Combine
        • WWDC
      • Study
        • 🚨 TroubleShooting
        • 🌱 SeSAC
  • 블로그 메뉴

    • 홈
    • Github
  • 인기 글

  • 최근 글

  • 태그

    ReactorKit
    @PropertyWrapper
    pointfree
    ios
    wwdc23
    layoutIfNeeded
    actor
    concurrency
    CLLocation
    인앱리뷰
    clipstobounds
    swiftdata
    traits
    Realm
    Swift
    Sendable
    Drawing Cycle
    의존성 주입
    mainactor
    kingfisher header
    mapkit
    RxSwift
    동시성프로그래밍
    FileManager
    displayPriority
    OperationQueue
    이미지 캐싱
    observable
    위치 권한
    swift concurrency
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.3
김졀니
[iOS/Kingfisher] 네트워크 통신으로 이미지 받아오기
상단으로

티스토리툴바