본문 바로가기
Swift 개발 이야기

Image Cache in Swift - 이미지 캐싱 사용해보기

by 방화동한량 2020. 10. 19.
728x90

굿데이 여러분 오늘은 이미지 캐싱에 대해서 알아보도록 할게여

 

매번 이미지를 가져올때마다 네트워킹을 하게 된다면 정말로 비효율적인 앱이 되겠쥬?

 

한번 받아둔 이미지는 캐시에 저장해서 캐시가 자동적으로 지워지기 전까진 아주-빠르게 이미지를 처리할 수 있게 해봅쉬다

 

물론 킹피셔나 알라모파이어이미지와 같은 라이브러리를 사용하면 좋긴 하지만 오늘은 그런거 없이 퓨어하게 가보도록 하겠읍니더ㅏ

 

먼저 캐시를 저장해놓을 Singleton class 를 하나 만들어볼게여

 

class ImageCacheManager {
    
    static let shared = NSCache<NSString, UIImage>()
    
    private init() {}
}

 

참 쉽죠?

 

이번엔 URL 을 통해서 이미지를 불러올 수 있게 UIImageView 의 extension 을 만들어보겠슴다

 

extension UIImageView {
    
    func setImageUrl(_ url: String) {
        
        DispatchQueue.global(qos: .background).async {
            if let url = URL(string: url) {
                URLSession.shared.dataTask(with: url) { (data, res, err) in
                    if let _ = err {
                        DispatchQueue.main.async {
                            self.image = UIImage()
                        }
                        return
                    }
                    DispatchQueue.main.async {
                        if let data = data, let image = UIImage(data: data) {
                            self.image = image
                        }
                    }
                }.resume()
            }
        }
    }
 }

 

어렵지 않은 코드죵? URLSession 을 통해 데이터를 받아와서 해당 데이터를 UIImage 로 변환시켜서 보여주는 아주아주 간단한 방식입니다

 

하지만 이 코드를 그대로 사용하게 되면 이미지를 불러올때마다 계속해서 네트워킹을 하게 되겠죠? 이제 미리 만들어두었던 캐시매니저를 써보도록 하게씀니다

 

    func setImageUrl(_ url: String) {
        
        let cacheKey = NSString(string: url) // 캐시에 사용될 Key 값
        
        if let cachedImage = ImageCacheManager.shared.object(forKey: cacheKey) { // 해당 Key 에 캐시이미지가 저장되어 있으면 이미지를 사용
            self.image = cachedImage
            return
        }
        
        DispatchQueue.global(qos: .background).async {
            if let imageUrl = URL(string: url) {
                URLSession.shared.dataTask(with: imageUrl) { (data, res, err) in
                    if let _ = err {
                        DispatchQueue.main.async {
                            self.image = UIImage()
                        }
                        return
                    }
                    DispatchQueue.main.async {
                        if let data = data, let image = UIImage(data: data) {
                            ImageCacheManager.shared.setObject(image, forKey: cacheKey) // 다운로드된 이미지를 캐시에 저장
                            self.image = image
                        }
                    }
                }.resume()
            }
        }
    }

 

추가된 부분은 cacheKey 부분과 cacheImage, 그리고 캐시에 이미지를 저장하는 부분 세부분 입니다

 

어렵지 않져??

 

아주 간단하게 이미지 캐싱에 대해 알아보았읍니다

 

다음에 그럼 또 만나여 여러분

 

안녕~~~~