From 9f5bc313a153476d6a8241d56b74ee60814e4247 Mon Sep 17 00:00:00 2001 From: BilalKhanWDI Date: Wed, 4 Sep 2024 20:17:33 +0530 Subject: [PATCH] - Implemented ADs with api for getting the app. - Added impressions and click count on the given ads with id. - - TC 62 - TC 64 - TC 65, 63 - TC 59 fixed --- WOKA.xcodeproj/project.pbxproj | 12 ++ WOKA/AdClicksImpressions+CoreDataClass.swift | 15 ++ ...ClicksImpressions+CoreDataProperties.swift | 27 +++ WOKA/Address/ViewModel/AddressListVM.swift | 2 + WOKA/Audio Books/AudioBookHomeVC.swift | 32 ++- WOKA/Audio Books/AudioBookHomeVM.swift | 32 ++- WOKA/Audio Books/AudioBooks.storyboard | 2 + .../Controller/UserDetailsRegisterVC.swift | 1 + WOKA/Games/Controller/GamesListVC.swift | 34 +++- WOKA/Games/Controller/GamesWebViewVC.swift | 14 +- WOKA/Games/Games.storyboard | 2 + WOKA/Games/ViewModel/GamesListVM.swift | 32 ++- WOKA/Helpers/LoadingIndicatorImageView.swift | 42 ++++ .../Karaoke/Controller/KaraokeListingVC.swift | 33 +++- WOKA/Karaoke/Karaoke.storyboard | 2 + WOKA/Karaoke/ViewModel/KaraokeListingVM.swift | 31 ++- WOKA/Main/AuthFunc/AdsDM.swift | 37 ++++ WOKA/Main/AuthFunc/AuthFunc.swift | 63 +++++- WOKA/Network Adapter/APIEndPoints.swift | 2 + WOKA/Network Adapter/NetworkManager.swift | 36 ++++ .../Controller/SplashVC.swift | 3 + .../ViewModel/SplashVM.swift | 12 +- WOKA/PersistentStorage.swift | 186 +++++++++++++----- WOKA/Shop/Controller/ShopListingVC.swift | 60 +++++- WOKA/Shop/Model/ShopSuperCategoryDM.swift | 3 +- WOKA/Shop/ViewModel/ShopListingVM.swift | 12 +- WOKA/Theme/Base.lproj/Theme.storyboard | 3 +- WOKA/Theme/Controller/PlayerVC.swift | 27 ++- WOKA/Theme/Controller/ThemeOneVC.swift | 15 ++ WOKA/Theme/ViewModel/PlayerVM.swift | 33 ++-- WOKA/Theme/ViewModel/ThemeOneVM.swift | 43 ++-- .../WOKA.xcdatamodel/contents | 5 + WOKA/WebSeries/Controller/WebSeriesVC.swift | 34 ++-- WOKA/WebSeries/ViewModel/WebSeriesVM.swift | 25 +-- WOKA/WebSeries/WebSeries.storyboard | 10 +- 35 files changed, 769 insertions(+), 153 deletions(-) create mode 100644 WOKA/AdClicksImpressions+CoreDataClass.swift create mode 100644 WOKA/AdClicksImpressions+CoreDataProperties.swift create mode 100644 WOKA/Main/AuthFunc/AdsDM.swift diff --git a/WOKA.xcodeproj/project.pbxproj b/WOKA.xcodeproj/project.pbxproj index 4eddd52..fe57866 100644 --- a/WOKA.xcodeproj/project.pbxproj +++ b/WOKA.xcodeproj/project.pbxproj @@ -94,6 +94,8 @@ 526A43752C36AA4A00AE148F /* GamesListVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 526A43742C36AA4A00AE148F /* GamesListVC.swift */; }; 5272FCE32BDFDB05000ECB1D /* UserDetailsRegisterVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5272FCE22BDFDB05000ECB1D /* UserDetailsRegisterVC.swift */; }; 5272FCE52BDFDC8C000ECB1D /* UserDetailsRegisterVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5272FCE42BDFDC8C000ECB1D /* UserDetailsRegisterVM.swift */; }; + 5276865F2C8879FD001A5496 /* AdClicksImpressions+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5276865D2C8879FD001A5496 /* AdClicksImpressions+CoreDataClass.swift */; }; + 527686602C8879FD001A5496 /* AdClicksImpressions+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5276865E2C8879FD001A5496 /* AdClicksImpressions+CoreDataProperties.swift */; }; 527A2BC62C576EAF0080DF9B /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 527A2BC52C576EAF0080DF9B /* GoogleService-Info.plist */; }; 527A2BC82C5777360080DF9B /* VerifyAddressPincodeVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527A2BC72C5777360080DF9B /* VerifyAddressPincodeVC.swift */; }; 527A2BCA2C57776A0080DF9B /* AddNewAddressVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527A2BC92C57776A0080DF9B /* AddNewAddressVC.swift */; }; @@ -230,6 +232,7 @@ 52CA28FA2BE119F500708B49 /* UserIntrestVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52CA28F92BE119F500708B49 /* UserIntrestVC.swift */; }; 52CA28FC2BE11A0400708B49 /* UserIntrestVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52CA28FB2BE11A0400708B49 /* UserIntrestVM.swift */; }; 52CC38C32BDF812F00B74C3E /* LocalisedElements.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52CC38C22BDF812F00B74C3E /* LocalisedElements.swift */; }; + 52CC4A742C883B3F001BE47C /* AdsDM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52CC4A732C883B3F001BE47C /* AdsDM.swift */; }; 52CC85542C5BABD40084030E /* WokaFMVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52CC85532C5BABD40084030E /* WokaFMVM.swift */; }; 52D23F112C465E6F003E743A /* LogoutPopupVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52D23F102C465E6F003E743A /* LogoutPopupVC.swift */; }; 52D2F3D82C24043D009E52FF /* ShimmerEffectView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52D2F3D72C24043D009E52FF /* ShimmerEffectView.swift */; }; @@ -493,6 +496,8 @@ 526A43742C36AA4A00AE148F /* GamesListVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GamesListVC.swift; sourceTree = ""; }; 5272FCE22BDFDB05000ECB1D /* UserDetailsRegisterVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDetailsRegisterVC.swift; sourceTree = ""; }; 5272FCE42BDFDC8C000ECB1D /* UserDetailsRegisterVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDetailsRegisterVM.swift; sourceTree = ""; }; + 5276865D2C8879FD001A5496 /* AdClicksImpressions+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AdClicksImpressions+CoreDataClass.swift"; sourceTree = ""; }; + 5276865E2C8879FD001A5496 /* AdClicksImpressions+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AdClicksImpressions+CoreDataProperties.swift"; sourceTree = ""; }; 527A2BC52C576EAF0080DF9B /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 527A2BC72C5777360080DF9B /* VerifyAddressPincodeVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerifyAddressPincodeVC.swift; sourceTree = ""; }; 527A2BC92C57776A0080DF9B /* AddNewAddressVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddNewAddressVC.swift; sourceTree = ""; }; @@ -629,6 +634,7 @@ 52CA28F92BE119F500708B49 /* UserIntrestVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIntrestVC.swift; sourceTree = ""; }; 52CA28FB2BE11A0400708B49 /* UserIntrestVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIntrestVM.swift; sourceTree = ""; }; 52CC38C22BDF812F00B74C3E /* LocalisedElements.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalisedElements.swift; sourceTree = ""; }; + 52CC4A732C883B3F001BE47C /* AdsDM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdsDM.swift; sourceTree = ""; }; 52CC85532C5BABD40084030E /* WokaFMVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WokaFMVM.swift; sourceTree = ""; }; 52D23F102C465E6F003E743A /* LogoutPopupVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogoutPopupVC.swift; sourceTree = ""; }; 52D2F3D72C24043D009E52FF /* ShimmerEffectView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShimmerEffectView.swift; sourceTree = ""; }; @@ -923,6 +929,8 @@ 523ED25C2BDA2BC700CFED02 /* WOKA */ = { isa = PBXGroup; children = ( + 5276865D2C8879FD001A5496 /* AdClicksImpressions+CoreDataClass.swift */, + 5276865E2C8879FD001A5496 /* AdClicksImpressions+CoreDataProperties.swift */, 52ACC1232C610CBC00791528 /* UserClicks+CoreDataClass.swift */, 52ACC1242C610CBC00791528 /* UserClicks+CoreDataProperties.swift */, 5255C3FB2C5B67C90030BB22 /* WOKAFM */, @@ -1683,6 +1691,7 @@ 525327D82BFCDDF700F64283 /* AuthFuncStartupSoundHandling.swift */, 52FDBA7A2BFF2712009D7AC7 /* AuthFuncTimeHandling.swift */, 9CC0D2F92C6F33BE0019DF73 /* AuthFuncUserVideoView.swift */, + 52CC4A732C883B3F001BE47C /* AdsDM.swift */, ); path = AuthFunc; sourceTree = ""; @@ -2375,6 +2384,7 @@ 9C7939132C0EFCAE00F5D6E6 /* FaqVM.swift in Sources */, 52D774ED2BDFC13F001D87DE /* OTPVM.swift in Sources */, 52D23F112C465E6F003E743A /* LogoutPopupVC.swift in Sources */, + 52CC4A742C883B3F001BE47C /* AdsDM.swift in Sources */, 527A2BD22C57B40A0080DF9B /* CartDataCache.swift in Sources */, 525327D62BFCC23600F64283 /* SideMenuVM.swift in Sources */, 525861D22C4FC6C000C33C79 /* CartPaymentOptionsVC.swift in Sources */, @@ -2512,6 +2522,8 @@ 9CA7C6C22C1095B600D73742 /* ProfileVM.swift in Sources */, 9CB3D0912C37D6930062869D /* KaraokeDetailsVC.swift in Sources */, 52E214C72C2AD47F00BC2D29 /* EpisodeDetailsVC.swift in Sources */, + 5276865F2C8879FD001A5496 /* AdClicksImpressions+CoreDataClass.swift in Sources */, + 527686602C8879FD001A5496 /* AdClicksImpressions+CoreDataProperties.swift in Sources */, 52D774F12BDFC53B001D87DE /* StringSubScript.swift in Sources */, 9C9BE46E2C663B1600C48D6A /* JWKaraokePlayerVM.swift in Sources */, 9CBE1B3F2C0F37B300CA6E61 /* DPDConstants.swift in Sources */, diff --git a/WOKA/AdClicksImpressions+CoreDataClass.swift b/WOKA/AdClicksImpressions+CoreDataClass.swift new file mode 100644 index 0000000..96bf9af --- /dev/null +++ b/WOKA/AdClicksImpressions+CoreDataClass.swift @@ -0,0 +1,15 @@ +// +// AdClicksImpressions+CoreDataClass.swift +// WOKA +// +// Created by MacBook Pro on 04/09/24. +// +// + +import Foundation +import CoreData + +@objc(AdClicksImpressions) +public class AdClicksImpressions: NSManagedObject { + +} diff --git a/WOKA/AdClicksImpressions+CoreDataProperties.swift b/WOKA/AdClicksImpressions+CoreDataProperties.swift new file mode 100644 index 0000000..c3125fc --- /dev/null +++ b/WOKA/AdClicksImpressions+CoreDataProperties.swift @@ -0,0 +1,27 @@ +// +// AdClicksImpressions+CoreDataProperties.swift +// WOKA +// +// Created by MacBook Pro on 04/09/24. +// +// + +import Foundation +import CoreData + + +extension AdClicksImpressions { + + @nonobjc public class func fetchRequest() -> NSFetchRequest { + return NSFetchRequest(entityName: "AdClicksImpressions") + } + + @NSManaged public var ad_id: Int64 + @NSManaged public var no_of_click: Int64 + @NSManaged public var no_of_impression: Int64 + +} + +extension AdClicksImpressions : Identifiable { + +} diff --git a/WOKA/Address/ViewModel/AddressListVM.swift b/WOKA/Address/ViewModel/AddressListVM.swift index 29c40eb..0c5dd27 100644 --- a/WOKA/Address/ViewModel/AddressListVM.swift +++ b/WOKA/Address/ViewModel/AddressListVM.swift @@ -101,8 +101,10 @@ class AddressListVM{ func checkForNoData(){ if CartDataCache.addressData.count == 0{ + vc.useSelectedAddBtn.isHidden = true vc.noDataStack.isHidden = false }else{ + vc.useSelectedAddBtn.isHidden = false vc.noDataStack.isHidden = true } } diff --git a/WOKA/Audio Books/AudioBookHomeVC.swift b/WOKA/Audio Books/AudioBookHomeVC.swift index e4a66bb..346ae3a 100644 --- a/WOKA/Audio Books/AudioBookHomeVC.swift +++ b/WOKA/Audio Books/AudioBookHomeVC.swift @@ -13,6 +13,8 @@ class AudioBookHomeVC: UIViewController { @IBOutlet weak var scrollView: UIScrollView! @IBOutlet weak var headerHeight: NSLayoutConstraint! + @IBOutlet weak var headerBtn: LocalisedElementsButton! + @IBOutlet weak var headerTitleHeight: NSLayoutConstraint! @IBOutlet weak var continueWatchingCV: UICollectionView! @IBOutlet weak var audioListingTableView: UITableView! @IBOutlet weak var tableHeight: NSLayoutConstraint! @@ -71,6 +73,16 @@ class AudioBookHomeVC: UIViewController { K.GVar.reloadContinueAudioBooks = false vm.getContinueWatching() } + + /* + Check if ads is there to map impressions + */ + if let adsData = AuthFunc.shareInstance.adsData{ + // check if ads data contains ad for webseries + if let audioBooksAd = adsData.result?.filter({$0.forPage == AdsEnum.audioBooks.rawValue}).first, let adID = audioBooksAd.id{ + PersistentStorage.shared.addAdsCount(adID: adID ,impressions: 1) + } + } } override func viewDidLayoutSubviews() { @@ -85,6 +97,20 @@ class AudioBookHomeVC: UIViewController { } @IBAction func listenAudioBtnTapped(_ sender: LocalisedElementsButton) { + /* + MAke logic for ads + */ + if let adsData = AuthFunc.shareInstance.adsData{ + // check if ads data contains ad for webseries + if let audioBooksAd = adsData.result?.filter({$0.forPage == AdsEnum.audioBooks.rawValue}).first, let adLink = audioBooksAd.adLink, let adID = audioBooksAd.id{ + PersistentStorage.shared.addAdsCount(adID: adID,clicks: 1) + if let url = URL(string: adLink), UIApplication.shared.canOpenURL(url) { + UIApplication.shared.open(url) + } + return + } + } + guard let data = vm.headerData, let postID = data.id else{return} PersistentStorage.shared.addAudioCount(postID: postID) var playerItems = [JwPlayerItemCreate]() @@ -279,16 +305,16 @@ extension AudioBookHomeVC: UIScrollViewDelegate { // Define the height range for the header view let minHeaderHeight: CGFloat = 0.0 // Height at which the header becomes invisible - let maxHeaderHeight: CGFloat = 200.0 // Maximum height when fully visible +// let maxHeaderHeight: CGFloat = 200.0 // Maximum height when fully visible // Calculate the new height for the header view based on the scroll position let newHeaderHeight: CGFloat if y < 0 { // When scrolling up beyond the top, ensure the header view is fully expanded - newHeaderHeight = maxHeaderHeight + newHeaderHeight = vm.maxHeaderHeight } else { // Calculate the new height for the header view, ensuring it doesn't go below the minimum height - newHeaderHeight = max(minHeaderHeight, maxHeaderHeight - y) + newHeaderHeight = max(minHeaderHeight, vm.maxHeaderHeight - y) } // Update the header view's height constraint with the new height diff --git a/WOKA/Audio Books/AudioBookHomeVM.swift b/WOKA/Audio Books/AudioBookHomeVM.swift index 0a7c17e..260eef8 100644 --- a/WOKA/Audio Books/AudioBookHomeVM.swift +++ b/WOKA/Audio Books/AudioBookHomeVM.swift @@ -18,6 +18,7 @@ class AudioBookHomeVM{ // var indexToLoad = 0 var pageNo = 0 + var maxHeaderHeight = 0.0 func initView(){ vc.scrollView.indicatorStyle = .white // or .white @@ -25,6 +26,10 @@ class AudioBookHomeVM{ setupCell() getContinueWatching() getShowListing() + + //Set banner height + maxHeaderHeight = UIScreen.main.bounds.width * 0.55 + vc.headerHeight.constant = maxHeaderHeight } func startShimmer(){ @@ -141,10 +146,31 @@ class AudioBookHomeVM{ self.vc.tableHeight.constant = self.vc.audioListingTableView.contentSize.height + 100 self.vc.audioListingTableView.layoutIfNeeded() self.vc.tableHeight.constant = self.vc.audioListingTableView.contentSize.height - if !isBtnClick{ - self.headerData = self.audioListData.first - self.setHeaderData() + /* + MAke logic for ads + */ + if let adsData = AuthFunc.shareInstance.adsData{ + // check if ads data contains ad for webseries + if let audioBooksAd = adsData.result?.filter({$0.forPage == AdsEnum.audioBooks.rawValue}).first, let bannerImage = audioBooksAd.bannerImage, let buttonImage = audioBooksAd.buttonImage{ + vc.headerImage.imageURL(bannerImage, color: .white) + vc.headerBtn.setTitle("", for: .normal) + vc.headerTitleLabel.text = "" + vc.headerTitleHeight.constant = 10 + vc.headerBtn.backgroundColor = .clear + vc.headerBtn.sd_setBackgroundImage(with: URL(string:buttonImage), for: .normal) + }else{ + if !isBtnClick{ + self.headerData = self.audioListData.first + self.setHeaderData() + } + } + }else{ + if !isBtnClick{ + self.headerData = self.audioListData.first + self.setHeaderData() + } } + self.stopShimmer() self.vc.loadMoreActivityIndicator.stopAnimating() diff --git a/WOKA/Audio Books/AudioBooks.storyboard b/WOKA/Audio Books/AudioBooks.storyboard index aaaccab..0f68718 100644 --- a/WOKA/Audio Books/AudioBooks.storyboard +++ b/WOKA/Audio Books/AudioBooks.storyboard @@ -225,8 +225,10 @@ + + diff --git a/WOKA/Authentication/Controller/UserDetailsRegisterVC.swift b/WOKA/Authentication/Controller/UserDetailsRegisterVC.swift index 068c069..37a4641 100644 --- a/WOKA/Authentication/Controller/UserDetailsRegisterVC.swift +++ b/WOKA/Authentication/Controller/UserDetailsRegisterVC.swift @@ -31,6 +31,7 @@ class UserDetailsRegisterVC : UIViewController{ override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) navigationController?.setNavigationBarHidden(false, animated: animated) + self.navigationController?.setColor(color: .black) } override func viewWillDisappear(_ animated: Bool) { diff --git a/WOKA/Games/Controller/GamesListVC.swift b/WOKA/Games/Controller/GamesListVC.swift index d6bae65..e938b43 100644 --- a/WOKA/Games/Controller/GamesListVC.swift +++ b/WOKA/Games/Controller/GamesListVC.swift @@ -14,6 +14,8 @@ class GamesListVC: UIViewController { @IBOutlet weak var gamesListingTableView: UITableView! @IBOutlet weak var tableHeight: NSLayoutConstraint! @IBOutlet weak var headerView: ShimmerEffectView! + @IBOutlet weak var headerTitleHeight: NSLayoutConstraint! + @IBOutlet weak var headerBtn: LocalisedElementsButton! @IBOutlet weak var headerImage: UIImageView! @IBOutlet weak var headerTitleLabel: UILabel! @IBOutlet weak var gamesLoadingView: ShimmerEffectView! @@ -55,6 +57,18 @@ class GamesListVC: UIViewController { self.navigationController?.setColor(color: .black) } + override func viewDidAppear(_ animated: Bool) { + /* + Check if ads is there to map impressions + */ + if let adsData = AuthFunc.shareInstance.adsData{ + // check if ads data contains ad for webseries + if let gamesAd = adsData.result?.filter({$0.forPage == AdsEnum.games.rawValue}).first, let adID = gamesAd.id{ + PersistentStorage.shared.addAdsCount(adID: adID ,impressions: 1) + } + } + } + override func viewDidLayoutSubviews() { vm.updateTableHeight() } @@ -63,6 +77,20 @@ class GamesListVC: UIViewController { @IBAction func gameBtnTapped(_ sender: LocalisedElementsButton) { + /* + MAke logic for ads + */ + if let adsData = AuthFunc.shareInstance.adsData{ + // check if ads data contains ad for webseries + if let gamesAd = adsData.result?.filter({$0.forPage == AdsEnum.games.rawValue}).first, let adLink = gamesAd.adLink, let adID = gamesAd.id{ + PersistentStorage.shared.addAdsCount(adID: adID,clicks: 1) + if let url = URL(string: adLink), UIApplication.shared.canOpenURL(url) { + UIApplication.shared.open(url) + } + return + } + } + let sb = UIStoryboard(name: K.StoryBoard.Games, bundle: nil) let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Games.gamesWebViewVC) as! GamesWebViewVC let gameData = vm.gameData[vm.indexToLoad] @@ -176,16 +204,16 @@ extension GamesListVC: UIScrollViewDelegate { // Define the height range for the header view let minHeaderHeight: CGFloat = 0.0 // Height at which the header becomes invisible - let maxHeaderHeight: CGFloat = 200.0 // Maximum height when fully visible +// let maxHeaderHeight: CGFloat = 200.0 // Maximum height when fully visible // Calculate the new height for the header view based on the scroll position let newHeaderHeight: CGFloat if y < 0 { // When scrolling up beyond the top, ensure the header view is fully expanded - newHeaderHeight = maxHeaderHeight + newHeaderHeight = vm.maxHeaderHeight } else { // Calculate the new height for the header view, ensuring it doesn't go below the minimum height - newHeaderHeight = max(minHeaderHeight, maxHeaderHeight - y) + newHeaderHeight = max(minHeaderHeight, vm.maxHeaderHeight - y) } // Update the header view's height constraint with the new height diff --git a/WOKA/Games/Controller/GamesWebViewVC.swift b/WOKA/Games/Controller/GamesWebViewVC.swift index 538634d..36c20cb 100644 --- a/WOKA/Games/Controller/GamesWebViewVC.swift +++ b/WOKA/Games/Controller/GamesWebViewVC.swift @@ -40,12 +40,16 @@ class GamesWebViewVC: UIViewController, WKNavigationDelegate,UIGestureRecognizer override func viewDidLoad() { super.viewDidLoad() - if let orientation, orientation == .landscape{ - appDelegate.deviceOrientation = .landscapeRight - let value = UIInterfaceOrientation.landscapeRight.rawValue - UIDevice.current.setValue(value, forKey: "orientation") -// rotateToLandsScapeDevice() + DispatchQueue.main.async { [weak self] in + guard let self else{return} + if let orientation, orientation == .landscape{ + appDelegate.deviceOrientation = .landscapeRight + let value = UIInterfaceOrientation.landscapeRight.rawValue + UIDevice.current.setValue(value, forKey: "orientation") + // rotateToLandsScapeDevice() + } } + guard let url else{return} diff --git a/WOKA/Games/Games.storyboard b/WOKA/Games/Games.storyboard index c5a96e1..cfba77a 100644 --- a/WOKA/Games/Games.storyboard +++ b/WOKA/Games/Games.storyboard @@ -192,8 +192,10 @@ + + diff --git a/WOKA/Games/ViewModel/GamesListVM.swift b/WOKA/Games/ViewModel/GamesListVM.swift index c67f0fe..f70d729 100644 --- a/WOKA/Games/ViewModel/GamesListVM.swift +++ b/WOKA/Games/ViewModel/GamesListVM.swift @@ -14,7 +14,8 @@ class GamesListVM{ var gameData = [GamesListDM.GameDatum]() var indexToLoad = 0 var pageNo = 0 - + var maxHeaderHeight = 0.0 + func initView(){ setupCell() vc.scrollView.indicatorStyle = .white // or .white @@ -23,6 +24,11 @@ class GamesListVM{ self.vc.view.applyGradient(colors: [color1,color2], startPoint: .Point.left.point , endPoint: .Point.right.point) startShimmer() getGamesListing() + + //Set banner height + maxHeaderHeight = UIScreen.main.bounds.width * 0.55 + vc.headerHeight.constant = maxHeaderHeight + } func setupCell(){ @@ -96,9 +102,29 @@ class GamesListVM{ self.vc.gamesListingTableView.layoutIfNeeded() self.vc.tableHeight.constant = self.vc.gamesListingTableView.contentSize.height - if !isBtnClick{ - setHeaderData() + /* + MAke logic for ads + */ + if let adsData = AuthFunc.shareInstance.adsData{ + // check if ads data contains ad for webseries + if let gamesAd = adsData.result?.filter({$0.forPage == AdsEnum.games.rawValue}).first, let bannerImage = gamesAd.bannerImage, let buttonImage = gamesAd.buttonImage{ + vc.headerImage.imageURL(bannerImage, color: .white) + vc.headerBtn.setTitle("", for: .normal) + vc.headerTitleLabel.text = "" + vc.headerTitleHeight.constant = 10 + vc.headerBtn.backgroundColor = .clear + vc.headerBtn.sd_setBackgroundImage(with: URL(string:buttonImage), for: .normal) + }else{ + if !isBtnClick{ + setHeaderData() + } + } + }else{ + if !isBtnClick{ + setHeaderData() + } } + self.stopShimmer() diff --git a/WOKA/Helpers/LoadingIndicatorImageView.swift b/WOKA/Helpers/LoadingIndicatorImageView.swift index 8e5ffc1..c10a3f9 100644 --- a/WOKA/Helpers/LoadingIndicatorImageView.swift +++ b/WOKA/Helpers/LoadingIndicatorImageView.swift @@ -39,3 +39,45 @@ extension UIImageView { } } } + +extension UIButton { + + func setImage(from url: String, for state: UIControl.State, color: UIColor = .black) { + + // Ensure the button's background is clear + self.backgroundColor = .clear + + // Ensure the button's image view background is clear + self.imageView?.backgroundColor = .clear + + let activityIndicator = UIActivityIndicatorView(style: .medium) + activityIndicator.tintColor = .darkGray + activityIndicator.color = color + activityIndicator.frame = CGRect(x: 0, y: 0, width: 64, height: 64) + activityIndicator.hidesWhenStopped = true + DispatchQueue.main.async { + activityIndicator.startAnimating() + } + activityIndicator.translatesAutoresizingMaskIntoConstraints = true + + activityIndicator.center = CGPoint(x: self.frame.size.width / 2, y: self.frame.size.height / 2) + + // Resizing the indicator to be perfectly centered + activityIndicator.autoresizingMask = [ + .flexibleRightMargin, + .flexibleLeftMargin, + .flexibleBottomMargin, + .flexibleTopMargin + ] + + self.addSubview(activityIndicator) + + // Setting the image using SDWebImage + self.sd_setImage(with: URL(string: url.replacingOccurrences(of: " ", with: "%20")), for: state) { (image, error, cacheType, url) in + DispatchQueue.main.async { + activityIndicator.stopAnimating() + activityIndicator.removeFromSuperview() + } + } + } +} diff --git a/WOKA/Karaoke/Controller/KaraokeListingVC.swift b/WOKA/Karaoke/Controller/KaraokeListingVC.swift index 169d0ce..b16b37c 100644 --- a/WOKA/Karaoke/Controller/KaraokeListingVC.swift +++ b/WOKA/Karaoke/Controller/KaraokeListingVC.swift @@ -10,8 +10,10 @@ import UIKit class KaraokeListingVC: UIViewController { @IBOutlet weak var headerView: ShimmerEffectView! + @IBOutlet weak var headerBtn: LocalisedElementsButton! @IBOutlet weak var selectedShowView: ShimmerEffectView! @IBOutlet weak var headerHeight: NSLayoutConstraint! + @IBOutlet weak var headerViewLabelHeight: NSLayoutConstraint! @IBOutlet weak var headerImage: UIImageView! @IBOutlet weak var headerTitleLabel: UILabel! @@ -69,6 +71,16 @@ class KaraokeListingVC: UIViewController { K.GVar.reloadContinueKaraoke = false self.vm.getContinueWatching() } + + /* + Check if ads is there to map impressions + */ + if let adsData = AuthFunc.shareInstance.adsData{ + // check if ads data contains ad for webseries + if let karaokeAd = adsData.result?.filter({$0.forPage == AdsEnum.karaoke.rawValue}).first, let adID = karaokeAd.id{ + PersistentStorage.shared.addAdsCount(adID: adID ,impressions: 1) + } + } } @IBAction func loadMoreBtnTapped(_ sender: LocalisedElementsButton) { @@ -80,6 +92,22 @@ class KaraokeListingVC: UIViewController { } @IBAction func singBtnTapped(_ sender: LocalisedElementsButton) { + + /* + MAke logic for ads + */ + if let adsData = AuthFunc.shareInstance.adsData{ + // check if ads data contains ad for webseries + if let karaokeAd = adsData.result?.filter({$0.forPage == AdsEnum.karaoke.rawValue}).first, let adLink = karaokeAd.adLink, let adID = karaokeAd.id{ + PersistentStorage.shared.addAdsCount(adID: adID ,clicks: 1) + + if let url = URL(string: adLink), UIApplication.shared.canOpenURL(url) { + UIApplication.shared.open(url) + } + return + } + } + if let id = vm.headerData?.id{ PersistentStorage.shared.addKaraokeCount(postID: id) } @@ -268,16 +296,15 @@ extension KaraokeListingVC: UIScrollViewDelegate { // Define the height range for the header view let minHeaderHeight: CGFloat = 0.0 // Height at which the header becomes invisible - let maxHeaderHeight: CGFloat = 200.0 // Maximum height when fully visible // Calculate the new height for the header view based on the scroll position let newHeaderHeight: CGFloat if y < 0 { // When scrolling up beyond the top, ensure the header view is fully expanded - newHeaderHeight = maxHeaderHeight + newHeaderHeight = vm.maxHeaderHeight } else { // Calculate the new height for the header view, ensuring it doesn't go below the minimum height - newHeaderHeight = max(minHeaderHeight, maxHeaderHeight - y) + newHeaderHeight = max(minHeaderHeight, vm.maxHeaderHeight - y) } // Update the header view's height constraint with the new height diff --git a/WOKA/Karaoke/Karaoke.storyboard b/WOKA/Karaoke/Karaoke.storyboard index 163f166..ef71d32 100644 --- a/WOKA/Karaoke/Karaoke.storyboard +++ b/WOKA/Karaoke/Karaoke.storyboard @@ -233,10 +233,12 @@ + + diff --git a/WOKA/Karaoke/ViewModel/KaraokeListingVM.swift b/WOKA/Karaoke/ViewModel/KaraokeListingVM.swift index 9a6e172..75749cf 100644 --- a/WOKA/Karaoke/ViewModel/KaraokeListingVM.swift +++ b/WOKA/Karaoke/ViewModel/KaraokeListingVM.swift @@ -17,6 +17,7 @@ class KaraokeListingVM{ var headerData : KaraokeListingDM.KaraokeDatum? var pageNo = 0 + var maxHeaderHeight = 0.0 func initView(){ setupCell() @@ -28,6 +29,10 @@ class KaraokeListingVM{ startShimmer() getContinueWatching() getKaraokeListing() + + //Set banner height + maxHeaderHeight = UIScreen.main.bounds.width * 0.55 + vc.headerHeight.constant = maxHeaderHeight } func setupCell(){ @@ -139,9 +144,29 @@ class KaraokeListingVM{ self.vc.karaokeListingTableView.layoutIfNeeded() self.vc.tableHeight.constant = self.vc.karaokeListingTableView.contentSize.height + 10 - if !isBtnClick{ - self.headerData = self.karaokeListData.first - setHeaderData() + /* + MAke logic for ads + */ + if let adsData = AuthFunc.shareInstance.adsData{ + // check if ads data contains ad for webseries + if let karaokeAd = adsData.result?.filter({$0.forPage == AdsEnum.karaoke.rawValue}).first, let bannerImage = karaokeAd.bannerImage, let buttonImage = karaokeAd.buttonImage{ + vc.headerImage.imageURL(bannerImage, color: .white) + vc.headerBtn.setTitle("", for: .normal) + vc.headerTitleLabel.text = "" + vc.headerViewLabelHeight.constant = 10 + vc.headerBtn.backgroundColor = .clear + vc.headerBtn.sd_setBackgroundImage(with: URL(string:buttonImage), for: .normal) + }else{ + if !isBtnClick{ + self.headerData = self.karaokeListData.first + setHeaderData() + } + } + }else{ + if !isBtnClick{ + self.headerData = self.karaokeListData.first + setHeaderData() + } } self.stopShimmer() diff --git a/WOKA/Main/AuthFunc/AdsDM.swift b/WOKA/Main/AuthFunc/AdsDM.swift new file mode 100644 index 0000000..b52e172 --- /dev/null +++ b/WOKA/Main/AuthFunc/AdsDM.swift @@ -0,0 +1,37 @@ +// +// AdsDM.swift +// WOKA +// +// Created by MacBook Pro on 04/09/24. +// + +import Foundation + +// MARK: - AdsDM +struct AdsDM: Codable { + let result: [ResultData]? + let totalRecords: Int? + + enum CodingKeys: String, CodingKey { + case result + case totalRecords = "total_records" + } + + // MARK: - Result + struct ResultData: Codable { + let id: Int? + let title, adCompany: String? + let bannerImage, buttonImage: String? + let forPage: String? + let adLink: String? + + enum CodingKeys: String, CodingKey { + case id, title + case adCompany = "ad_company" + case bannerImage = "banner_image" + case buttonImage = "button_image" + case forPage = "for_page" + case adLink = "ad_link" + } + } +} diff --git a/WOKA/Main/AuthFunc/AuthFunc.swift b/WOKA/Main/AuthFunc/AuthFunc.swift index 3947d51..e5b85f6 100644 --- a/WOKA/Main/AuthFunc/AuthFunc.swift +++ b/WOKA/Main/AuthFunc/AuthFunc.swift @@ -9,11 +9,23 @@ import Foundation import AVFoundation import UIKit import OneSignalFramework +import Alamofire enum GetSet{ case get case set } + +enum AdsEnum : String{ + case themeOne = "theme-1" + case themeTwo = "theme-2" + case shop_super_category = "shop-super-category" + case web_series = "web-series" + case karaoke = "karaoke" + case audioBooks = "audio-books" + case games = "games" +} + class AuthFunc{ /** @@ -23,10 +35,31 @@ class AuthFunc{ var player: AVQueuePlayer? var playerLooper: AVPlayerLooper? + + /* + This will hold user type + */ var userType = UserType.adult + + /* + This will hold the user data + */ var userData : UserDataDM.ResultData? + + /* + This holds the live url and fm url + */ var staticURLs : URLStaticDM? + /* + This holds the ads + */ + var adsData : AdsDM? + + + /* + This holds the language selected by user + */ var languageSelected = LocalizedEnum.english { didSet { NotificationCenter.default.post(name: .languageDidChange, object: nil) @@ -36,6 +69,9 @@ class AuthFunc{ var authID = String() var authPass = String() + /* + This will hold the theme selected + */ var selectedTheme = ThemeSelect.theme1 /* @@ -156,6 +192,7 @@ class AuthFunc{ UserDefaults.standard.setValue(nil, forKey: K.UserDefaultsStruct.userAccessToken) UserDefaults.standard.setValue(nil, forKey: K.UserDefaultsStruct.userType) userData = nil + CartDataCache.shareInstance.removeAll() selectedTheme = .theme1 } @@ -184,7 +221,31 @@ class AuthFunc{ default: onCompletion?(false) } - case .failure(let error): + case .failure(_): + onCompletion?(false) + } + } + } + + // MARK: - Get AD's + + func getAds(onCompletion: ((Bool) -> Void)? = nil){ + let params : Parameters = ["start" : "0", + "limit":"0"] + NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Analytics.get_ad_data, method: .get,parameters: params) { (result : Result, NetworkManager.APIError>) in + switch result{ + case .success(let data): + switch data.success{ + case 0: + onCompletion?(false) + case 1: + guard let data = data.data else{return} + AuthFunc.shareInstance.adsData = data + onCompletion?(true) + default: + onCompletion?(false) + } + case .failure(_): onCompletion?(false) } } diff --git a/WOKA/Network Adapter/APIEndPoints.swift b/WOKA/Network Adapter/APIEndPoints.swift index 97ea377..e958fd0 100644 --- a/WOKA/Network Adapter/APIEndPoints.swift +++ b/WOKA/Network Adapter/APIEndPoints.swift @@ -156,6 +156,8 @@ struct APIEndPoints { struct Analytics{ static let user_clicks = makeURL(path: "v2/user_clicks") static let user_video_view = makeURL(path: "user_video_view") + static let get_ad_data = makeURL(path: "get_ad_data") + static let update_ad_count = makeURL(path: "update_ad_count") } // Helper method to construct full URL from base URL and path diff --git a/WOKA/Network Adapter/NetworkManager.swift b/WOKA/Network Adapter/NetworkManager.swift index 811b105..2573bf5 100644 --- a/WOKA/Network Adapter/NetworkManager.swift +++ b/WOKA/Network Adapter/NetworkManager.swift @@ -192,6 +192,42 @@ class NetworkManager{ } } } + + func nwCallRawJSONAds(adsData : [AdsClickImpressionsData], onCompletion : @escaping (Bool) -> Void){ + let loginCred = getLoginIDPass() + let encoder = JSONEncoder() + encoder.keyEncodingStrategy = .convertToSnakeCase + guard let jsonData = try? encoder.encode(adsData), + let jsonArray = try? JSONSerialization.jsonObject(with: jsonData, options: .allowFragments) as? [[String: Any]] else { + print("Failed to encode totalClicks array to JSON") + return + } + + let url = APIEndPoints.Analytics.update_ad_count + var request = URLRequest(url: url) + request.httpMethod = "POST" + request.headers = ["device-id" : AuthFunc.shareInstance.getDeviceUUID(), + "access-token" : AuthFunc.shareInstance.getAccessToken()] + request.setValue("application/json", forHTTPHeaderField: "Content-Type") + do { + // Set the HTTP body with the JSON data + request.httpBody = try JSONSerialization.data(withJSONObject: jsonArray) + } catch let error { + print("Error: \(error.localizedDescription)") + return + } + + AF.request(request).authenticate(username: loginCred.0, password: loginCred.1) + .validate(statusCode: 200..<300) + .responseDecodable(of: CommonResponseModel.self) { response in + switch response.result { + case .success(let data): + onCompletion(true) + case .failure(let error): + onCompletion(false) + } + } + } } diff --git a/WOKA/OnBoarding Module/Controller/SplashVC.swift b/WOKA/OnBoarding Module/Controller/SplashVC.swift index c770fb6..9f0d0f2 100644 --- a/WOKA/OnBoarding Module/Controller/SplashVC.swift +++ b/WOKA/OnBoarding Module/Controller/SplashVC.swift @@ -39,10 +39,13 @@ class SplashVC: UIViewController { switch sender{ case hindiBtn: + UserDefaults.standard.setValue(LocalizedEnum.hindi.rawValue, forKey: K.UserDefaultsStruct.defaultLanguage) AuthFunc.shareInstance.languageSelected = .hindi case englishBtn: + UserDefaults.standard.setValue(LocalizedEnum.english.rawValue, forKey: K.UserDefaultsStruct.defaultLanguage) AuthFunc.shareInstance.languageSelected = .english default: + UserDefaults.standard.setValue(LocalizedEnum.english.rawValue, forKey: K.UserDefaultsStruct.defaultLanguage) AuthFunc.shareInstance.languageSelected = .english } diff --git a/WOKA/OnBoarding Module/ViewModel/SplashVM.swift b/WOKA/OnBoarding Module/ViewModel/SplashVM.swift index b7a3788..99d720e 100644 --- a/WOKA/OnBoarding Module/ViewModel/SplashVM.swift +++ b/WOKA/OnBoarding Module/ViewModel/SplashVM.swift @@ -19,6 +19,10 @@ class SplashVM{ if AuthFunc.shareInstance.staticURLs == nil{ AuthFunc.shareInstance.getStaticURLs() } + + if AuthFunc.shareInstance.adsData == nil{ + AuthFunc.shareInstance.getAds() + } 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) @@ -34,7 +38,6 @@ class SplashVM{ }else{ AuthFunc.shareInstance.setDefaultLanguage(language: .english) } - } // Play initial sound @@ -67,6 +70,9 @@ class SplashVM{ if AuthFunc.shareInstance.getUserType() == 3{ //setusertype AuthFunc.shareInstance.userData = UserDataDM.ResultData(id: nil, genderData: nil, birthdate: nil, email: nil, avtar: nil, avtarURL: nil, userType: "3", languageMasterID: nil, lastLogin: nil, rememberToken: nil, childDetail: nil, language: nil, alreadyLoggedIn: nil, isDeactive: nil) + if AuthFunc.shareInstance.adsData == nil{ + AuthFunc.shareInstance.getAds() + } if AuthFunc.shareInstance.staticURLs == nil{ AuthFunc.shareInstance.getStaticURLs { isDone in if isDone == true{ @@ -108,6 +114,10 @@ class SplashVM{ if AuthFunc.shareInstance.staticURLs == nil{ AuthFunc.shareInstance.getStaticURLs() } + if AuthFunc.shareInstance.adsData == nil{ + AuthFunc.shareInstance.getAds() + } + DispatchQueue.main.async { UIApplication.setRootView(SideMenuController.instantiate(from: .Home)) } diff --git a/WOKA/PersistentStorage.swift b/WOKA/PersistentStorage.swift index 2e6abe1..aa3c12b 100644 --- a/WOKA/PersistentStorage.swift +++ b/WOKA/PersistentStorage.swift @@ -47,6 +47,31 @@ struct UserClickData { let postType: Int } +// MARK: - Clicks +struct ClicksAnalytics : Codable { + let postID, postType, numberOfClicks, deviceType: Int? + let categoryID: Int? + + enum CodingKeys: String, CodingKey { + case postID = "post_id" + case postType = "post_type" + case numberOfClicks = "number_of_clicks" + case deviceType = "device_type" + case categoryID = "category_id" + } +} + +// MARK: - ADs Impressions & Clicks +struct AdsClickImpressionsData : Codable { + let adID, noOfClick, noOfOmpression: Int + + enum CodingKeys: String, CodingKey { + case adID = "ad_id" + case noOfClick = "no_of_click" + case noOfOmpression = "no_of_impression" + } +} + //struct UserVideoViewData { // let postId: Int // let postType: Int @@ -246,7 +271,7 @@ final class PersistentStorage debugPrint(error) } } - + func deleteData(_ data: [UserClicks]) { let managedContext = PersistentStorage.shared.context @@ -263,6 +288,8 @@ final class PersistentStorage } } + + // MARK: - Handle Clicks For UserClicks func addOthersCount(){ @@ -311,51 +338,120 @@ final class PersistentStorage let userClicks = UserClickData(clickCounts: 1, categoryId: catID, postId: postID, postType: postType.rawValue) PersistentStorage.shared.checkWebSeries(clicksData: userClicks) } + // MARK: - Handling ADS + func sendAdsData() { + //create a context from this container + let managedContext = PersistentStorage.shared.context + + let fetchRequest:NSFetchRequest = NSFetchRequest.init(entityName: "AdClicksImpressions") + fetchRequest.fetchLimit = 15 + do { + guard let result = try managedContext.fetch(fetchRequest) as? [AdClicksImpressions] else {return} + var userImpressions = [AdsClickImpressionsData]() + result.forEach { ads in + // device type 1- android , 2 - iOS + userImpressions.append(AdsClickImpressionsData(adID: Int(ads.ad_id), noOfClick: Int(ads.no_of_click), noOfOmpression: Int(ads.no_of_impression))) + + print("ID:-" , ads.ad_id, "No Of Clicks :- ", ads.no_of_click, "Impressions :- ", ads.no_of_impression) + } + NetworkManager.shareInstance.nwCallRawJSONAds(adsData: userImpressions) { isDone in + if isDone{ + self.deleteAdsData(result) + } + } + } + catch let error + { + debugPrint(error) + } + } - // MARK: - Handling UserViewView CRUD + func checkIfAdExist(adsData : AdsClickImpressionsData) { + + let managedContext = PersistentStorage.shared.context + let fetchRequest = NSFetchRequest(entityName: "AdClicksImpressions") + fetchRequest.predicate = NSPredicate(format: "ad_id == %@" ,adsData.adID.toString()) + + do { + guard let result = try managedContext.fetch(fetchRequest) as? [AdClicksImpressions] else {return} + if result.isEmpty{ + //create + PersistentStorage.shared.createAdsData(data: adsData) + print("create, In Exist") + }else{ + //update + let objectUpdate = result[0] as NSManagedObject + print("Update, In Exist") + objectUpdate.setValue(result.first!.no_of_click + Int64(adsData.noOfClick), forKey: "no_of_click") + objectUpdate.setValue(result.first!.no_of_impression + Int64(adsData.noOfOmpression), forKey: "no_of_impression") + do{ + try managedContext.save() + retrieveAdsData(adID: adsData.adID) + } + catch + { + print(error) + } + } + }catch let error as NSError { + print("Could not fetch. \(error), \(error.userInfo)") + } + } + + func createAdsData(data : AdsClickImpressionsData){ + + //We need to create a context from this container + let managedContext = PersistentStorage.shared.context + + let share = AdClicksImpressions(context: managedContext) + share.ad_id = Int64(data.adID) + share.no_of_click = Int64(data.noOfClick) + share.no_of_impression = Int64(data.noOfOmpression) + + do { + try managedContext.save() + retrieveAdsData(adID: data.adID) + } catch let error as NSError { + print("Could not save. \(error), \(error.userInfo)") + } + } + + func retrieveAdsData(adID : Int?) { + let managedContext = PersistentStorage.shared.context + let fetchRequest:NSFetchRequest = NSFetchRequest.init(entityName: "AdClicksImpressions") + + fetchRequest.predicate = NSPredicate(format: "ad_id == %@",adID?.toString() ?? 0) + do { + guard let result = try managedContext.fetch(fetchRequest) as? [AdClicksImpressions] else {return} + result.forEach { ads in + print("ID:-" , ads.ad_id, "No Of Clicks :- ", ads.no_of_click, "Impressions :- ", ads.no_of_impression) + } + } + catch let error + { + debugPrint(error) + } + } + + func addAdsCount(adID : Int, impressions : Int = 0, clicks : Int = 0){ + let adsData = AdsClickImpressionsData(adID: adID, noOfClick: clicks, noOfOmpression: impressions) + PersistentStorage.shared.checkIfAdExist( adsData: adsData) + } + + func deleteAdsData(_ data: [AdClicksImpressions]) { + let managedContext = PersistentStorage.shared.context -// func createVideoViewData(data : UserVideoViewData){ -// -// //We need to create a context from this container -// let managedContext = PersistentStorage.shared.context -// -// let videoData = UserVideoView(context: managedContext) -// videoData.post_id = Int64(data.postId) -// videoData.post_type = Int64(data.postType) -// videoData.total_watched_duration = data.watchedDuration -// videoData.category_id = Int64(data.categoryId) -// -// do { -// try managedContext.save() -// retrieveData(postID: data.postId, catID: data.categoryId, postType: data.postType) -// } catch let error as NSError { -// print("Could not save. \(error), \(error.userInfo)") -// } -// } -// -// func retrieveVideoViewData(postID : Int?, catID : Int?, postType : Int) { -// -// //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]) -// let fetchRequest:NSFetchRequest = NSFetchRequest.init(entityName: "UserVideoView") -// -// fetchRequest.predicate = NSPredicate(format: "post_id == %@ AND category_id == %@ AND post_type == %@" ,postID?.toString() ?? "0", catID?.toString() ?? "0" ,postType.toString()) -// -// do { -// guard let result = try managedContext.fetch(fetchRequest) as? [UserClicks] else {return} -// result.forEach { clicks in -// print("VideoView:- ","ID:-" , PostType(rawValue: Int(clicks.post_type))!, "CatID:- ", clicks.category_id, "PostID:- ", clicks.post_id , "Count:-", clicks.click_counts) -// } -// } -// catch let error -// { -// debugPrint(error) -// } -// } - // MARK: - Handle Clicks For UserVideoView - + data.forEach { clicks in + managedContext.delete(clicks) + } + + do { + try managedContext.save() + getAllData() + print("Deleted data") + } catch let error { + debugPrint("Failed to delete data:", error) + } + } } diff --git a/WOKA/Shop/Controller/ShopListingVC.swift b/WOKA/Shop/Controller/ShopListingVC.swift index e895728..8473532 100644 --- a/WOKA/Shop/Controller/ShopListingVC.swift +++ b/WOKA/Shop/Controller/ShopListingVC.swift @@ -50,6 +50,18 @@ class ShopListingVC: UIViewController { self.navigationController?.setColor(color: .black) } + override func viewDidAppear(_ animated: Bool) { + /* + Check if ads is there to map impressions + */ + if let adsData = AuthFunc.shareInstance.adsData{ + // check if ads data contains ad for webseries + if let shopSuperCatAd = adsData.result?.filter({$0.forPage == AdsEnum.shop_super_category.rawValue}).first, let adID = shopSuperCatAd.id{ + PersistentStorage.shared.addAdsCount(adID: adID ,impressions: 1) + } + } + } + @IBAction func retryBtnTapped(_ sender: LocalisedElementsButton) { noDataStack.isHidden = true tableView.isHidden = false @@ -78,20 +90,48 @@ extension ShopListingVC : TableViewSRC{ } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - if vm.superCatData.count == 0 {return} - let superCatID = vm.superCatData[indexPath.row].id - if let superCatID{ - PersistentStorage.shared.addShopCount(postID: superCatID) + /* + MAke logic for ads + */ + if vm.superCatData[indexPath.row].isAD == true{ + if let adsData = AuthFunc.shareInstance.adsData{ + // check if ads data contains ad for webseries + if let shopSuperCatAd = adsData.result?.filter({$0.forPage == AdsEnum.shop_super_category.rawValue}).first,let adLink = shopSuperCatAd.adLink, let adID = shopSuperCatAd.id{ + PersistentStorage.shared.addAdsCount(adID: adID,clicks: 1) + if let url = URL(string: adLink), UIApplication.shared.canOpenURL(url) { + UIApplication.shared.open(url) + } + return + } + } + } + + if vm.superCatData.count == 0 {return} + + if let adsData = AuthFunc.shareInstance.adsData, (adsData.result?.filter({$0.forPage == AdsEnum.shop_super_category.rawValue}).first) != nil{ + // check if ads data contains ad for webseries + let superCatID = vm.superCatData[indexPath.row - 1].id + if let superCatID{ + PersistentStorage.shared.addShopCount(postID: superCatID) + } + let sb = UIStoryboard(name: K.StoryBoard.shop, bundle: nil) + let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Shop.shopCategoryVC) as! ShopCategoryVC + vcPush.vm.superCatID = superCatID + self.navigationController?.pushViewController(vcPush, animated: true) + return + }else{ + let superCatID = vm.superCatData[indexPath.row].id + if let superCatID{ + PersistentStorage.shared.addShopCount(postID: superCatID) + } + let sb = UIStoryboard(name: K.StoryBoard.shop, bundle: nil) + let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Shop.shopCategoryVC) as! ShopCategoryVC + vcPush.vm.superCatID = superCatID + self.navigationController?.pushViewController(vcPush, animated: true) } - let sb = UIStoryboard(name: K.StoryBoard.shop, bundle: nil) - let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Shop.shopCategoryVC) as! ShopCategoryVC - vcPush.vm.superCatID = superCatID - self.navigationController?.pushViewController(vcPush, animated: true) } } - - //extension UIViewController { // // func createCartButton(imageName: String, diff --git a/WOKA/Shop/Model/ShopSuperCategoryDM.swift b/WOKA/Shop/Model/ShopSuperCategoryDM.swift index d3aa840..7432d20 100644 --- a/WOKA/Shop/Model/ShopSuperCategoryDM.swift +++ b/WOKA/Shop/Model/ShopSuperCategoryDM.swift @@ -22,11 +22,12 @@ struct ShopSuperCategoryDM: Codable { let id: Int? let superCategoryName: String? let superCategoryThumbnail: String? - + var isAD : Bool? = false enum CodingKeys: String, CodingKey { case id case superCategoryName = "super_category_name" case superCategoryThumbnail = "super_category_thumbnail" + case isAD } } diff --git a/WOKA/Shop/ViewModel/ShopListingVM.swift b/WOKA/Shop/ViewModel/ShopListingVM.swift index 9722215..2c81687 100644 --- a/WOKA/Shop/ViewModel/ShopListingVM.swift +++ b/WOKA/Shop/ViewModel/ShopListingVM.swift @@ -84,7 +84,17 @@ class ShopListingVM{ vc.noDataStack.isHidden = true vc.tableView.isHidden = false - self.superCatData = data + /* + MAke logic for ads + */ + if let adsData = AuthFunc.shareInstance.adsData{ + // check if ads data contains ad for webseries + if let shopSuperCatAd = adsData.result?.filter({$0.forPage == AdsEnum.shop_super_category.rawValue}).first, let bannerImage = shopSuperCatAd.bannerImage{ + self.superCatData.append(ShopSuperCategoryDM.ResultData(id: shopSuperCatAd.id, superCategoryName: shopSuperCatAd.title, superCategoryThumbnail: bannerImage,isAD: true)) + } + } + + self.superCatData.append(contentsOf: data) self.vc.tableView.reloadData() default: vc.noDataStack.isHidden = false diff --git a/WOKA/Theme/Base.lproj/Theme.storyboard b/WOKA/Theme/Base.lproj/Theme.storyboard index d7f85fa..59f0c87 100644 --- a/WOKA/Theme/Base.lproj/Theme.storyboard +++ b/WOKA/Theme/Base.lproj/Theme.storyboard @@ -415,7 +415,7 @@ -