작업중 동료분의 질문을 받던중 나도 모르던 정보를 알게 되었고 그것들을
정리 하기 위한 시간을 가져 보려고 합니다. 그중의 다운 샘플링도 알게되어 같이 정리해 볼께요
KingfisherManager.shared.retrieveImage(with: URL(string: imageUrl)!, options: [
.processor(processor),
.requestModifier(KingFisherNet()),
.scaleFactor(scale),
.cacheOriginalImage
]) { imageResult in
switch imageResult {
case .success(let result):
self.image = result.image
case .failure(let error):
// print(error)
break
}
}
“구글링 답변” : **컴퓨팅 및 컴퓨터 과학에서 외부 데이터 소스(일반적으로 메모리 또는 기타 데이터 스트림)에서 작업을 수행하는 전기 부품(디지털 회로)
흠 그래서 킹피셔에서 말하는건?
’이미지 처리를 위해 사용되는 하나의 구성 요소’**
일단 다운 샘플링이 무엇인지 알아야 겠죠?
이미지의 해상도를 실제 표시될 크기로 줄이는 과정
을 말합니다
즉 이미지 리사이징 개념과 비슷하죠!
let processor = DownsamplingImageProcessor(size: CGSize(width: 300, height: 300))
imageView.kf.setImage(
with: url,
options: [
.processor(processor),
.scaleFactor(UIScreen.main.scale)
]
)
가장 명확한 차이점은
이미지가 디코딩되는 단계에서 수행
VS
이미지가 이미 디코딩되어 메모리에 로드된 상태에서 수행
즉 이미지가 이미 로드 됬는데 리사이징을 하는 것인가?
아니면 이미지를 그리기 전에 걸러서 그리는 것인가 라는 개념입니다.
특정상황에 따라 선택하면 될 것 같은게
만약 사용자의 이미지를 저장할때는 그건 다운샘플링이 아니라 리사이징을 해야하는 것이고
네트워크를 통해 혹은 다른 루트에 의해 받아져야 할때 는 다운 샘플링 으로 처리해야 할 것 같습니다.
킹피셔도 결국엔 네트워크를 통해 이미지를 불러오는 라이브러리 이다 보니
중간에 헤더나, 토큰이나, 특정 URL 변경등 의 상황에 대처할수 있게 만들어준 기능이죠.다음은 위와 같은 상황을 담아놓은 예시 코드입니다.
import Kingfisher
import Foundation
final class KingFisherNet: ImageDownloadRequestModifier {
private
let baseURL = APIKey.baseURL.rawValue // 베이스 URL
private
let version = "/v1/" // 버전정보
func modified(for request: URLRequest) -> URLRequest? {
// 토큰을 추가 하기 위한 과정
guard let accessTokken = TokenStorage.shared.accessToken else {
return nil
}
// URLComponts 조립과정 시작
var components = URLComponents(string: baseURL) // 1. 베이스 URL
components?.path = version + (request.url?.path() ?? "") // 패스 추가
guard let url = components?.url else { // URL 변환
return nil
}
var urlRequest = URLRequest(url: url) // URL Request 변환
// 헤더 추가
urlRequest.addValue(accessTokken, forHTTPHeaderField: NetHTTPHeader.authorization.rawValue)
// 키 추가
urlRequest.addValue(APIKey.sesacKey.rawValue, forHTTPHeaderField: NetHTTPHeader.sesacKey.rawValue)
return urlRequest
}
}
URL을 통해 이미지를 검색 처리하는 작업을 수행하는데 이미지를 다운로드 하기전에
이미 캐시된 이미지가 있다면 캐시 이미지를 사용합니다.
종류는 대표적인 것으로 준비해 왔습니다.
- .forceRefresh : 나 캐쉬 안해
- .onlyFromCache : 캐쉬 한 것만 쓸래
- .cacheOrigialImage
이미지 다운(통신) 을 성공적으로 처리하였다면 원본 데이터를 킹피셔 캐시 시스템에
저장합니다. 즉 같은 URL이미지를 재 요청시엔 이미 다운로드된 데이터를 로드할수 있어요!
imageView.kf.setImage(
with: url,
placeholder: UIImage(named: "placeholder"),
options: [
.processor(DownsamplingImageProcessor(size: imageView.bounds.size)),
.scaleFactor(UIScreen.main.scale),
.cacheOriginalImage
]
)
public enum CacheType {
/// The image is not cached yet when retrieving it.
/// 이미지를 검색할 때 이미지가 아직 캐시되지 않았습니다.
case none
/// The image is cached in memory.
/// 이미지가 메모리에 캐시되어 있습니다.
case memory
/// The image is cached in disk.
/// 이미지가 디스크에 캐시됩니다.
case disk
/// Whether the cache type represents the image is already cached or not.
/// 캐시 유형이 이미지가 이미 캐시되어 있는지 여부를 나타냅니다.
public var cached: Bool {
switch self {
case .memory, .disk: return true
case .none: return false
}
}
}
++ /// 디스크에 저장되는 캐시의 기간은 7일
open var maxCachePeriodInSecond: TimeInterval = 60 * 60 * 24 * 7 //Cache exists for 1 week
+++ // +++ 캐시 사이즈나 개수를 지정 할수 있습니다.
// Limit memory cache size to 300 MB.
cache.memoryStorage.config.totalCostLimit = 300 * 1024 * 1024
// Limit memory cache to hold 150 images at most.
cache.memoryStorage.config.countLimit = 150
// Limit disk cache size to 1 GB.
cache.diskStorage.config.sizeLimit = = 1000 * 1024 * 1024
// Memory image expires after 10 minutes.
cache.memoryStorage.config.expiration = .seconds(600)
// Disk image never expires.
cache.diskStorage.config.expiration = .never
이말인 즉 메모리에 캐시되어 있을건지 디스크에 캐시해 놓을건지 인데
추가적으로 디스크에 저장되는 캐시의 기간은 7일이다.
none
- 이미지가 아직 어떠한 캐시에도 저장되지 않았음을 의미합니다.
이미지가 처음 요청되었을 때, 캐시에서 해당 이미지를 찾을 수 없음을 말하며,
네트워크를 통해 이미지를 다운로드해야 함을 말합니다!memory
- 이미지가 메모리 캐시에 저장되어 있음을 나타냅니다
메모리 캐시는 빠른 속도를 제공하지만, 앱이 종료되면 사라지는 휘발성 캐시입니다.
메모리에 캐시된 이미지는 앱이 실행 중인 동안 빠르게 접근할 수 있으며,
반복적인 이미지 로딩에 유용하게 사용됩니다.disk
- 이미지가 디스크 캐시에 저장되어 있음을 의미해요
디스크 캐시는 비교적 느린 속도를 가지지만, 앱이 종료된 후에도 지속됩니다.
이를 통해 앱을 재시작하거나 장기간에 걸쳐 이미지를 유지할 필요가 있을 때 유용하게 사용됩니다!
imageView.kf.setImage(
with: url,
options: [
.processor(DownsamplingImageProcessor(size: imageView.bounds.size)),
.scaleFactor(UIScreen.main.scale),
.cacheOriginalImage,
.memoryCacheExpiration(.days(1)), // 메모리 캐시 유지 기간을 1일로 설정
.diskCacheExpiration(.never) // 디스크 캐시는 만료되지 않도록 설정
]
)