iOS KingFisher 사용법
KingFisher 란?
iOS에서 이미지를 관리해주는 오픈소스이다.
가령 URL에서 이미지를 요청하여 가져오는 경우를 생각해보자 기존의 경우 아래의 코드와 같이 단순하게 UIImageView에 직접적으로 이미지를 올릴뿐 아무런 작업을 하지 않는다.
@IBOutlet weak var imageView: UIImageView!
...
guard let url = URL(string: imageUrl) else { return nil }
guard let data = try? Data(contentsOf: url) else { return nil }
let image = UIImage(data: data)
imageView.image = image
하지만 만약 많은 양의 이미지 데이터가 올 경우나 용량이 큰 이미지 파일등을 다루어야 할 경우 이는 앱 성능에 심각한 영향을 준다. 이에 따라 image Cache 등 상황에 효율적으로 대처하기 위해서 추가적인 작업이 필요하다. 마찬가지로 위의 코드에서 실제로 동작을 할려면 아래와 같이 코드를 수정 해주어야 한다.
DispatchQueue.global().async {
guard let url = URL(string: imageUrl) else { return nil }
guard let data = try? Data(contentsOf: url) else { return nil }
let image = UIImage(data: data)
DispatchQueue.main.async {
self.imageView.image = image
}
}
또한 위처럼 URL로 된 이미지를 요청 하는 부분은 비동기적으로 동작이 되어야한다.(이미지를 다운받는데 다른 작업이 다 멈추고 이미지 다운을 기다릴수는 없다! ). 그리고 UI에 변화를 주는 작업은 main 스레드에서 동작하도록 설계해야한다.
Kingfisher는 아래와 같은 기능을 제공하여 위의 문제점을 해결하고 조금더 간결하고 직관적인 image 처리를 할 수 있다.
- 비동기 이미지 다운로드 및 Caching
URLSession
기반 네트워킹이 이루어진다. 그리고 기본 이미지 processor 및 filter가 제공된다.- 메모리와 디스크를 위한 다중 계층 캐시 제공
- 성능을 향상 시키기 위해서 다운로드 작업을 취소하거나 처리할 수 있는 작업이 있다
UIImageView
,NSImage
및UIButton
에 대한 확장으로 URL에서 이미지를 직접 설정가능하다- 필요에 따라
downLoader
,Caching
시스템을 별도로 사용한다. - 이미지를 설정 시 내장된 애니메이션을 사용가능하다.
- 확장 가능한 이미지 처리(아래에 추가적으로 설명하겠다.) 및 GIF 이미지 형식 지원
Kingfisher를 이용한 이미지 로드 구현
guard let url = URL(string: imageURLString) else { return }
// 이미지 로딩(비동기, 캐싱기능 포함)
let processor = RoundCornerImageProcessor(cornerRadius: 80)
// 이미지 변형 프로세서 설정(모서리 부분 동그랗게 )
imageView.kf.setImage(with: url, options: [.processor(processor)])
// 기본 : imageView.kf.setImage(with: url)
위와 같이 UIImageVIew
에서 kf
로 접근하여 kingfisher를 사용할 수 있다. 그리고 다양하게 효과들을 위와 같이 processor를 통해 할 수있다.
- Processor를 통한 이미지 확장 기능
// 둥근 모서리 효과
let processor = RoundCornerImageProcessor(cornerRadius: 20)
// 이미지 사이즈 재설정
let processor = ResizingImageProcessor(targetSizeL CGSize(width: 100, height: 100))
// 이미지 흐림(Blur) 정도
let processor = BlurImageProcessor(blurRadius: 5.0)
// Overlay 색상과 fraction(Overlay가 차지하는 비율) 설정
let processor = OverlayImageProcessor(overlay: .red, fraction: 0.7)
// Color Tint 설정
let processor = TintImageProcessor(tint: .blue)
// 인접(Adjust) 색상
let processor = ColorControlProcessor(brightness: 1.0, contrast: 0.7, saturation: 1)
// 흑백 설정
let processor = BlackWhiteProcessor()
중복된 processor 적용을 위해 >>
로 여러개를 나열할 수 있다.
- GIF 지원
let imageView = AnimatedImageView()
Kingfisher의 장점: High-resolution Image 처리
let url = URL(string: "https://example.com/high_resolution_image.png")
let processor = DownsamplingImageProcessor(size: imageView.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)")
}
}
kingfisher의 장점: 이미지 캐싱
kingfisher의 큰 장점 중 하나는 이미지를 캐싱하여 재접근 할 시에 캐시의 장점을 사용하여 이미지 로딩 시간을 다량으로 줄여준다. 기본적인 단계는 아래와 같다
imageView.kf.setImage
KingfisherManager.shared.retrieveImage
tryToRetrieveImageFromCache
ImageCache.default.retrieveImage
- 이미지 가져오는 작업
memoryCache
에서 저장된 이미지 캐시 가져오기- 1에서 찾지 못한 경우 디스크에서 찾는다.
memoryCache
및 디스크에 원본 저장
imageView.image = image
캐시를 사용하여 memoryCache
에 저장되어있는 이미지 캐시를 우선적으로 탐색 한 다음에 찾은 경우에 빠르게 가져오고 없는 경우에는 디스크에서 가져온다. 마찬가지로 캐시에 저장되는 기한등을 설정할 수 있는데 그 옵션 값은 아래와 같다.
ImageCache
클래스에 존재하는 프로퍼티로서 의미와 메모리 관리 기법은 다음과 같다.
maxCachePeriodInSecond
: 기본값 1주일maxMemoryCost
(기본값 0. no limit)SDWebImage
와 마찬가지로 역시NSCache
의 값을 조절한다.(캐시 임계값 설정)maxDiskCacheSize
(기본값 0. no limit)cacheMemoryOnly
,onlyFromCache
,forceRefresh
,fromMemoryCacheOrRefresh
clearMemoryCache
: memory warning notification 을 받았을때 호출한다 호출하면memoryCache
를 다지워준다.clearExpiredDiskCache
: 앱이 꺼지거나 백그라운드 진입시에 호출되는 함수이다. expire 된 것들을 지운다음, 여전히 디스크 용량을 많이 차지하고 있으면contentAccessData
로 정렬하여 지운다.
추가) KingFisher에서 URL에 한국어가 포함 되어있을 때 대처
addingPercentEncoding()
메서드 사용
// 원하는 imageURL을 addingPercentEncoding을 통해 바꿔준다.
let url = imageURL?.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)
imageView.kf.setImage(with: URL(string: url), placeholder: defaultImg, options: [.transition(ImageTransition.fade(0.5))])