[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  (2) 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
  • 인기 글

  • 최근 글

  • 태그

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

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

티스토리툴바