관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 1. Kingfisher 프레임워크 (이미지 캐싱, 이미지 로드) - 사용 방법 본문

iOS framework

[iOS - swift] 1. Kingfisher 프레임워크 (이미지 캐싱, 이미지 로드) - 사용 방법

jake-kim 2021. 12. 9. 23:53

1. Kingfisher 프레임워크 (이미지 캐싱, 이미지 로드) - 사용 방법

2. Kingfisher 프레임워크 (이미지 캐싱, 이미지 로드) - .processor, progressiveJPEG 옵션

Kingfisher 기능

  • 이미지 로드 기능 (url을 넘겨주면 이미지 로드)
  • 이미지 캐시 기능
  • UIImageView에 편리하게 round 처리 기능
  • 이미지 다운로드 기능

의존성

  • cocoapods 사용 시 설치
    pod 'Kingfisher'​

이미지 로드 기능

  • 이미지 단순히 불러오기 - .kf.setImage(with:)
private func loadImage() {
  guard let url = URL(string: "https://live.staticflickr.com/65535/51734305911_f4541d7629_m.jpg") else { return }
  myImageView.kf.setImage(with: url)
}
  • indicator 표출 기능 - .kf.indicatorType = .activity
    myImageView.kf.indicatorType = .activity
    myImageView.kf.setImage(
      with: url,
      placeholder: nil,
      options: nil,
      completionHandler: nil
    )
  • 이미지를 가져오는 동안 애니메이션 표출 - options: [.transition(.fade(1.2)]
    • 아래 코드는 최대 1.2초이며, 그전에 이미지를 가져오면 애니메이션 미표출
      myImageView.kf.indicatorType = .activity
      myImageView.kf.setImage(
        with: url,
        placeholder: nil,
        options: [.transition(.fade(1.2))],
        completionHandler: nil
      )​
  • 이미지를 가져오는 동안 애니메이션 표출 - options: [.transition(.fade(1.2))]
    • (최대 1.2초)
      myImageView.kf.indicatorType = .activity
      myImageView.kf.setImage(
        with: url,
        placeholder: nil,
        options: [.transition(.fade(1.2))],
        completionHandler: nil
      )​
  • 이미지를 가져오는 시간이 짦아도 transition이 되도록 설정 - options: [.forceTransition]
myImageView.kf.indicatorType = .activity
myImageView.kf.setImage(
  with: url,
  placeholder: nil,
  options: [
    .transition(.fade(1.2)),
    .forceTransition
  ],
  completionHandler: nil
)
  • 이미지 뷰 round 처리 - RoundCornerImageProcessor 인스턴스를 .processor()의 생성자로 주입
let cornerImageProcessor = RoundCornerImageProcessor(cornerRadius: 30)
myImageView.kf.indicatorType = .activity
myImageView.kf.setImage(
  with: url,
  placeholder: nil,
  options: [
    .transition(.fade(1.2)),
    .forceTransition,
    .processor(cornerImageProcessor)
  ],
  completionHandler: nil)
  • 이미지 로드 실패 시 재시도 - DelayRetryStrategy 인스턴스를 .retryStraregy() 생성자로 주입
let retryStrategy = DelayRetryStrategy(maxRetryCount: 2, retryInterval: .seconds(3))
let cornerImageProcessor = RoundCornerImageProcessor(cornerRadius: 30)
myImageView.kf.indicatorType = .activity
myImageView.kf.setImage(
  with: url,
  placeholder: nil, options: [
    .retryStrategy(retryStrategy),
    .transition(.fade(1.2)),
    .forceTransition,
    .processor(cornerImageProcessor)
  ],
  completionHandler: nil)
  • 퍼센티지 - progressBlock 사용
let retryStrategy = DelayRetryStrategy(maxRetryCount: 2, retryInterval: .seconds(3))
let cornerImageProcessor = RoundCornerImageProcessor(cornerRadius: 30)
myImageView.kf.setImage(
  with: url,
  placeholder: nil,
  options: [
    .retryStrategy(retryStrategy),
    .transition(.fade(1.2)),
    .forceTransition,
    .processor(cornerImageProcessor)
  ],
  progressBlock: { receivedSize, totalSize in
    let percentage = (Float(receivedSize) / Float(totalSize)) * 100.0
    print("이곳")
    print(percentage)
  },
  completionHandler: nil
)

캐시에 추가

  • 이미지 캐시 없이, 계속 새로 받아야 하는 경우 처리
    myImageView.kf.setImage(with: url, options: [.forceRefresh])​
  • 네트워크가 끊겨진 경우와 같이, 캐시에서만 이미지를 로드하는 기능
    imageView.kf.setImage(with: url, options: [.onlyFromCache])​
  • 종합 캐시 처리 - UIIMageView의 extension으로 사용
extension UIImageView {
  func setImage(with urlString: String) {
    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 = ImageResource(downloadURL: url, cacheKey: urlString)
          self.kf.setImage(with: resource)
        }
      case .failure(let error):
        print(error)
      }
    }
  }
}

캐시 삭제

  • 현재 디스크 캐시 크기 확인
private func checkCurrentCacheSize() {
  //현재 캐시 크기 확인
  ImageCache.default.calculateDiskStorageSize { result in
    switch result {
    case .success(let size):
      print("disk cache size = \(Double(size) / 1024 / 1024)")
    case .failure(let error):
      print(error)
    }
  }
}
  • 캐시 삭제
private func removeCache() {
  //모든 캐시 삭제
  ImageCache.default.clearMemoryCache()
  ImageCache.default.clearDiskCache { print("done clearDiskCache") }
  
  //만료된 캐시만 삭제
  ImageCache.default.cleanExpiredMemoryCache()
  ImageCache.default.cleanExpiredDiskCache { print("done cleanExpiredDiskCache") }
}

이미지 다운로드

  • ImageResource 생성자에 url을 넣어서 얻은 resource 인스턴스를 KinfisherManager.shared.retrieveImage에서 사용
private func downloadImage(with urlString: String) {
  guard let url = URL(string: urlString) else { return }
  let resource = ImageResource(downloadURL: url)
  KingfisherManager.shared.retrieveImage(with: resource,
                                         options: nil,
                                         progressBlock: nil) { result in
    switch result {
    case .success(let value):
      print(value.image)
    case .failure(let error):
      print("Error: \(error)")
    }
  }
}

* 전체 코드: https://github.com/JK0369/ExKingfisher

 

* 참고

- https://github.com/onevcat/Kingfisher

Comments