꾸준히 안타치기

이미지를 캐시하는 방법 / NSCache, KingFisher 본문

iOS/문제해결

이미지를 캐시하는 방법 / NSCache, KingFisher

글자줍기 2022. 5. 10. 15:36
반응형

서버에서 이미지를 불러올때 매번 URL을 호출해서 이미지를 가지고 왔었는데, 이미지를 가져올때마다 새로 불러오느냐고 질문을 주셔서 이 부분에 대해서 생각을 하게 되었다.

생각해보니 그러면 리소스도 많이들고, 비용이 많이 드는 문제가 있을 것 같았다. 메모리에 잠시 저장하는 캐시라는 것이 있다는 것을 알았고 이미지 캐시를 어떻게 하면 좋을지 공부해보았다.


캐시란?

3.컴퓨터캐시메모리: 주(主)기억 장치에 들어 있는 데이터의 일부를 일시적으로 보관하는 고속 기억 장치.

 

캐시를 왜 써야할까?

매번 이미지를 가져올때마다 네트워킹을 하게 된다면 비효율적! (리소스 낭비, 다운로드시간 낭비)

한번 받아둔 이미지는 캐시에 저장해서 자동적으로 지워지기 전까지 빠른처리를 하게한다.

 

이미지를 캐시하는 방법을 찾아보니?

NSCache, FileManager, kingFisher, Alamofire등의 키워드를 발견함

 

NSCache?

https://developer.apple.com/documentation/foundation/nscache

key-value쌍을 임시로 저장하는데 사용되는 변경 가능한 Collection

NSCache는 주로 Memory Caching 사용되는 클래스로 메모리에서 해제될  자동으로 캐시된 내용이 제거



캐시 개체는 다른 변경 가능한 컬렉션과는  가지 면에서 다릅니다.


NSCache 클래스는 캐시가 시스템 메모리를 너무 많이 사용하지 않도록 하는 다양한 자동 제거 정책을 통합합니다. 다른 응용 프로그램에서 메모리가 필요한 경우 이러한 정책은 캐시에서 일부 항목을 제거하여 메모리 공간을 최소화합니다.


직접 캐시를 잠그지 않고도 다른 스레드에서 캐시에 있는 항목을 추가, 제거  쿼리할  있습니다.


NSMutableDictionary 개체와 달리 캐시는 캐시에 포함된 주요 개체를 복사하지 않습니다.


일반적으로 NSCache 개체를 사용하여 생성 비용이 많이 드는 임시 데이터가 있는 개체를 임시로 저장합니다. 이러한 개체를 재사용하면 해당 값을 다시 계산할 필요가 없으므로 성능상의 이점을 얻을  있습니다. 그러나 개체는 응용 프로그램에 중요하지 않으며 메모리가 부족할 경우 폐기될  있습니다. 만약 폐기된다면, 그들의 값은 필요할  다시 계산되어야  것이다.


사용하지 않을  폐기할  있는 하위 구성 요소가 있는 개체는 NSDiscardableContent 프로토콜을 채택하여 캐시 제거 동작을 개선할  있습니다. 기본적으로 캐시의 NSDiscardableContent 객체는 콘텐츠가 삭제되면 자동으로 제거되지만  자동 제거 정책은 변경될  있습니다. NSDiscardableContent 객체가 캐시에 저장되는 경우 캐시는 해당 개체를 제거할  해당 개체의 ContentIfPossible() 폐기합니다.

캐시는 Memory Caching 와 Disk Caching 두 종류가 있다.

memory cache에는 NSCache가 있고

disk cache를 사용하는 방법은 1. FileManager객체 사용해 데이터를 파일형태로 디스크에 저장하는 방법

 2. UserDefaults, CoreData를 사용하는 방법이 있음

API를 호출해서 이미지 URL을 받아온 다음에 캐시가 진행되는 과정

NSCache 

 

[Swift] Image Cache처리 (NSCache, FileManager)

서버에서 이미지를 불러올때 이미지 URL을 받고 다시 해당 URL로 통신을 하는 식으로 이미지를 받아온다면 비효율적이겠죠?? 또한 이미지크기도 크다고하면 더욱 좋지 않을거같아요..! 그래서!!

nsios.tistory.com


KingFisher 

이런캐싱을 쉽게 해주는 라이브러리인 킹피셔를 사용해서 이미지를 캐싱했다.

https://github.com/onevcat/Kingfisher

 

GitHub - onevcat/Kingfisher: A lightweight, pure-Swift library for downloading and caching images from the web.

A lightweight, pure-Swift library for downloading and caching images from the web. - GitHub - onevcat/Kingfisher: A lightweight, pure-Swift library for downloading and caching images from the web.

github.com

특징

  • 비동기식 이미지 다운로드 및 캐싱.
  • URLSession기반 네트워킹 또는 로컬 제공 데이터 에서 이미지를 로드 합니다.
  • 유용한 이미지 프로세서 및 필터가 제공됩니다.
  • 메모리와 디스크 모두를 위한 다중 계층 하이브리드 캐시.
  • 캐시 동작에 대한 미세 제어. 사용자 정의 가능한 만료 날짜 및 크기 제한.
  • 성능 향상을 위해 다운로드를 취소하고 이전에 다운로드한 콘텐츠를 자동으로 재사용합니다.
  • 독립 구성 요소. 필요에 따라 다운로더, 캐싱 시스템 및 이미지 프로세서를 별도로 사용합니다.
  • 이미지를 미리 가져오고 캐시에서 표시하여 앱을 향상시킵니다.
  • UIImageView, NSImageView, NSButton및 UIButtonURL에서 이미지를 직접 설정하려면 확장자를 봅니다.
  • 이미지를 설정할 때 내장된 전환 애니메이션.
  • 이미지를 로드하는 동안 사용자 지정 가능한 자리 표시자 및 표시기.
  • 확장 가능한 이미지 처리 및 이미지 형식을 쉽게.
  • 낮은 데이터 모드 지원.
  • SwiftUI 지원.

이미지 URL을 가져오는 부분에 붙여서 사용하면 된다.

import Kingfisher

let url = URL(string: "https://example.com/image.png")
imageView.kf.setImage(with: url)

옵션 +

let url = URL(string: "https://example.com/high_resolution_image.png")
let processor = DownsamplingImageProcessor(size: imageView.bounds.size)
             |> RoundCornerImageProcessor(cornerRadius: 20)
imageView.kf.indicatorType = .activity
imageView.kf.setImage(
    with: url,
    placeholder: UIImage(named: "placeholderImage"),
    options: [
        .processor(processor),
        .scaleFactor(UIScreen.main.scale),
        .transition(.fade(1)),
        .cacheOriginalImage
    ])
{
    result in
    switch result {
    case .success(let value):
        print("Task done for: \(value.source.url?.absoluteString ?? "")")
    case .failure(let error):
        print("Job failed: \(error.localizedDescription)")
    }
}

킹피셔사용예제

https://www.youtube.com/watch?v=JYqLtV1i7io&t=612s 

 

 

참조

https://developer.apple.com/documentation/foundation/nscache 애플공식

https://nsios.tistory.com/58 NSCache

https://snowee.tistory.com/56 NSCache

https://duwjdtn11.tistory.com/594 킹피셔사용법

https://poisonf2.tistory.com/98 킹피셔해석 

반응형
Comments