Vasilis
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
7 objects = { 7 objects = {
8 8
9 /* Begin PBXBuildFile section */ 9 /* Begin PBXBuildFile section */
10 + 1E7086652811A93F00704CA8 /* CouponBarcodeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E7086642811A93F00704CA8 /* CouponBarcodeView.swift */; };
11 + 1E7086672811A96E00704CA8 /* CouponBarcodeViewInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E7086662811A96E00704CA8 /* CouponBarcodeViewInterface.swift */; };
10 1E735FF2281067320050A298 /* CampaignWebview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E735FF1281067320050A298 /* CampaignWebview.swift */; }; 12 1E735FF2281067320050A298 /* CampaignWebview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E735FF1281067320050A298 /* CampaignWebview.swift */; };
11 1E735FF42810681E0050A298 /* CampaignWebviewInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E735FF32810681E0050A298 /* CampaignWebviewInterface.swift */; }; 13 1E735FF42810681E0050A298 /* CampaignWebviewInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E735FF32810681E0050A298 /* CampaignWebviewInterface.swift */; };
12 1EBEB02D280D69D800BF802C /* GiftsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EBEB02C280D69D800BF802C /* GiftsView.swift */; }; 14 1EBEB02D280D69D800BF802C /* GiftsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EBEB02C280D69D800BF802C /* GiftsView.swift */; };
...@@ -141,6 +143,8 @@ ...@@ -141,6 +143,8 @@
141 143
142 /* Begin PBXFileReference section */ 144 /* Begin PBXFileReference section */
143 1353B8C484CC0649CAC2EB74 /* Pods_WarplySDKFrameworkIOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_WarplySDKFrameworkIOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 145 1353B8C484CC0649CAC2EB74 /* Pods_WarplySDKFrameworkIOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_WarplySDKFrameworkIOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
146 + 1E7086642811A93F00704CA8 /* CouponBarcodeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CouponBarcodeView.swift; sourceTree = "<group>"; };
147 + 1E7086662811A96E00704CA8 /* CouponBarcodeViewInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CouponBarcodeViewInterface.swift; sourceTree = "<group>"; };
144 1E735FF1281067320050A298 /* CampaignWebview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CampaignWebview.swift; sourceTree = "<group>"; }; 148 1E735FF1281067320050A298 /* CampaignWebview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CampaignWebview.swift; sourceTree = "<group>"; };
145 1E735FF32810681E0050A298 /* CampaignWebviewInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CampaignWebviewInterface.swift; sourceTree = "<group>"; }; 149 1E735FF32810681E0050A298 /* CampaignWebviewInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CampaignWebviewInterface.swift; sourceTree = "<group>"; };
146 1EBEB02C280D69D800BF802C /* GiftsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GiftsView.swift; sourceTree = "<group>"; }; 150 1EBEB02C280D69D800BF802C /* GiftsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GiftsView.swift; sourceTree = "<group>"; };
...@@ -345,6 +349,8 @@ ...@@ -345,6 +349,8 @@
345 E67D1EB9281055F800940F01 /* MoreForYouViewInterface.swift */, 349 E67D1EB9281055F800940F01 /* MoreForYouViewInterface.swift */,
346 E67D1EBF2810579F00940F01 /* MoreForYouView.swift */, 350 E67D1EBF2810579F00940F01 /* MoreForYouView.swift */,
347 E67D1EC128113EED00940F01 /* CouponView.swift */, 351 E67D1EC128113EED00940F01 /* CouponView.swift */,
352 + 1E7086642811A93F00704CA8 /* CouponBarcodeView.swift */,
353 + 1E7086662811A96E00704CA8 /* CouponBarcodeViewInterface.swift */,
348 E67D1EC328113EFD00940F01 /* CouponViewInterface.swift */, 354 E67D1EC328113EFD00940F01 /* CouponViewInterface.swift */,
349 E6D8DF5E27A9429E0006A3A9 /* MyApi.h */, 355 E6D8DF5E27A9429E0006A3A9 /* MyApi.h */,
350 E6D8DF5C27A9429E0006A3A9 /* MyApi.m */, 356 E6D8DF5C27A9429E0006A3A9 /* MyApi.m */,
...@@ -746,6 +752,7 @@ ...@@ -746,6 +752,7 @@
746 E6D8DF2E27A942920006A3A9 /* UIRefreshControl+AFNetworking.m in Sources */, 752 E6D8DF2E27A942920006A3A9 /* UIRefreshControl+AFNetworking.m in Sources */,
747 E6D8DF4827A942920006A3A9 /* AFURLRequestSerialization.m in Sources */, 753 E6D8DF4827A942920006A3A9 /* AFURLRequestSerialization.m in Sources */,
748 E67D1EC228113EED00940F01 /* CouponView.swift in Sources */, 754 E67D1EC228113EED00940F01 /* CouponView.swift in Sources */,
755 + 1E7086672811A96E00704CA8 /* CouponBarcodeViewInterface.swift in Sources */,
749 E6D8DEF327A942920006A3A9 /* WLNativeVideoTableViewCell.m in Sources */, 756 E6D8DEF327A942920006A3A9 /* WLNativeVideoTableViewCell.m in Sources */,
750 E6D8DF2527A942920006A3A9 /* WLSMSActionHanlder.m in Sources */, 757 E6D8DF2527A942920006A3A9 /* WLSMSActionHanlder.m in Sources */,
751 E67D1EBE2810573900940F01 /* WalletView.swift in Sources */, 758 E67D1EBE2810573900940F01 /* WalletView.swift in Sources */,
...@@ -790,6 +797,7 @@ ...@@ -790,6 +797,7 @@
790 E67D1EC828119ED300940F01 /* swiftApi.swift in Sources */, 797 E67D1EC828119ED300940F01 /* swiftApi.swift in Sources */,
791 E6D8DF5227A942920006A3A9 /* FMDatabase.m in Sources */, 798 E6D8DF5227A942920006A3A9 /* FMDatabase.m in Sources */,
792 E6D8DF1227A942920006A3A9 /* WLPushManager.m in Sources */, 799 E6D8DF1227A942920006A3A9 /* WLPushManager.m in Sources */,
800 + 1E7086652811A93F00704CA8 /* CouponBarcodeView.swift in Sources */,
793 E6D8DEF827A942920006A3A9 /* WLNativeAdTableViewCell.m in Sources */, 801 E6D8DEF827A942920006A3A9 /* WLNativeAdTableViewCell.m in Sources */,
794 E6D8DE6D27A942010006A3A9 /* WarplySDKFrameworkIOS.docc in Sources */, 802 E6D8DE6D27A942010006A3A9 /* WarplySDKFrameworkIOS.docc in Sources */,
795 E6D8DF4427A942920006A3A9 /* AFURLResponseSerialization.m in Sources */, 803 E6D8DF4427A942920006A3A9 /* AFURLResponseSerialization.m in Sources */,
......
1 +//
2 +// CouponBarcodeViewInterface.swift
3 +// WarplySDKFrameworkIOS
4 +//
5 +// Created by Manos Chorianopoulos on 21/4/22.
6 +//
7 +
8 +import Foundation
9 +import SwiftUI
10 +
11 +@available(iOS 13.0.0, *)
12 +@objc public class CouponBarcodeViewInterface : NSObject {
13 +
14 + @objc(couponBarcodeViewController::) static public func couponBarcodeViewController(parentView: UIView?, coupon: Dictionary<String, Any>) -> UIViewController {
15 + return UIHostingController(rootView: CouponBarcodeView(parentView: parentView!, coupon: coupon))
16 + }
17 +
18 +}
19 +
...@@ -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 } 201 + }
194 - DispatchQueue.main.async { 202 +
195 - self.data = data 203 + guard let cacheImage = imageCache.get(forKey: urlString) else {
196 - } 204 + return false
197 } 205 }
206 +
207 + image = cacheImage
208 + return true
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
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
19 - (void) setLang:(NSString*) lang; 19 - (void) setLang:(NSString*) lang;
20 - (UIViewController *) openCoupons:(UIView*) parentView; 20 - (UIViewController *) openCoupons:(UIView*) parentView;
21 - (UIViewController *) openCoupon:(UIView*) parentView coupon:(NSDictionary*) coupon; 21 - (UIViewController *) openCoupon:(UIView*) parentView coupon:(NSDictionary*) coupon;
22 +- (UIViewController *) openCouponBarcode:(UIView*) parentView coupon:(NSDictionary*) coupon;
22 - (UIViewController *) openGifts:(UIView*) parentView; 23 - (UIViewController *) openGifts:(UIView*) parentView;
23 - (UIViewController *) openWallet:(UIView*) parentView; 24 - (UIViewController *) openWallet:(UIView*) parentView;
24 - (UIViewController *) openMoreForYou:(UIView*) parentView; 25 - (UIViewController *) openMoreForYou:(UIView*) parentView;
......
...@@ -59,6 +59,12 @@ NSString *LANG; ...@@ -59,6 +59,12 @@ NSString *LANG;
59 return couponViewController; 59 return couponViewController;
60 } 60 }
61 61
62 +- (UIViewController *) openCouponBarcode:(UIView*) parentView coupon:(NSDictionary*) coupon {
63 +
64 + UIViewController *couponBarcodeViewController = [CouponBarcodeViewInterface couponBarcodeViewController:parentView :coupon];
65 + return couponBarcodeViewController;
66 +}
67 +
62 - (UIViewController *) openGifts:(UIView*) parentView{ 68 - (UIViewController *) openGifts:(UIView*) parentView{
63 69
64 UIViewController *giftsViewController = [GiftsViewInterface giftsViewController:parentView]; 70 UIViewController *giftsViewController = [GiftsViewInterface giftsViewController:parentView];
......