From f3a62cee632163e6296e944f45b8e2a603c01fb0 Mon Sep 17 00:00:00 2001 From: Bilal Date: Tue, 6 Aug 2024 21:17:00 +0530 Subject: [PATCH] - Added api for getting live stream and fm url - modified the data for live stream url in theme 1 and theme 2 with speicifed languages also with titles - modified FM url - worked on coredata crud. made functions for crud with queries - added default avatar images for guest - Finalised the Data Model and tried to save and update the counts in local --- WOKA.xcodeproj/project.pbxproj | 20 +- .../Home/DefaultAvatar.imageset/Contents.json | 21 ++ .../profile_placeholder.png | Bin 0 -> 51628 bytes WOKA/Main/AuthFunc/AuthFunc.swift | 24 +++ WOKA/Network Adapter/APIEndPoints.swift | 1 + .../Controller/SplashVC.swift | 5 + .../OnBoarding Module/Model/URLStaticDM.swift | 66 ++++++ .../ViewModel/SplashVM.swift | 13 +- WOKA/PersistentStorage.swift | 204 +++++++++++++++++- WOKA/Shop/Controller/ProductDetailsVC.swift | 3 +- WOKA/Shop/ViewModel/ProductDetailsVM.swift | 2 + WOKA/Shop/ViewModel/ShopCategoryVM.swift | 2 + WOKA/Shop/ViewModel/ShopListingVM.swift | 2 + WOKA/Shop/ViewModel/ShopProductsVM.swift | 2 + WOKA/SideBarNav/ViewModel/MyOrdersVM.swift | 2 + .../ViewModel/SideMenuVM.swift | 2 + WOKA/Theme/Controller/ThemeOneVC.swift | 11 +- WOKA/Theme/ViewModel/ThemeOneVM.swift | 133 +++++++----- WOKA/Theme/ViewModel/ThemeTwoVM.swift | 121 +++++++---- WOKA/WOKAFM/ViewModel/WokaFMVM.swift | 12 +- 20 files changed, 526 insertions(+), 120 deletions(-) create mode 100644 WOKA/Assets/Assets.xcassets/Home/DefaultAvatar.imageset/Contents.json create mode 100644 WOKA/Assets/Assets.xcassets/Home/DefaultAvatar.imageset/profile_placeholder.png create mode 100644 WOKA/OnBoarding Module/Model/URLStaticDM.swift diff --git a/WOKA.xcodeproj/project.pbxproj b/WOKA.xcodeproj/project.pbxproj index 0493355..6f7967d 100644 --- a/WOKA.xcodeproj/project.pbxproj +++ b/WOKA.xcodeproj/project.pbxproj @@ -141,7 +141,6 @@ 52A981D82C1B0E27000E0BEC /* FavouriteCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 52A981D62C1B0E27000E0BEC /* FavouriteCell.xib */; }; 52AC2D252C295A7900337473 /* TeaserDM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52AC2D242C295A7900337473 /* TeaserDM.swift */; }; 52AC2D272C29791500337473 /* JWPlayerManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52AC2D262C29791500337473 /* JWPlayerManager.swift */; }; - 52ACC1222C610C5900791528 /* WOKA.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 52ACC1202C610C5900791528 /* WOKA.xcdatamodeld */; }; 52ACC1252C610CBC00791528 /* UserClicks+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52ACC1232C610CBC00791528 /* UserClicks+CoreDataClass.swift */; }; 52ACC1262C610CBC00791528 /* UserClicks+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52ACC1242C610CBC00791528 /* UserClicks+CoreDataProperties.swift */; }; 52ACC12A2C610EC900791528 /* PersistentStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52ACC1292C610EC900791528 /* PersistentStorage.swift */; }; @@ -244,6 +243,8 @@ 9C21F81C2C37E1FA0050BFCC /* KaraokeContinueWatchingDM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C21F81B2C37E1FA0050BFCC /* KaraokeContinueWatchingDM.swift */; }; 9C21F81E2C37E3CA0050BFCC /* AVPlayerVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C21F81D2C37E3CA0050BFCC /* AVPlayerVC.swift */; }; 9C21F8222C382A580050BFCC /* AVPlayerVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C21F8212C382A580050BFCC /* AVPlayerVM.swift */; }; + 9C23FB772C62085C00F4DC5C /* WOKA.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 9C23FB752C62085C00F4DC5C /* WOKA.xcdatamodeld */; }; + 9C23FB792C62164600F4DC5C /* URLStaticDM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C23FB782C62164600F4DC5C /* URLStaticDM.swift */; }; 9C27E1602BDB6ECA00EC1DA9 /* UserDefaultsStruct.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C27E15F2BDB6ECA00EC1DA9 /* UserDefaultsStruct.swift */; }; 9C27E1632BDB6F1900EC1DA9 /* AuthFunc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C27E1622BDB6F1900EC1DA9 /* AuthFunc.swift */; }; 9C27E1652BDB6FBC00EC1DA9 /* StoryBoardID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C27E1642BDB6FBC00EC1DA9 /* StoryBoardID.swift */; }; @@ -493,7 +494,6 @@ 52A981D62C1B0E27000E0BEC /* FavouriteCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FavouriteCell.xib; sourceTree = ""; }; 52AC2D242C295A7900337473 /* TeaserDM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TeaserDM.swift; sourceTree = ""; }; 52AC2D262C29791500337473 /* JWPlayerManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JWPlayerManager.swift; sourceTree = ""; }; - 52ACC1212C610C5900791528 /* WOKA.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = WOKA.xcdatamodel; sourceTree = ""; }; 52ACC1232C610CBC00791528 /* UserClicks+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserClicks+CoreDataClass.swift"; sourceTree = SOURCE_ROOT; }; 52ACC1242C610CBC00791528 /* UserClicks+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserClicks+CoreDataProperties.swift"; sourceTree = SOURCE_ROOT; }; 52ACC1292C610EC900791528 /* PersistentStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersistentStorage.swift; sourceTree = ""; }; @@ -600,6 +600,8 @@ 9C21F81B2C37E1FA0050BFCC /* KaraokeContinueWatchingDM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KaraokeContinueWatchingDM.swift; sourceTree = ""; }; 9C21F81D2C37E3CA0050BFCC /* AVPlayerVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVPlayerVC.swift; sourceTree = ""; }; 9C21F8212C382A580050BFCC /* AVPlayerVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVPlayerVM.swift; sourceTree = ""; }; + 9C23FB762C62085C00F4DC5C /* WOKA.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = WOKA.xcdatamodel; sourceTree = ""; }; + 9C23FB782C62164600F4DC5C /* URLStaticDM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLStaticDM.swift; sourceTree = ""; }; 9C27E15F2BDB6ECA00EC1DA9 /* UserDefaultsStruct.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsStruct.swift; sourceTree = ""; }; 9C27E1622BDB6F1900EC1DA9 /* AuthFunc.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthFunc.swift; sourceTree = ""; }; 9C27E1642BDB6FBC00EC1DA9 /* StoryBoardID.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoryBoardID.swift; sourceTree = ""; }; @@ -855,7 +857,7 @@ 9C535DC82C00C34000DA6DCD /* Theme */, 52DAC6462C21761700E2F85B /* WebSeries */, 9C834ED92C1C20EC00B29A9C /* WOKA.entitlements */, - 52ACC1202C610C5900791528 /* WOKA.xcdatamodeld */, + 9C23FB752C62085C00F4DC5C /* WOKA.xcdatamodeld */, 52ACC1292C610EC900791528 /* PersistentStorage.swift */, ); path = WOKA; @@ -895,6 +897,7 @@ children = ( 9C27E16A2BDB774D00EC1DA9 /* CarouselData.swift */, 529B0DD52C070C0F00CFC54B /* GuestDataDM.swift */, + 9C23FB782C62164600F4DC5C /* URLStaticDM.swift */, ); path = Model; sourceTree = ""; @@ -2189,6 +2192,7 @@ 52D2F3D82C24043D009E52FF /* ShimmerEffectView.swift in Sources */, 9C27E16F2BDB866500EC1DA9 /* CellIdentifier.swift in Sources */, 52BC3BF22C170264002FACA6 /* MoreVM.swift in Sources */, + 9C23FB772C62085C00F4DC5C /* WOKA.xcdatamodeld in Sources */, 9CB3D08F2C37D0D60062869D /* KaraokeListingDM.swift in Sources */, 52ACC12A2C610EC900791528 /* PersistentStorage.swift in Sources */, 9CBE1B412C0F37B300CA6E61 /* DPDUIView+Extension.swift in Sources */, @@ -2323,9 +2327,9 @@ 9C27E1722BDB86B600EC1DA9 /* OnBoardCell.swift in Sources */, 525861D82C4FD38D00C33C79 /* CartPaymentOptionsCell.swift in Sources */, 529B0DD42C06156B00CFC54B /* LoginNavVC.swift in Sources */, + 9C23FB792C62164600F4DC5C /* URLStaticDM.swift in Sources */, 52A981D72C1B0E27000E0BEC /* FavouriteCell.swift in Sources */, 52BFB0652C5B5B4F0038D750 /* BlogsVC.swift in Sources */, - 52ACC1222C610C5900791528 /* WOKA.xcdatamodeld in Sources */, 52C8B05F2BDA5AFA003B51D0 /* SplashVM.swift in Sources */, 52C1A4E12C05B69F007BAA50 /* UIApplicationSwitchRoot.swift in Sources */, 527A2BCC2C577F8A0080DF9B /* AnalyticsEventKeys.swift in Sources */, @@ -2827,14 +2831,14 @@ /* End XCSwiftPackageProductDependency section */ /* Begin XCVersionGroup section */ - 52ACC1202C610C5900791528 /* WOKA.xcdatamodeld */ = { + 9C23FB752C62085C00F4DC5C /* WOKA.xcdatamodeld */ = { isa = XCVersionGroup; children = ( - 52ACC1212C610C5900791528 /* WOKA.xcdatamodel */, + 9C23FB762C62085C00F4DC5C /* WOKA.xcdatamodel */, ); - currentVersion = 52ACC1212C610C5900791528 /* WOKA.xcdatamodel */; + currentVersion = 9C23FB762C62085C00F4DC5C /* WOKA.xcdatamodel */; name = WOKA.xcdatamodeld; - path = /Users/macbookpro/Desktop/WOKA/WOKA/WOKA.xcdatamodeld; + path = /Users/bilal/Desktop/woka_native_ios_swift/WOKA/WOKA.xcdatamodeld; sourceTree = ""; versionGroupType = wrapper.xcdatamodel; }; diff --git a/WOKA/Assets/Assets.xcassets/Home/DefaultAvatar.imageset/Contents.json b/WOKA/Assets/Assets.xcassets/Home/DefaultAvatar.imageset/Contents.json new file mode 100644 index 0000000..0030dc6 --- /dev/null +++ b/WOKA/Assets/Assets.xcassets/Home/DefaultAvatar.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "profile_placeholder.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/WOKA/Assets/Assets.xcassets/Home/DefaultAvatar.imageset/profile_placeholder.png b/WOKA/Assets/Assets.xcassets/Home/DefaultAvatar.imageset/profile_placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..4d1ae9d3e8c9498318386ccc7f677199e1e2e304 GIT binary patch literal 51628 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, NetworkManager.APIError>) in + switch result{ + case .success(let data): + guard let self else{return} + switch data.success{ + case 0: + break + case 1: + guard let data = data.data else{return} + AuthFunc.shareInstance.staticURLs = data + default: + break + } + case .failure(let error): + break + } + } + } + } // MARK: - Language Enum diff --git a/WOKA/Network Adapter/APIEndPoints.swift b/WOKA/Network Adapter/APIEndPoints.swift index 8ddd7e5..63ca727 100644 --- a/WOKA/Network Adapter/APIEndPoints.swift +++ b/WOKA/Network Adapter/APIEndPoints.swift @@ -28,6 +28,7 @@ struct APIEndPoints { struct StaticURLs{ // var masilaUrl = "https://content.jwplatform.com/videos/Iygt11AD-Ysj2G4DQ.mp4" static let masilaUrl = "https://cdn.jwplayer.com/manifests/Iygt11AD.m3u8" + static let live_streaming = makeURL(path: "live_streaming") } struct Auth { diff --git a/WOKA/OnBoarding Module/Controller/SplashVC.swift b/WOKA/OnBoarding Module/Controller/SplashVC.swift index a3d97cc..b02e96d 100644 --- a/WOKA/OnBoarding Module/Controller/SplashVC.swift +++ b/WOKA/OnBoarding Module/Controller/SplashVC.swift @@ -78,6 +78,11 @@ class SplashVC: UIViewController { if AuthFunc.shareInstance.checkLogin(){ vm.getUserData() return + } else{ + //check if the static url data is fetched + if AuthFunc.shareInstance.staticURLs == nil{ + AuthFunc.shareInstance.getStaticURLs() + } } UIView.animate(withDuration: 0.5, animations: { // Update the constant value of the top constraint diff --git a/WOKA/OnBoarding Module/Model/URLStaticDM.swift b/WOKA/OnBoarding Module/Model/URLStaticDM.swift new file mode 100644 index 0000000..c4935b6 --- /dev/null +++ b/WOKA/OnBoarding Module/Model/URLStaticDM.swift @@ -0,0 +1,66 @@ +// +// URLStaticDM.swift +// WOKA +// +// Created by Bilal on 06/08/2024. +// + +import Foundation + +// MARK: - URLStaticDM +struct URLStaticDM: Codable { + let liveFmData: LiveFmData? + let liveData: [LiveDatum]? + + enum CodingKeys: String, CodingKey { + case liveFmData = "live_fm_data" + case liveData = "live_data" + } + + // MARK: - LiveDatum + struct LiveDatum: Codable { + let id: Int? + let name: Name? + let liveURL: LiveURL? + + enum CodingKeys: String, CodingKey { + case id, name + case liveURL = "live_url" + } + } + + // MARK: - LiveURL + struct LiveURL: Codable { + let hdURLEn, hdURLHin, sdURLEn, sdURLHin: String? + + enum CodingKeys: String, CodingKey { + case hdURLEn = "hd_url_en" + case hdURLHin = "hd_url_hin" + case sdURLEn = "sd_url_en" + case sdURLHin = "sd_url_hin" + } + } + + // MARK: - Name + struct Name: Codable { + let titleEn, titleHin: String? + + enum CodingKeys: String, CodingKey { + case titleEn = "title_en" + case titleHin = "title_hin" + } + } + + // MARK: - LiveFmData + struct LiveFmData: Codable { + let id: Int? + let title: String? + let liveFmURL: String? + + enum CodingKeys: String, CodingKey { + case id, title + case liveFmURL = "live_fm_url" + } + } + +} diff --git a/WOKA/OnBoarding Module/ViewModel/SplashVM.swift b/WOKA/OnBoarding Module/ViewModel/SplashVM.swift index 2d33e47..05bc60a 100644 --- a/WOKA/OnBoarding Module/ViewModel/SplashVM.swift +++ b/WOKA/OnBoarding Module/ViewModel/SplashVM.swift @@ -18,7 +18,7 @@ class SplashVM{ func initView(){ // Analytics.logEvent(K.AnalyticsEventKeys.guest_login_iOS, parameters: nil) - + AuthFunc.shareInstance.getStaticURLs() vc.activityIndicator.hidesWhenStopped = true let color1 = #colorLiteral(red: 0.144693464, green: 0.1426281333, blue: 0.6686832905, alpha: 1) let color2 = #colorLiteral(red: 0.4862745098, green: 0.1960784314, blue: 0.7019607843, alpha: 1) @@ -33,9 +33,7 @@ class SplashVM{ AuthFunc.shareInstance.languageSelected = language }else{ AuthFunc.shareInstance.setDefaultLanguage(language: .english) - } - - + } } @@ -95,6 +93,12 @@ class SplashVM{ startStopIndicator(start: false,hide: true) guard let data = data.data?.result else{return} AuthFunc.shareInstance.userData = data + + //check if the static url data is fetched + if AuthFunc.shareInstance.staticURLs == nil{ + AuthFunc.shareInstance.getStaticURLs() + } + UIApplication.setRootView(SideMenuController.instantiate(from: .Home)) print("User Token --> ", AuthFunc.shareInstance.getAccessToken()) default: @@ -108,6 +112,7 @@ class SplashVM{ } } + // handling activity indicator func startStopIndicator(start : Bool , hide : Bool = false){ if hide{ diff --git a/WOKA/PersistentStorage.swift b/WOKA/PersistentStorage.swift index 597baa5..3b847ce 100644 --- a/WOKA/PersistentStorage.swift +++ b/WOKA/PersistentStorage.swift @@ -13,6 +13,41 @@ import CoreData Do share this with your iOS group on whatsapp or facebook or anyone who wants to learn iOS*/ +enum PersistentStorageEnum : String{ + case UserClicks + + case click_counts + case category_id + case post_id + case post_type +} + +enum PostType: String { + case series = "1" + case season = "2" + case episode = "3" + case video = "4" +// case paint = "5" + case game = "6" + case audio = "7" + case karaokeVideo = "8" + case shopProduct = "9" +// case parentalVideo = "10" +// case article = "11" + case liveTV = "12" + case FM = "13" + case teaser = "14" + case others = "15" + case home = "16" +} + +struct UserClickData { + let clickCounts: Int + let categoryId: Int + let postId: Int + let postType: Int +} + final class PersistentStorage { @@ -47,27 +82,174 @@ final class PersistentStorage } } - func saveClicksCount(){ - let clicks = UserClicks(context: PersistentStorage.shared.context) - clicks.post_type = 1 - clicks.post_id = 22 - clicks.category_id = 33 - clicks.click_counts = 100 - PersistentStorage.shared.saveContext() + func createData(data : UserClickData){ + + //We need to create a context from this container + let managedContext = PersistentStorage.shared.context + + let share = UserClicks(context: managedContext) + share.click_counts = Int64(data.clickCounts) + share.category_id = Int64(data.categoryId) + share.post_id = Int64(data.postId) + share.post_type = Int64(data.postType) + + do { + try managedContext.save() + retrieveData() + } catch let error as NSError { + print("Could not save. \(error), \(error.userInfo)") + } } - func getchClicksCount(){ + func checkIfExist( key : PersistentStorageEnum , clicksData : UserClickData) { + + let managedContext = PersistentStorage.shared.context + let fetchRequest = NSFetchRequest(entityName: PersistentStorageEnum.UserClicks.rawValue) +// fetchRequest.fetchLimit = 1 +// fetchRequest.predicate = NSPredicate(format: "id == %d" ,id) + fetchRequest.predicate = NSPredicate(format: "\(key.rawValue) == %@" ,clicksData.postType.toString()) + + do { + guard let result = try managedContext.fetch(fetchRequest) as? [UserClicks] else {return} + if result.isEmpty{ + //create + PersistentStorage.shared.createData(data: clicksData) + print("create") + }else{ + //update + let objectUpdate = result[0] as NSManagedObject + print("Update") + objectUpdate.setValue(result.first!.click_counts + Int64(clicksData.clickCounts), forKey: "click_counts") + do{ + try managedContext.save() + self.retrieveData() + } + catch + { + print(error) + } + } + result.forEach { clicks in + print("Counts" , clicks.click_counts) + } + }catch let error as NSError { + print("Could not fetch. \(error), \(error.userInfo)") + } + } + + func retrieveData() { + + //We need to create a context from this container + let managedContext = PersistentStorage.shared.context + let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) - debugPrint(path[0]) +// debugPrint(path[0]) + + let fetchRequests = NSFetchRequest(entityName: "UserClicks") + +// fetchRequests.fetchLimit = 1 +// fetchRequests.predicate = NSPredicate(format: "uuid = %@", "2") +// fetchRequests.sortDescriptors = [NSSortDescriptor.init(key: "uuid", ascending: false)] do { - guard let result = try PersistentStorage.shared.context.fetch(UserClicks.fetchRequest()) as? [UserClicks] else {return} - result.forEach({debugPrint("sad", $0.click_counts)}) + guard let result = try managedContext.fetch(fetchRequests) as? [UserClicks] else {return} + result.forEach { clicks in + print("ID:-" , clicks.post_type, "Count:-", clicks.click_counts) + } } catch let error { debugPrint(error) } } + + func updateData(){ + //We need to create a context from this container + let managedContext = PersistentStorage.shared.context + + + let fetchRequest:NSFetchRequest = NSFetchRequest.init(entityName: "UserClicks") + fetchRequest.predicate = NSPredicate(format: "uuid = %@", "2") + do + { + let test = try managedContext.fetch(fetchRequest) + + let objectUpdate = test[0] as! NSManagedObject + objectUpdate.setValue("Bilal Ahmed Khan New Name", forKey: "name") + do{ + try managedContext.save() + self.retrieveData() + } + catch + { + print(error) + } + } + catch + { + print(error) + } + + } + + func deleteData(){ + //We need to create a context from this container + let managedContext = PersistentStorage.shared.context + + let fetchRequest = NSFetchRequest(entityName: "UserClicks") +// fetchRequest.fetchLimit = 1 +// fetchRequest.predicate = NSPredicate(format: "uuid = %@ AND uuid = %@", "1", "1") + fetchRequest.predicate = NSPredicate(format: "post_id = %@", "11") + + do + { + let test = try managedContext.fetch(fetchRequest) + + let objectToDelete = test[0] as! NSManagedObject +// test.forEach { obbject in +// managedContext.delete(obbject as! NSManagedObject) +// } + managedContext.delete(test.first as! NSManagedObject) +// managedContext.delete(objectToDelete) + + do{ + try managedContext.save() +// self.createData() + self.retrieveData() + } + catch + { + print(error) + } + + } + catch + { + print(error) + } + } + +// func saveClicksCount(){ +// let clicks = UserClicks(context: PersistentStorage.shared.context) +// clicks.post_type = 1 +// clicks.post_id = 22 +// clicks.category_id = 33 +// clicks.click_counts = 100 +// PersistentStorage.shared.saveContext() +// } +// +// func getchClicksCount(){ +// let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) +// debugPrint(path[0]) +// +// do { +// guard let result = try PersistentStorage.shared.context.fetch(UserClicks.fetchRequest()) as? [UserClicks] else {return} +// result.forEach({debugPrint("sad", $0.click_counts)}) +// +// } catch let error +// { +// debugPrint(error) +// } +// } } diff --git a/WOKA/Shop/Controller/ProductDetailsVC.swift b/WOKA/Shop/Controller/ProductDetailsVC.swift index dad2d70..089e292 100644 --- a/WOKA/Shop/Controller/ProductDetailsVC.swift +++ b/WOKA/Shop/Controller/ProductDetailsVC.swift @@ -63,6 +63,8 @@ class ProductDetailsVC: UIViewController { } @IBAction func addToCartBtnTapped(_ sender: LocalisedElementsButton) { + if AuthFunc.shareInstance.guestUserLoginPopUp() { return} + if sender.titleLabel?.text == "Add to Cart"{ if let shopMasterID = vm.productDetails?.id{ vm.addToCart(shopMasterID: shopMasterID) @@ -72,7 +74,6 @@ class ProductDetailsVC: UIViewController { vm.removeItemFromCart(shopMasterID: shopMasterID) } } - } @IBAction func retryBtnTapped(_ sender: UIButton) { diff --git a/WOKA/Shop/ViewModel/ProductDetailsVM.swift b/WOKA/Shop/ViewModel/ProductDetailsVM.swift index e737b39..638edfa 100644 --- a/WOKA/Shop/ViewModel/ProductDetailsVM.swift +++ b/WOKA/Shop/ViewModel/ProductDetailsVM.swift @@ -29,6 +29,8 @@ class ProductDetailsVM{ } @objc func cartButtonTapped(){ + if AuthFunc.shareInstance.guestUserLoginPopUp() { return} + let sb = UIStoryboard(name: K.StoryBoard.cart, bundle: nil) let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Cart.cartListVC) as! CartListVC self.vc.navigationController?.pushViewController(vcPush, animated: true) diff --git a/WOKA/Shop/ViewModel/ShopCategoryVM.swift b/WOKA/Shop/ViewModel/ShopCategoryVM.swift index 39bf67e..4379b7e 100644 --- a/WOKA/Shop/ViewModel/ShopCategoryVM.swift +++ b/WOKA/Shop/ViewModel/ShopCategoryVM.swift @@ -26,6 +26,8 @@ class ShopCategoryVM{ } @objc func cartButtonTapped(){ + if AuthFunc.shareInstance.guestUserLoginPopUp() { return} + let sb = UIStoryboard(name: K.StoryBoard.cart, bundle: nil) let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Cart.cartListVC) as! CartListVC self.vc.navigationController?.pushViewController(vcPush, animated: true) diff --git a/WOKA/Shop/ViewModel/ShopListingVM.swift b/WOKA/Shop/ViewModel/ShopListingVM.swift index e0dec07..ddcc24a 100644 --- a/WOKA/Shop/ViewModel/ShopListingVM.swift +++ b/WOKA/Shop/ViewModel/ShopListingVM.swift @@ -36,6 +36,8 @@ class ShopListingVM{ } @objc func cartButtonTapped(){ + if AuthFunc.shareInstance.guestUserLoginPopUp() { return} + let sb = UIStoryboard(name: K.StoryBoard.cart, bundle: nil) let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Cart.cartListVC) as! CartListVC self.vc.navigationController?.pushViewController(vcPush, animated: true) diff --git a/WOKA/Shop/ViewModel/ShopProductsVM.swift b/WOKA/Shop/ViewModel/ShopProductsVM.swift index 41ae96a..bc051f1 100644 --- a/WOKA/Shop/ViewModel/ShopProductsVM.swift +++ b/WOKA/Shop/ViewModel/ShopProductsVM.swift @@ -31,6 +31,8 @@ class ShopProductsVM{ } @objc func cartButtonTapped(){ + if AuthFunc.shareInstance.guestUserLoginPopUp() { return} + let sb = UIStoryboard(name: K.StoryBoard.cart, bundle: nil) let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Cart.cartListVC) as! CartListVC self.vc.navigationController?.pushViewController(vcPush, animated: true) diff --git a/WOKA/SideBarNav/ViewModel/MyOrdersVM.swift b/WOKA/SideBarNav/ViewModel/MyOrdersVM.swift index 72be388..5b19486 100644 --- a/WOKA/SideBarNav/ViewModel/MyOrdersVM.swift +++ b/WOKA/SideBarNav/ViewModel/MyOrdersVM.swift @@ -33,6 +33,8 @@ class MyOrdersVM{ } @objc func cartButtonTapped(){ + if AuthFunc.shareInstance.guestUserLoginPopUp() { return} + let sb = UIStoryboard(name: K.StoryBoard.cart, bundle: nil) let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Cart.cartListVC) as! CartListVC self.vc.navigationController?.pushViewController(vcPush, animated: true) diff --git a/WOKA/TabBar & SideMenu/ViewModel/SideMenuVM.swift b/WOKA/TabBar & SideMenu/ViewModel/SideMenuVM.swift index 74ce10f..746f80d 100644 --- a/WOKA/TabBar & SideMenu/ViewModel/SideMenuVM.swift +++ b/WOKA/TabBar & SideMenu/ViewModel/SideMenuVM.swift @@ -102,6 +102,8 @@ class SideMenuVM{ if let avatar = data.avtarURL{ // vc.avatarImage.imageURL("https://wokaland.com/secret-panel-10102023/hidden-admin-portal-20092023/storage/app/public/uploads/avtar/avatar2.png?d=1716889852") vc.avatarImage.imageURL(avatar) + }else{ + vc.avatarImage.image = UIImage(named: "DefaultAvatar") } } diff --git a/WOKA/Theme/Controller/ThemeOneVC.swift b/WOKA/Theme/Controller/ThemeOneVC.swift index 54448aa..5744349 100644 --- a/WOKA/Theme/Controller/ThemeOneVC.swift +++ b/WOKA/Theme/Controller/ThemeOneVC.swift @@ -42,7 +42,6 @@ class ThemeOneVC: UIViewController { weak var delegate: ChildViewControllerDelegate? - deinit{ timer?.invalidate() // Removing observers @@ -71,6 +70,13 @@ class ThemeOneVC: UIViewController { MyListDataTemp.shareInstance.favListingData = FavouriteListingDM.ResultData(showData: [], videoData: [], gameData: [], singKaraokeData: [], audioData: []) } // connectedToNetwork() + +// PersistentStorage.shared.deleteData() +// PersistentStorage.shared.retrieveData() + let userClicks = UserClickData(clickCounts: 5, categoryId: 0, postId: 0, postType: 1) + PersistentStorage.shared.checkIfExist( key: .post_type,clicksData: userClicks) + + } override func viewWillAppear(_ animated: Bool) { @@ -135,6 +141,9 @@ class ThemeOneVC: UIViewController { vcPush.modalPresentationStyle = .overCurrentContext vcPush.modalTransitionStyle = .crossDissolve self.present(vcPush, animated: true) + + let userClicks = UserClickData(clickCounts: 5, categoryId: 0, postId: 0, postType: 1) + PersistentStorage.shared.checkIfExist( key: .post_type,clicksData: userClicks) } } diff --git a/WOKA/Theme/ViewModel/ThemeOneVM.swift b/WOKA/Theme/ViewModel/ThemeOneVM.swift index 3d81c03..d2b8b6e 100644 --- a/WOKA/Theme/ViewModel/ThemeOneVM.swift +++ b/WOKA/Theme/ViewModel/ThemeOneVM.swift @@ -15,7 +15,7 @@ class ThemeOneVM{ weak var vc : ThemeOneVC! var cloudMovingRight = false // Flag to track the direction of movement var isMovingRight = false // Flag to track the direction of movement - var liveStreamURL = "https://d3volyx7jx7oal.cloudfront.net/master.m3u8" +// var liveStreamURL = "https://d3volyx7jx7oal.cloudfront.net/master.m3u8" var avPlayer : AVPlayer! var playerItem: AVPlayerItem! @@ -113,7 +113,22 @@ class ThemeOneVM{ /* Av Player Setup */ - guard let streamURL = URL(string: liveStreamURL) else{return} + guard let data = AuthFunc.shareInstance.staticURLs , let liveStreamData = data.liveData?.first else{ + self.vc.toast(msg: "Issue with live streaming", time: 2) + return + } + var url = String() +// var title = String() + + if AuthFunc.shareInstance.languageSelected == .english{ + url = liveStreamData.liveURL?.hdURLEn ?? "" +// title = liveStreamData.name?.titleEn ?? "" + }else{ + url = liveStreamData.liveURL?.hdURLHin ?? "" +// title = liveStreamData.name?.titleHin ?? "" + } + + guard let streamURL = URL(string: url) else{return} playerItem = AVPlayerItem(url: streamURL) @@ -157,6 +172,8 @@ class ThemeOneVM{ if let avatar = data.avtarURL{ vc.avatarImage.imageURL(avatar) // vc.avatarImage.imageURL("https://wokaland.com/secret-panel-10102023/hidden-admin-portal-20092023/storage/app/public/uploads/avtar/avatar2.png?d=1716889852") + }else{ + vc.avatarImage.image = UIImage(named: "DefaultAvatar") } } @@ -346,57 +363,75 @@ class ThemeOneVM{ Utilities.startProgressHUD(msg: "Loading...") } print("tapped") - - let vc = self.vc.storyboard?.instantiateViewController(withIdentifier: "PlayerVC") as! PlayerVC - do { - // Ensure the liveStreamURL is valid - guard let liveStreamURL = URL(string: self.liveStreamURL) else { - print("Invalid live stream URL") - Utilities.dismissProgressHUD() - return - } - - let videoSourceBuilder = try JWVideoSourceBuilder() -// .defaultVideo(true) - .file(liveStreamURL) - .label("Live Stream") - .build() - - // Create a JWPlayerItem - let item = try JWPlayerItemBuilder() -// .file(liveStreamURL) - .videoSources([videoSourceBuilder]) - .build() - - // Create a JWPlayerConfiguration - let config = try JWPlayerConfigurationBuilder() - .playlist(items: [item]) - .preload(JWPreload(rawValue: 20) ?? .none) - .autostart(true) - .build() - - vc.config = config - vc.dismissTapped = self.tapped - vc.contentType = .liveStream - vc.modalPresentationStyle = .fullScreen - vc.modalTransitionStyle = .crossDissolve - - DispatchQueue.main.async { [weak self] in - guard let self else{return} - - // Present the PlayerVC - self.vc.present(vc, animated: false) { [weak self] in - guard let self else{return} - stopLiveStream() - } - } - } catch { - print("Error creating JWPlayer configuration: \(error)") + + let vc = self.vc.storyboard?.instantiateViewController(withIdentifier: K.StoryBoardID.Theme.playerVC) as! PlayerVC + + guard let data = AuthFunc.shareInstance.staticURLs , let liveStreamData = data.liveData?.first else{ + self.vc.toast(msg: "Issue with live streaming", time: 2) + return + } + + var url = String() + var title = String() + + if AuthFunc.shareInstance.languageSelected == .english{ + url = liveStreamData.liveURL?.hdURLEn ?? "" + title = liveStreamData.name?.titleEn ?? "" + }else{ + url = liveStreamData.liveURL?.hdURLHin ?? "" + title = liveStreamData.name?.titleHin ?? "" + } + + do { + // Ensure the liveStreamURL is valid + guard let liveStreamURL = URL(string: url) else { + print("Invalid live stream URL") Utilities.dismissProgressHUD() + return } - // Dismiss the progress HUD after the view controller presentation + let videoSourceBuilder = try JWVideoSourceBuilder() + // .defaultVideo(true) + .file(liveStreamURL) + .label(title) + .build() + + // Create a JWPlayerItem + let item = try JWPlayerItemBuilder() + // .file(liveStreamURL) + .videoSources([videoSourceBuilder]) + .title(title) + .build() + + // Create a JWPlayerConfiguration + let config = try JWPlayerConfigurationBuilder() + .playlist(items: [item]) + .preload(JWPreload(rawValue: 20) ?? .none) + .autostart(true) + .build() + + vc.config = config + vc.dismissTapped = self.tapped + vc.contentType = .liveStream + vc.modalPresentationStyle = .fullScreen + vc.modalTransitionStyle = .crossDissolve + + DispatchQueue.main.async { [weak self] in + guard let self else{return} + + // Present the PlayerVC + self.vc.present(vc, animated: false) { [weak self] in + guard let self else{return} + stopLiveStream() + } + } + } catch { + print("Error creating JWPlayer configuration: \(error)") Utilities.dismissProgressHUD() + } + + // Dismiss the progress HUD after the view controller presentation + Utilities.dismissProgressHUD() } func tapped(){ diff --git a/WOKA/Theme/ViewModel/ThemeTwoVM.swift b/WOKA/Theme/ViewModel/ThemeTwoVM.swift index bf31f03..2aed5f5 100644 --- a/WOKA/Theme/ViewModel/ThemeTwoVM.swift +++ b/WOKA/Theme/ViewModel/ThemeTwoVM.swift @@ -118,48 +118,73 @@ class ThemeTwoVM{ func playLiveTV(){ Utilities.startProgressHUD(msg: "Loading...") print("tapped") - let vc = self.vc.storyboard?.instantiateViewController(identifier: "PlayerVC") as! PlayerVC + let vc = self.vc.storyboard?.instantiateViewController(identifier: K.StoryBoardID.Theme.playerVC) as! PlayerVC - DispatchQueue.main.async { - do { - // Create a JWMediaTrack with the thumbnails .vtt file -// let thumbnailTrack = try JWThumbnailTrackBuilder() -// .file(URL(string:"https://content.jwplatform.com/videos/Agy4RIje-Ysj2G4DQ.mp4")!) -// .build() - - // Create a JWPlayerItem - let item = try JWPlayerItemBuilder() - .file(URL(string: self.liveStreamURL)!) -// .posterImage(URL(string: "https://img.freepik.com/free-photo/painting-mountain-lake-with-mountain-background_188544-9126.jpg")!) - // .mediaTracks([thumbnailTrack]) - .build() - - // Create a config, and give it the item as a playlist. - let config = try JWPlayerConfigurationBuilder() - .playlist(items: [item]) - .autostart(true) -// .preload(.auto) -// .repeatContent(true) - .build() - - vc.config = config - vc.dismissTapped = self.tapped - vc.contentType = .liveStream - vc.modalPresentationStyle = .overFullScreen - vc.modalTransitionStyle = .crossDissolve - Utilities.dismissProgressHUD() - self.vc.present(vc, animated: false) { - self.stopLiveStream() - // vc.setDeviceOrientation(orientation: .landscapeRight) - } -// Utilities.dismissProgressHUD() -// self.vc.navigationController?.pushViewController(vc, animated: true) -// self.stopLiveStream() - } - catch { - // Handle Error - } + guard let data = AuthFunc.shareInstance.staticURLs , let liveStreamData = data.liveData?.first else{ + self.vc.toast(msg: "Issue with live streaming", time: 2) + return } + var url = String() + var title = String() + + if AuthFunc.shareInstance.languageSelected == .english{ + url = liveStreamData.liveURL?.hdURLEn ?? "" + title = liveStreamData.name?.titleEn ?? "" + }else{ + url = liveStreamData.liveURL?.hdURLHin ?? "" + title = liveStreamData.name?.titleHin ?? "" + } + + do { + // Ensure the liveStreamURL is valid + guard let liveStreamURL = URL(string: url) else { + print("Invalid live stream URL") + Utilities.dismissProgressHUD() + return + } + + let videoSourceBuilder = try JWVideoSourceBuilder() + // .defaultVideo(true) + .file(liveStreamURL) + .label(title) + .build() + + // Create a JWPlayerItem + let item = try JWPlayerItemBuilder() + // .file(liveStreamURL) + .videoSources([videoSourceBuilder]) + .title(title) + .build() + + // Create a JWPlayerConfiguration + let config = try JWPlayerConfigurationBuilder() + .playlist(items: [item]) + .preload(JWPreload(rawValue: 20) ?? .none) + .autostart(true) + .build() + + vc.config = config + vc.dismissTapped = self.tapped + vc.contentType = .liveStream + vc.modalPresentationStyle = .fullScreen + vc.modalTransitionStyle = .crossDissolve + + DispatchQueue.main.async { [weak self] in + guard let self else{return} + + // Present the PlayerVC + self.vc.present(vc, animated: false) { [weak self] in + guard let self else{return} + stopLiveStream() + } + } + } catch { + print("Error creating JWPlayer configuration: \(error)") + Utilities.dismissProgressHUD() + } + + // Dismiss the progress HUD after the view controller presentation + Utilities.dismissProgressHUD() } func tapped(){ @@ -204,6 +229,8 @@ class ThemeTwoVM{ if let avatar = data.avtarURL{ // vc.avatarImage.imageURL("https://wokaland.com/secret-panel-10102023/hidden-admin-portal-20092023/storage/app/public/uploads/avtar/avatar2.png?d=1716889852") vc.avatarImage.imageURL(avatar) + }else{ + vc.avatarImage.image = UIImage(named: "DefaultAvatar") } } @@ -211,7 +238,19 @@ class ThemeTwoVM{ /* Av Player Setup */ - guard let streamURL = URL(string: liveStreamURL) else{return} + guard let data = AuthFunc.shareInstance.staticURLs , let liveStreamData = data.liveData?.first else{ + self.vc.toast(msg: "Issue with live streaming", time: 2) + return + } + var url = String() + + if AuthFunc.shareInstance.languageSelected == .english{ + url = liveStreamData.liveURL?.hdURLEn ?? "" + }else{ + url = liveStreamData.liveURL?.hdURLHin ?? "" + } + + guard let streamURL = URL(string: url) else{return} playerItem = AVPlayerItem(url: streamURL) diff --git a/WOKA/WOKAFM/ViewModel/WokaFMVM.swift b/WOKA/WOKAFM/ViewModel/WokaFMVM.swift index b43eb2f..940677a 100644 --- a/WOKA/WOKAFM/ViewModel/WokaFMVM.swift +++ b/WOKA/WOKAFM/ViewModel/WokaFMVM.swift @@ -11,10 +11,7 @@ import AVFoundation class WokaFMVM{ weak var vc : WokaFMVC! - - //Approved url from client - var url = "https://stream.rcast.net/71643" - + var player: AVPlayer! var playerItem: AVPlayerItem! @@ -44,7 +41,12 @@ class WokaFMVM{ } func setupPlayer() { - guard let url = URL(string: url) else{return} + guard let data = AuthFunc.shareInstance.staticURLs , let liveFmURL = data.liveFmData?.liveFmURL else{ + self.vc.toast(msg: "Issue with Radio", time: 2) + return + } + + guard let url = URL(string: liveFmURL) else{return} playerItem = AVPlayerItem(url: url) player = AVPlayer(playerItem: playerItem) }