- 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
This commit is contained in:
@@ -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 = "<group>"; };
|
||||
5272FCE22BDFDB05000ECB1D /* UserDetailsRegisterVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDetailsRegisterVC.swift; sourceTree = "<group>"; };
|
||||
5272FCE42BDFDC8C000ECB1D /* UserDetailsRegisterVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDetailsRegisterVM.swift; sourceTree = "<group>"; };
|
||||
5276865D2C8879FD001A5496 /* AdClicksImpressions+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AdClicksImpressions+CoreDataClass.swift"; sourceTree = "<group>"; };
|
||||
5276865E2C8879FD001A5496 /* AdClicksImpressions+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AdClicksImpressions+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
||||
527A2BC52C576EAF0080DF9B /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
|
||||
527A2BC72C5777360080DF9B /* VerifyAddressPincodeVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerifyAddressPincodeVC.swift; sourceTree = "<group>"; };
|
||||
527A2BC92C57776A0080DF9B /* AddNewAddressVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddNewAddressVC.swift; sourceTree = "<group>"; };
|
||||
@@ -629,6 +634,7 @@
|
||||
52CA28F92BE119F500708B49 /* UserIntrestVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIntrestVC.swift; sourceTree = "<group>"; };
|
||||
52CA28FB2BE11A0400708B49 /* UserIntrestVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIntrestVM.swift; sourceTree = "<group>"; };
|
||||
52CC38C22BDF812F00B74C3E /* LocalisedElements.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalisedElements.swift; sourceTree = "<group>"; };
|
||||
52CC4A732C883B3F001BE47C /* AdsDM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdsDM.swift; sourceTree = "<group>"; };
|
||||
52CC85532C5BABD40084030E /* WokaFMVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WokaFMVM.swift; sourceTree = "<group>"; };
|
||||
52D23F102C465E6F003E743A /* LogoutPopupVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogoutPopupVC.swift; sourceTree = "<group>"; };
|
||||
52D2F3D72C24043D009E52FF /* ShimmerEffectView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShimmerEffectView.swift; sourceTree = "<group>"; };
|
||||
@@ -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 = "<group>";
|
||||
@@ -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 */,
|
||||
|
||||
15
WOKA/AdClicksImpressions+CoreDataClass.swift
Normal file
15
WOKA/AdClicksImpressions+CoreDataClass.swift
Normal file
@@ -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 {
|
||||
|
||||
}
|
||||
27
WOKA/AdClicksImpressions+CoreDataProperties.swift
Normal file
27
WOKA/AdClicksImpressions+CoreDataProperties.swift
Normal file
@@ -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<AdClicksImpressions> {
|
||||
return NSFetchRequest<AdClicksImpressions>(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 {
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -225,8 +225,10 @@
|
||||
<outlet property="audioListingTableView" destination="2hg-bQ-s8S" id="zNi-4V-7ZX"/>
|
||||
<outlet property="continueWatchingCV" destination="GjK-nD-NIP" id="noB-jL-jX9"/>
|
||||
<outlet property="continueWatchingStack" destination="wjN-Eq-Uv8" id="K3b-KD-IhI"/>
|
||||
<outlet property="headerBtn" destination="X2b-oH-h8S" id="BsM-b2-aoJ"/>
|
||||
<outlet property="headerHeight" destination="bLW-xt-Ji5" id="ifD-sE-vZI"/>
|
||||
<outlet property="headerImage" destination="upA-oa-YmU" id="5nk-X3-Ik1"/>
|
||||
<outlet property="headerTitleHeight" destination="vuS-va-hGV" id="DvS-Rf-KjO"/>
|
||||
<outlet property="headerTitleLabel" destination="gVU-VB-fhU" id="IdJ-vA-fbU"/>
|
||||
<outlet property="headerView" destination="Y14-44-gYV" id="iEI-3T-DaP"/>
|
||||
<outlet property="headerViewTopConstraint" destination="1nk-Sb-8DA" id="0WC-Ao-ddY"/>
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}
|
||||
|
||||
|
||||
@@ -192,8 +192,10 @@
|
||||
<connections>
|
||||
<outlet property="gamesListingTableView" destination="pP6-WY-FP2" id="mWN-yu-zs1"/>
|
||||
<outlet property="gamesLoadingView" destination="mTn-30-lIq" id="5bF-uk-ObF"/>
|
||||
<outlet property="headerBtn" destination="2MA-Jr-TEh" id="lJ4-lX-e0t"/>
|
||||
<outlet property="headerHeight" destination="eU7-Gn-MJi" id="nBh-iw-8tI"/>
|
||||
<outlet property="headerImage" destination="Kgv-cB-NPV" id="HPo-R5-rj0"/>
|
||||
<outlet property="headerTitleHeight" destination="RBd-ac-t4j" id="BYz-Id-Zdc"/>
|
||||
<outlet property="headerTitleLabel" destination="7BL-Zy-PFm" id="kro-hg-bg7"/>
|
||||
<outlet property="headerView" destination="mer-q0-6Vp" id="Ni3-qe-8Ud"/>
|
||||
<outlet property="loadMoreActivityIndicator" destination="ulX-KY-9er" id="jGf-y1-HQw"/>
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -233,10 +233,12 @@
|
||||
<connections>
|
||||
<outlet property="continueWatchingCV" destination="Dty-MN-L9A" id="A3d-Vy-ObE"/>
|
||||
<outlet property="continueWatchingStack" destination="CKh-Ui-Z3R" id="LPT-Y3-630"/>
|
||||
<outlet property="headerBtn" destination="gwc-TP-cJR" id="hJG-tY-LIQ"/>
|
||||
<outlet property="headerHeight" destination="bn9-gt-j6P" id="ZJh-vu-Mfq"/>
|
||||
<outlet property="headerImage" destination="uTJ-KB-jeA" id="z8L-VL-5Ay"/>
|
||||
<outlet property="headerTitleLabel" destination="fQH-gr-lSI" id="vjR-Yu-eZO"/>
|
||||
<outlet property="headerView" destination="V10-F3-AfA" id="gZb-F6-pQ2"/>
|
||||
<outlet property="headerViewLabelHeight" destination="Dm6-9O-x7v" id="chh-we-0BP"/>
|
||||
<outlet property="karaokeListingTableView" destination="haV-Gw-hD2" id="1En-mN-yVg"/>
|
||||
<outlet property="loadMoreActivityIndicator" destination="OhD-ec-2sW" id="yfU-R6-UbS"/>
|
||||
<outlet property="loadMoreBtn" destination="ims-Sc-C3R" id="WEX-0M-lBp"/>
|
||||
|
||||
@@ -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()
|
||||
|
||||
37
WOKA/Main/AuthFunc/AdsDM.swift
Normal file
37
WOKA/Main/AuthFunc/AdsDM.swift
Normal file
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<BaseResponseModel<AdsDM>, 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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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<NSFetchRequestResult> = 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<NSManagedObject>(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<NSFetchRequestResult> = 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<NSFetchRequestResult> = 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -415,7 +415,7 @@
|
||||
<constraint firstItem="GGC-rX-Pyw" firstAttribute="centerY" secondItem="feU-AA-gLO" secondAttribute="centerY" constant="30" id="vSh-CJ-Awg"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="HomeTestBanner" translatesAutoresizingMaskIntoConstraints="NO" id="0qL-H2-cMA">
|
||||
<imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="0qL-H2-cMA">
|
||||
<rect key="frame" x="304" y="742" width="100" height="100"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
@@ -1388,7 +1388,6 @@
|
||||
<image name="Games" width="164" height="130.5"/>
|
||||
<image name="HomeGrassDay" width="570.66668701171875" height="641.33331298828125"/>
|
||||
<image name="HomeIcon" width="26.5" height="26.5"/>
|
||||
<image name="HomeTestBanner" width="85.333335876464844" height="85.333335876464844"/>
|
||||
<image name="Karaoke" width="172" height="137"/>
|
||||
<image name="LiveHindi" width="326.66665649414062" height="176.66667175292969"/>
|
||||
<image name="LiveTV" width="172" height="122.5"/>
|
||||
|
||||
@@ -73,12 +73,17 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate {
|
||||
if #available(iOS 16.0, *) {
|
||||
// Code for iOS 15.0 and above
|
||||
print("Running on iOS 15.0 or later")
|
||||
appDelegate.deviceOrientation = .landscapeRight
|
||||
let value = UIInterfaceOrientation.landscapeRight.rawValue
|
||||
UIDevice.current.setValue(value, forKey: "orientation")
|
||||
DispatchQueue.main.async {
|
||||
appDelegate.deviceOrientation = .landscapeRight
|
||||
let value = UIInterfaceOrientation.landscapeRight.rawValue
|
||||
UIDevice.current.setValue(value, forKey: "orientation")
|
||||
}
|
||||
} else {
|
||||
// Fallback code for earlier iOS versions
|
||||
rotateView(to: .pi / 2) // Example: 90 degrees rotation
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self else{return}
|
||||
rotateView(to: .pi / 2) // Example: 90 degrees rotation
|
||||
}
|
||||
print("Running on a version earlier than iOS 15.0")
|
||||
}
|
||||
|
||||
@@ -409,13 +414,17 @@ extension PlayerVC {
|
||||
|
||||
if #available(iOS 16.0, *) {
|
||||
// Code for iOS 16.0 and above
|
||||
appDelegate.deviceOrientation = .portrait
|
||||
let value = UIInterfaceOrientation.portrait.rawValue
|
||||
UIDevice.current.setValue(value, forKey: "orientation")
|
||||
UIViewController.attemptRotationToDeviceOrientation()
|
||||
DispatchQueue.main.async {
|
||||
appDelegate.deviceOrientation = .portrait
|
||||
let value = UIInterfaceOrientation.portrait.rawValue
|
||||
UIDevice.current.setValue(value, forKey: "orientation")
|
||||
UIViewController.attemptRotationToDeviceOrientation()
|
||||
}
|
||||
} else {
|
||||
// Fallback code for earlier iOS versions
|
||||
self.dismiss(animated: true)
|
||||
DispatchQueue.main.async {
|
||||
self.dismiss(animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -55,6 +55,8 @@ class ThemeOneVC: UIViewController {
|
||||
NotificationCenter.default.removeObserver(self, name: UIApplication.willEnterForegroundNotification, object: nil)
|
||||
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: K.NotificationCenterReloads.reloadTheme), object: nil)
|
||||
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: K.NotificationCenterReloads.themeOnePush), object: nil)
|
||||
NotificationCenter.default.removeObserver(self, name: .languageDidChange, object: nil)
|
||||
|
||||
// NotificationCenter.default.removeObserver(self, name: NSNotification.Name.connectivityStatus, object: nil)
|
||||
if let playerItem = vm.playerItem{
|
||||
playerItem.removeObserver(self, forKeyPath: "status")
|
||||
@@ -80,6 +82,7 @@ class ThemeOneVC: UIViewController {
|
||||
MyListDataTemp.shareInstance.favListingData = FavouriteListingDM.ResultData(totalRecords: nil, showData: FavouriteListingDM.ResultData.ShowData(hindi: [],english: []),videoData: [],gameData: [],singKaraokeData: [],audioData: [])
|
||||
}
|
||||
vm.setupAvPlayer()
|
||||
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
@@ -106,6 +109,16 @@ class ThemeOneVC: UIViewController {
|
||||
if let player = vm.avPlayer{
|
||||
player.play()
|
||||
}
|
||||
|
||||
/*
|
||||
Check if ads is there to map impressions
|
||||
*/
|
||||
if let adsData = AuthFunc.shareInstance.adsData{
|
||||
// check if ads data contains ad for webseries
|
||||
if let themeOneAd = adsData.result?.filter({$0.forPage == AdsEnum.themeOne.rawValue}).first, let adID = themeOneAd.id{
|
||||
PersistentStorage.shared.addAdsCount(adID: adID ,impressions: 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override func viewDidLayoutSubviews() {
|
||||
@@ -139,6 +152,8 @@ class ThemeOneVC: UIViewController {
|
||||
self.navigationController?.pushViewController(vcPush, animated: true)
|
||||
|
||||
PersistentStorage.shared.sendDataToServer()
|
||||
|
||||
PersistentStorage.shared.sendAdsData()
|
||||
}
|
||||
|
||||
@IBAction func radioBtnTapped(_ sender: UIButton) {
|
||||
|
||||
@@ -119,17 +119,18 @@ class PlayerVM{
|
||||
}
|
||||
updateClicks()
|
||||
|
||||
if #available(iOS 16.0, *) {
|
||||
// Code for iOS 15.0 and above
|
||||
appDelegate.deviceOrientation = .portrait
|
||||
let value = UIInterfaceOrientation.portrait.rawValue
|
||||
UIDevice.current.setValue(value, forKey: "orientation")
|
||||
UIViewController.attemptRotationToDeviceOrientation()
|
||||
} else {
|
||||
// Fallback code for earlier iOS versions
|
||||
self.vc.dismiss(animated: true)
|
||||
DispatchQueue.main.async {
|
||||
if #available(iOS 16.0, *) {
|
||||
// Code for iOS 15.0 and above
|
||||
appDelegate.deviceOrientation = .portrait
|
||||
let value = UIInterfaceOrientation.portrait.rawValue
|
||||
UIDevice.current.setValue(value, forKey: "orientation")
|
||||
UIViewController.attemptRotationToDeviceOrientation()
|
||||
} else {
|
||||
// Fallback code for earlier iOS versions
|
||||
self.vc.dismiss(animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func updateClicks(){
|
||||
@@ -167,11 +168,13 @@ class PlayerVM{
|
||||
} else {
|
||||
print("Device is in landscape mode")
|
||||
if vc.isFullScreenBtn{
|
||||
appDelegate.deviceOrientation = .portrait
|
||||
|
||||
let value = UIInterfaceOrientation.portrait.rawValue
|
||||
UIDevice.current.setValue(value, forKey: "orientation")
|
||||
UIViewController.attemptRotationToDeviceOrientation()
|
||||
DispatchQueue.main.async {
|
||||
appDelegate.deviceOrientation = .portrait
|
||||
|
||||
let value = UIInterfaceOrientation.portrait.rawValue
|
||||
UIDevice.current.setValue(value, forKey: "orientation")
|
||||
UIViewController.attemptRotationToDeviceOrientation()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,9 +48,16 @@ class ThemeOneVM{
|
||||
UIView.animate(withDuration: 0.7, delay: 0, options: [], animations: {
|
||||
self.vc.allIconView.transform = CGAffineTransform.identity // Reset the transform to original size
|
||||
}, completion: {_ in
|
||||
self.vc.adBanner.isHidden = false
|
||||
})
|
||||
}
|
||||
|
||||
if let adsData = AuthFunc.shareInstance.adsData{
|
||||
// check if ads data contains ad for webseries
|
||||
if let themeOneAd = adsData.result?.filter({$0.forPage == AdsEnum.themeOne.rawValue}).first, let bannerImage = themeOneAd.bannerImage{
|
||||
vc.adBanner.imageURL(bannerImage, color: .textDarkBlue)
|
||||
vc.adBanner.isHidden = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func handleNotificationCenter(){
|
||||
@@ -60,9 +67,14 @@ class ThemeOneVM{
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(self.reloadTheme), name: NSNotification.Name(rawValue: K.NotificationCenterReloads.reloadTheme), object: nil)
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(handleRouteChange(_:)), name: AVAudioSession.routeChangeNotification, object: nil)
|
||||
// NotificationCenter.default.addObserver(self, selector: #selector(showOfflineDeviceUI(notification:)), name: NSNotification.Name.connectivityStatus, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(languageDidChange), name: .languageDidChange, object: nil)
|
||||
|
||||
// NotificationCenter.default.addObserver(self, selector: #selector(showOfflineDeviceUI(notification:)), name: NSNotification.Name.connectivityStatus, object: nil)
|
||||
}
|
||||
|
||||
@objc private func languageDidChange() {
|
||||
print("Language Change")
|
||||
}
|
||||
// @objc func showOfflineDeviceUI(notification: Notification) {
|
||||
// if NetworkMonitor.shared.isConnected {
|
||||
// NetworkMonitor.shared.stopMonitoring()
|
||||
@@ -275,11 +287,18 @@ class ThemeOneVM{
|
||||
*/
|
||||
|
||||
vc.adBanner.addTapGesture {
|
||||
ViewButtonAnimation.sharedInstance.btnTapped(in: self.vc, view: self.vc.adBanner) { [weak self] in
|
||||
guard let self else{return}
|
||||
|
||||
ViewButtonAnimation.sharedInstance.btnTapped(in: self.vc, view: self.vc.adBanner) {
|
||||
//check url from api
|
||||
if let url = URL(string: "https://miniklub.in/?utm_source=Kids+video+channel&utm_medium=banner&utm_campaign=Trial&utm_id=Woka"), UIApplication.shared.canOpenURL(url) {
|
||||
UIApplication.shared.open(url)
|
||||
if let adsData = AuthFunc.shareInstance.adsData{
|
||||
// check if ads data contains ad for webseries
|
||||
if let themeOneAd = adsData.result?.filter({$0.forPage == AdsEnum.themeOne.rawValue}).first, let adLink = themeOneAd.adLink, let adID = themeOneAd.id{
|
||||
PersistentStorage.shared.addAdsCount(adID: adID,clicks: 1)
|
||||
|
||||
if let url = URL(string: adLink), UIApplication.shared.canOpenURL(url) {
|
||||
UIApplication.shared.open(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -651,16 +670,4 @@ class ThemeOneVM{
|
||||
// }
|
||||
//}
|
||||
|
||||
// MARK: - StaticURLs
|
||||
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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="22758" systemVersion="23F79" minimumToolsVersion="Automatic" sourceLanguage="Swift" usedWithSwiftData="YES" userDefinedModelVersionIdentifier="">
|
||||
<entity name="AdClicksImpressions" representedClassName="AdClicksImpressions" syncable="YES">
|
||||
<attribute name="ad_id" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="no_of_click" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="no_of_impression" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
</entity>
|
||||
<entity name="UserClicks" representedClassName="UserClicks" syncable="YES">
|
||||
<attribute name="category_id" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="click_counts" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
|
||||
@@ -90,6 +90,16 @@ class WebSeriesVC: UIViewController {
|
||||
}else{
|
||||
K.GVar.reloadContinueWebSeries = false
|
||||
}
|
||||
|
||||
/*
|
||||
Check if ads is there to map impressions
|
||||
*/
|
||||
if let adsData = AuthFunc.shareInstance.adsData{
|
||||
// check if ads data contains ad for webseries
|
||||
if let webSeriesAd = adsData.result?.filter({$0.forPage == AdsEnum.web_series.rawValue}).first, let adID = webSeriesAd.id{
|
||||
PersistentStorage.shared.addAdsCount(adID: adID ,impressions: 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override func viewDidLayoutSubviews() {
|
||||
@@ -99,6 +109,19 @@ class WebSeriesVC: UIViewController {
|
||||
|
||||
// MARK: - Tap Handler
|
||||
@IBAction func playTrailer(_ sender: LocalisedElementsButton) {
|
||||
|
||||
//If its ads then nav user to webview
|
||||
if let adsData = AuthFunc.shareInstance.adsData{
|
||||
// check if ads data contains ad for webseries
|
||||
if let webSeriesAd = adsData.result?.filter({$0.forPage == AdsEnum.web_series.rawValue}).first, let adLink = webSeriesAd.adLink,let adID = webSeriesAd.id{
|
||||
PersistentStorage.shared.addAdsCount(adID: adID ,clicks: 1)
|
||||
if let url = URL(string: adLink), UIApplication.shared.canOpenURL(url) {
|
||||
UIApplication.shared.open(url)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
let item = JwPlayerItemCreate(url: APIEndPoints.StaticURLs.masilaUrl, poster: nil, titles: "Masila")
|
||||
JWPlayerManager.shared.presentPlayer(from: self, playerItems: [item], contentType: .trailer, videoIDs: [0])
|
||||
PersistentStorage.shared.addTrailerCount()
|
||||
@@ -405,7 +428,6 @@ extension WebSeriesVC: UIScrollViewDelegate {
|
||||
|
||||
// Define the height range for the header view
|
||||
let minHeaderHeight: CGFloat = 0.0 // Height at which the header becomes invisible
|
||||
// let maxHeaderHeight: CGFloat = self.headerView.frame.height // Maximum height when fully visible
|
||||
|
||||
// Calculate the new height for the header view based on the scroll position
|
||||
let newHeaderHeight: CGFloat
|
||||
@@ -424,16 +446,6 @@ extension WebSeriesVC: UIScrollViewDelegate {
|
||||
UIView.animate(withDuration: 0.3) {
|
||||
self.view.layoutIfNeeded()
|
||||
}
|
||||
|
||||
// if headerHeight.constant == maxHeaderHeight {
|
||||
// UIView.transition(with: headerViewImage, duration: 0.3, options: .transitionCrossDissolve, animations: {
|
||||
// self.headerViewImage.contentMode = .scaleToFill
|
||||
// }, completion: nil)
|
||||
// } else {
|
||||
// UIView.transition(with: headerViewImage, duration: 0.3, options: .transitionCrossDissolve, animations: {
|
||||
// self.headerViewImage.contentMode = .scaleAspectFill
|
||||
// }, completion: nil)
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,15 +31,16 @@ class WebSeriesVM{
|
||||
func initView(){
|
||||
|
||||
// let heightMultiplier: CGFloat = 0.257511
|
||||
let heightMultiplier: CGFloat = 0.29
|
||||
// let heightMultiplier: CGFloat = 0.29
|
||||
|
||||
// Get the current screen height
|
||||
let currentScreenHeight = UIScreen.main.bounds.height
|
||||
// let currentScreenHeight = UIScreen.main.bounds.height
|
||||
|
||||
// Calculate the new view height based on the multiplier
|
||||
// maxHeaderHeight = currentScreenHeight * heightMultiplier
|
||||
maxHeaderHeight = UIScreen.main.bounds.width * 0.55
|
||||
|
||||
//Set banner height
|
||||
maxHeaderHeight = UIScreen.main.bounds.width * 0.55
|
||||
vc.headerHeight.constant = maxHeaderHeight
|
||||
|
||||
setupCell()
|
||||
@@ -67,14 +68,16 @@ class WebSeriesVM{
|
||||
/*
|
||||
MAke logic for ads
|
||||
*/
|
||||
if 1 == 1{
|
||||
vc.headerViewImage.image = UIImage(named: "KaraokeTestBanner")
|
||||
vc.headerBtn.setTitle("", for: .normal)
|
||||
vc.headerViewLabel.text = ""
|
||||
vc.headerViewLabelHeight.constant = 10
|
||||
vc.headerBtn.backgroundColor = .clear
|
||||
vc.headerBtn.setImage(UIImage(named: "ButtonTestBanner"), for: .normal)
|
||||
// vc.headerViewLabel.isHidden = true
|
||||
if let adsData = AuthFunc.shareInstance.adsData{
|
||||
// check if ads data contains ad for webseries
|
||||
if let webSeriesAd = adsData.result?.filter({$0.forPage == AdsEnum.web_series.rawValue}).first, let bannerImage = webSeriesAd.bannerImage, let buttonImage = webSeriesAd.buttonImage{
|
||||
vc.headerViewImage.imageURL(bannerImage, color: .white)
|
||||
vc.headerBtn.setTitle("", for: .normal)
|
||||
vc.headerViewLabel.text = ""
|
||||
vc.headerViewLabelHeight.constant = 10
|
||||
vc.headerBtn.backgroundColor = .clear
|
||||
vc.headerBtn.sd_setBackgroundImage(with: URL(string:buttonImage), for: .normal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bTO-Ql-tyN" customClass="ShimmerEffectView" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="59" width="430" height="240"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="KaraokeTestBanner" translatesAutoresizingMaskIntoConstraints="NO" id="wnB-dE-0v3">
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="MasilaComingSoon" translatesAutoresizingMaskIntoConstraints="NO" id="wnB-dE-0v3">
|
||||
<rect key="frame" x="0.0" y="0.0" width="430" height="240"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</imageView>
|
||||
@@ -476,7 +476,7 @@
|
||||
<rect key="frame" x="377.66666666666669" y="0.0" width="32.333333333333314" height="49"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="hand.thumbsup.fill" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="eng-oC-d9H">
|
||||
<rect key="frame" x="0.0" y="0.50000000000000178" width="20" height="47.999999999999986"/>
|
||||
<rect key="frame" x="0.0" y="0.66666666666666785" width="20" height="47.666666666666671"/>
|
||||
<color key="tintColor" red="0.035294117649999998" green="0.0" blue="0.36470588240000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="0" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Egv-Cu-aPK">
|
||||
@@ -530,7 +530,7 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="40" height="50"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" image="heart" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="QkS-fP-ADo">
|
||||
<rect key="frame" x="5" y="1.5000000000000018" width="30" height="33.5"/>
|
||||
<rect key="frame" x="5" y="2" width="30" height="33"/>
|
||||
<color key="tintColor" name="ImageDarkBlue"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="30" id="MvO-j1-tEk"/>
|
||||
@@ -614,7 +614,7 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="40" height="50"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" image="hand.thumbsup" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="f9M-ON-9gL">
|
||||
<rect key="frame" x="7.6666666666666856" y="-0.5" width="25" height="36.5"/>
|
||||
<rect key="frame" x="7.6666666666666856" y="-0.33333333333333215" width="25" height="36"/>
|
||||
<color key="tintColor" name="ImageDarkBlue"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="25" id="UAK-v9-EKA"/>
|
||||
@@ -1244,7 +1244,7 @@
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="CloseIconEmpty" width="30" height="30"/>
|
||||
<image name="KaraokeTestBanner" width="266.66665649414062" height="146.66667175292969"/>
|
||||
<image name="MasilaComingSoon" width="200" height="100"/>
|
||||
<image name="PlayButtonSmall" width="28.333333969116211" height="28.333333969116211"/>
|
||||
<image name="ShareImage" width="18" height="18"/>
|
||||
<image name="SupportBottomArrow" width="16.333333969116211" height="16.333333969116211"/>
|
||||
|
||||
Reference in New Issue
Block a user