Manos Chorianopoulos

add cache to UrlImages

...@@ -130,24 +130,20 @@ extension CouponView { ...@@ -130,24 +130,20 @@ extension CouponView {
130 } 130 }
131 131
132 struct ImageView: View { 132 struct ImageView: View {
133 - @ObservedObject var imageLoader:ImageLoaderGifts 133 + @ObservedObject var imageLoader:UrlImageModel
134 - @State var image:UIImage = UIImage()
135 134
136 var uiscreen = UIScreen.main.bounds 135 var uiscreen = UIScreen.main.bounds
137 136
138 init(withURL url:String) { 137 init(withURL url:String) {
139 - imageLoader = ImageLoaderGifts(urlString:url) 138 + imageLoader = UrlImageModel(urlString:url)
140 } 139 }
141 140
142 var body: some View { 141 var body: some View {
143 142
144 - Image(uiImage: image) 143 + Image(uiImage: imageLoader.image ?? UIImage())
145 .resizable() 144 .resizable()
146 .aspectRatio(contentMode: .fill) 145 .aspectRatio(contentMode: .fill)
147 .frame(width: self.uiscreen.width, height: self.uiscreen.height * 0.25) 146 .frame(width: self.uiscreen.width, height: self.uiscreen.height * 0.25)
148 - .onReceive(imageLoader.didChange) { data in
149 - self.image = UIImage(data: data) ?? UIImage()
150 - }
151 } 147 }
152 } 148 }
153 149
......
...@@ -179,24 +179,88 @@ struct RoundedCorner: Shape { ...@@ -179,24 +179,88 @@ struct RoundedCorner: Shape {
179 } 179 }
180 } 180 }
181 181
182 -class ImageLoaderGifts: ObservableObject { 182 +class UrlImageModel: ObservableObject {
183 - var didChange = PassthroughSubject<Data, Never>() 183 + @Published var image: UIImage?
184 - var data = Data() { 184 + var urlString: String?
185 - didSet { 185 + var imageCache = ImageCache.getImageCache()
186 - didChange.send(data) 186 +
187 +
188 + func loadImage() {
189 + if loadImageFromCache() {
190 + print("Cache hit")
191 + return
187 } 192 }
193 +
194 + print("Cache miss, loading from url")
195 + loadImageFromUrl()
188 } 196 }
189 197
190 - init(urlString:String) { 198 + func loadImageFromCache() -> Bool {
191 - guard let url = URL(string: urlString) else { return } 199 + guard let urlString = urlString else {
192 - let task = URLSession.shared.dataTask(with: url) { data, response, error in 200 + return false
193 - guard let data = data else { return }
194 - DispatchQueue.main.async {
195 - self.data = data
196 } 201 }
202 +
203 + guard let cacheImage = imageCache.get(forKey: urlString) else {
204 + return false
205 + }
206 +
207 + image = cacheImage
208 + return true
197 } 209 }
210 +
211 + func loadImageFromUrl() {
212 + guard let urlString = urlString else {
213 + return
214 + }
215 +
216 + let url = URL(string: urlString)!
217 + let task = URLSession.shared.dataTask(with: url, completionHandler: getImageFromResponse(data:response:error:))
198 task.resume() 218 task.resume()
199 } 219 }
220 +
221 + func getImageFromResponse(data: Data?, response: URLResponse?, error: Error?) {
222 + guard error == nil else {
223 + print("Error: \(error!)")
224 + return
225 + }
226 + guard let data = data else {
227 + print("No data found")
228 + return
229 + }
230 +
231 + DispatchQueue.main.async {
232 + guard let loadedImage = UIImage(data: data) else {
233 + return
234 + }
235 +
236 + self.imageCache.set(forKey: self.urlString!, image: loadedImage)
237 + self.image = loadedImage
238 + }
239 + }
240 +
241 + init(urlString:String) {
242 + self.urlString = urlString
243 + loadImage()
244 + }
245 +}
246 +
247 +class ImageCache {
248 + var cache = NSCache<NSString, UIImage>()
249 +
250 + func get(forKey: String) -> UIImage? {
251 + return cache.object(forKey: NSString(string: forKey))
252 + }
253 +
254 + func set(forKey: String, image: UIImage) {
255 + cache.setObject(image, forKey: NSString(string: forKey))
256 + }
257 +}
258 +
259 +extension ImageCache {
260 + private static var imageCache = ImageCache()
261 + static func getImageCache() -> ImageCache {
262 + return imageCache
263 + }
200 } 264 }
201 265
202 266
...@@ -286,29 +350,25 @@ extension GiftsView { ...@@ -286,29 +350,25 @@ extension GiftsView {
286 } 350 }
287 351
288 struct ImageView: View { 352 struct ImageView: View {
289 - @ObservedObject var imageLoader:ImageLoaderGifts 353 + @ObservedObject var imageLoader:UrlImageModel
290 - @State var image:UIImage = UIImage()
291 @State var width:CGFloat 354 @State var width:CGFloat
292 @State var isFill:Bool 355 @State var isFill:Bool
293 356
294 var uiscreen = UIScreen.main.bounds 357 var uiscreen = UIScreen.main.bounds
295 358
296 init(withURL url:String , width:CGFloat, isFill:Bool) { 359 init(withURL url:String , width:CGFloat, isFill:Bool) {
297 - imageLoader = ImageLoaderGifts(urlString:url) 360 + imageLoader = UrlImageModel(urlString:url)
298 self.width = width 361 self.width = width
299 self.isFill = isFill 362 self.isFill = isFill
300 } 363 }
301 364
302 var body: some View { 365 var body: some View {
303 366
304 - Image(uiImage: image) 367 + Image(uiImage: imageLoader.image ?? UIImage())
305 .resizable() 368 .resizable()
306 .aspectRatio(contentMode: isFill ? .fill : .fit) 369 .aspectRatio(contentMode: isFill ? .fill : .fit)
307 .frame(width: self.width) 370 .frame(width: self.width)
308 .frame(maxHeight: .infinity) 371 .frame(maxHeight: .infinity)
309 - .onReceive(imageLoader.didChange) { data in
310 - self.image = UIImage(data: data) ?? UIImage()
311 - }
312 } 372 }
313 } 373 }
314 374
......