Skip to content

Instantly share code, notes, and snippets.

@tobitech
Created May 27, 2020 12:05
Show Gist options
  • Save tobitech/52e530fb26a9526c35c26f434cbee970 to your computer and use it in GitHub Desktop.
Save tobitech/52e530fb26a9526c35c26f434cbee970 to your computer and use it in GitHub Desktop.
Reactive ImageDownloader with Alamofire + Cache
//
// ImageDownloader.swift
// ImageDownloader
//
// Created by Oluwatobi Omotayo on 27/05/2020.
// Copyright © 2020 Oluwatobi Omotayo. All rights reserved.
//
import UIKit
import RxSwift
import Alamofire
class ImageCache {
var cacheDictionary = Dictionary<String, UIImage>()
func saveImageToCache(image: UIImage?, url: URL) {
if let image = image {
cacheDictionary[url.absoluteString] = image
}
}
func imageFromCacheWith(url: URL) -> UIImage? {
return cacheDictionary[url.absoluteString]
}
}
class ImageDownloader {
enum Errors: Error {
case noImageData
}
static let shared = ImageDownloader()
let cache: ImageCache
private init(cache: ImageCache = ImageCache()) {
self.cache = cache
}
func downloadImage(from url: URL) -> Observable<UIImage> {
return Observable.create {[unowned self] observer -> Disposable in
if let image = self.cache.imageFromCacheWith(url: url) {
observer.onNext(image)
observer.onCompleted()
} else {
AF.download(url).responseData { response in
let result = response.result
switch result {
case .success(let data):
if let image = UIImage(data: data) {
self.cache.saveImageToCache(image: image, url: url)
observer.onNext(image)
observer.onCompleted()
} else {
observer.onError(Errors.noImageData)
}
case .failure(let error):
observer.onError(error)
}
}
}
return Disposables.create()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment