EEYatHo 앱 깎는 이야기

Swift ) 이미지 다운로드, 캐싱 - EEYatHo iOS 본문

iOS, Swift/Feature

Swift ) 이미지 다운로드, 캐싱 - EEYatHo iOS

EEYatHo 2022. 6. 21. 12:23
반응형

 

 

UIImageView 이미지 다운로드 구현


Placeholder Image 지원

Image 넣는 부분은 main queue로 작업

외부 라이브러리 없이 URLSesstion dataTask 사용

 

extension UIImageView {
    func imageDown(urlStr: String, placeholderImage: UIImage? = nil) {
        
        func _setImage(image: UIImage?) {
            DispatchQueue.main.async { [weak self] in
                self?.image = image
            }
        }
        
        // 캐싱 체크
        if let image = ImageCacheManager.shared.getImage(urlStr) {
            _setImage(image: image)
            return
        }
        
        // URL 에러 처리
        guard let url = URL(string: urlStr) else {
            _setImage(image: placeholderImage)
            return
        }
        
        let task = URLSession.shared.dataTask(with: url) { data, response, error in
            // 반환된 에러 처리
            if let e = error {
                print("ImageDown DataTask Error: \((e as NSError).code)")
                _setImage(image: placeholderImage)
                return
            }
            
            // status code 에러 처리
            if let r = response as? HTTPURLResponse, !(200...299).contains(r.statusCode) {
                print("ImageDown Response Error: \(r.statusCode)")
                _setImage(image: placeholderImage)
                return
            }
            
            // Data -> UIImage
            guard let d = data, let image = UIImage(data: d) else {
                print("ImageDown Response Data Error")
                _setImage(image: placeholderImage)
                return
            }
            _setImage(image: image)
            
            // Caching
            ImageCacheManager.shared.setImage(urlStr, image: image)
        }
        task.resume()
    }
}

 

 

 

간단한 이미지 캐시 구현


[Image URL String : UIImage] 로 캐싱

NSCashe 사용

class ImageCacheManager {
    static let shared = ImageCacheManager()
    private init() {}
    
    // [Image Url String: UIImage] 캐싱
    private let cache = NSCache<NSString, UIImage>()
    
    func setImage(_ urlStr: String, image: UIImage) {
        cache.setObject(image, forKey: urlStr as NSString)
    }
    
    func getImage(_ urlStr: String) -> UIImage? {
        cache.object(forKey: urlStr as NSString)
    }
}

일반적인 NSMutableDictionary가 아닌 NSCache를 사용하는 이유

 

  • 리소스 부족시 자동으로 해제해주는 기능
  • thread safe (다른 스레드를 잠그지않고 조작할 수 있음)
  • NSMutableDictionary는 value값을 잃을 경우 leak에 대한 우려가 있기 때문에, key에 사용되는 값은 모두 copy되어 사용되는데, NSCache는 메모리가 부족할시 알아서 해제해주기 때문에, 굳이 copy하지 않음.

 

 

NSDictionary 애플문서 링크

 

Comments