diff --git a/WOKA.xcodeproj/project.pbxproj b/WOKA.xcodeproj/project.pbxproj index 4f712a3..66e3abe 100644 --- a/WOKA.xcodeproj/project.pbxproj +++ b/WOKA.xcodeproj/project.pbxproj @@ -19,7 +19,6 @@ 520CE6AF2C74999200974228 /* AppUpdateDM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 520CE6AE2C74999200974228 /* AppUpdateDM.swift */; }; 520CE6B12C74BB9D00974228 /* AppUpdateVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 520CE6B02C74BB9D00974228 /* AppUpdateVC.swift */; }; 5219C2C22C086D9C00A1DF4D /* DataTypeConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5219C2C12C086D9B00A1DF4D /* DataTypeConversion.swift */; }; - 521CB1002C493DB80085BDF8 /* JWPlayerKit in Frameworks */ = {isa = PBXBuildFile; productRef = 521CB0FF2C493DB80085BDF8 /* JWPlayerKit */; }; 522242662BFC74380085C632 /* MyListVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522242632BFC74380085C632 /* MyListVC.swift */; }; 522242682BFC74380085C632 /* TabBarVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522242652BFC74380085C632 /* TabBarVC.swift */; }; 5222426A2BFC7AFC0085C632 /* SideMenuVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522242692BFC7AFC0085C632 /* SideMenuVC.swift */; }; @@ -90,6 +89,7 @@ 52663FF72BDFACF60001D8CE /* ShadowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52663FF62BDFACF60001D8CE /* ShadowView.swift */; }; 52663FF92BDFAF110001D8CE /* EmailVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52663FF82BDFAF110001D8CE /* EmailVM.swift */; }; 52663FFB2BDFB1700001D8CE /* TextFieldShadow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52663FFA2BDFB1700001D8CE /* TextFieldShadow.swift */; }; + 5267659B2C9C5F8900CF2271 /* JWPlayerKit in Frameworks */ = {isa = PBXBuildFile; productRef = 5267659A2C9C5F8900CF2271 /* JWPlayerKit */; }; 526A436F2C36A97400AE148F /* Games.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 526A436E2C36A97400AE148F /* Games.storyboard */; }; 526A43752C36AA4A00AE148F /* GamesListVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 526A43742C36AA4A00AE148F /* GamesListVC.swift */; }; 5272FCE32BDFDB05000ECB1D /* UserDetailsRegisterVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5272FCE22BDFDB05000ECB1D /* UserDetailsRegisterVC.swift */; }; @@ -772,13 +772,13 @@ 4469E533EC95AC428FE50FB2 /* Pods_WOKA.framework in Frameworks */, 52C83E3F2C493FD700F27563 /* RSKPlaceholderTextView in Frameworks */, 9CF6980B2C89A324006007EF /* Lottie in Frameworks */, + 5267659B2C9C5F8900CF2271 /* JWPlayerKit in Frameworks */, 9CBA530C2C89A2680046735C /* FirebaseAnalytics in Frameworks */, 9CF6980F2C8AFFBF006007EF /* SDWebImage in Frameworks */, 9CBA530E2C89A2680046735C /* FirebaseCrashlytics in Frameworks */, 528F26F02C6B7BD1003E4D99 /* OneSignalFramework in Frameworks */, 528F26F22C6B7BD1003E4D99 /* OneSignalInAppMessages in Frameworks */, 9CBA53102C89A2680046735C /* FirebasePerformance in Frameworks */, - 521CB1002C493DB80085BDF8 /* JWPlayerKit in Frameworks */, 5282DB292C92D73B00465BA1 /* GoogleInteractiveMediaAds in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2042,7 +2042,6 @@ ); name = WOKA; packageProductDependencies = ( - 521CB0FF2C493DB80085BDF8 /* JWPlayerKit */, 52C83E3E2C493FD700F27563 /* RSKPlaceholderTextView */, 528F26EF2C6B7BD1003E4D99 /* OneSignalFramework */, 528F26F12C6B7BD1003E4D99 /* OneSignalInAppMessages */, @@ -2052,6 +2051,7 @@ 9CF6980A2C89A324006007EF /* Lottie */, 9CF6980E2C8AFFBF006007EF /* SDWebImage */, 5282DB282C92D73B00465BA1 /* GoogleInteractiveMediaAds */, + 5267659A2C9C5F8900CF2271 /* JWPlayerKit */, ); productName = WOKA; productReference = 523ED25A2BDA2BC700CFED02 /* WOKA.app */; @@ -2150,13 +2150,13 @@ ); mainGroup = 523ED2512BDA2BC700CFED02; packageReferences = ( - 521CB0FE2C493DB80085BDF8 /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */, 52C83E3D2C493FD700F27563 /* XCRemoteSwiftPackageReference "RSKPlaceholderTextView" */, 528F26EC2C6B7BD1003E4D99 /* XCRemoteSwiftPackageReference "OneSignal-XCFramework" */, 9CBA530A2C89A2680046735C /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, 9CF698092C89A324006007EF /* XCRemoteSwiftPackageReference "lottie-spm" */, 9CF6980D2C8AFFBF006007EF /* XCRemoteSwiftPackageReference "SDWebImage" */, 5282DB272C92D73B00465BA1 /* XCRemoteSwiftPackageReference "swift-package-manager-google-interactive-media-ads-ios" */, + 526765992C9C5F8900CF2271 /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */, ); productRefGroup = 523ED25B2BDA2BC700CFED02 /* Products */; projectDirPath = ""; @@ -3120,7 +3120,7 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ - 521CB0FE2C493DB80085BDF8 /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */ = { + 526765992C9C5F8900CF2271 /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/jwplayer/JWPlayerKit-package.git"; requirement = { @@ -3179,9 +3179,9 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ - 521CB0FF2C493DB80085BDF8 /* JWPlayerKit */ = { + 5267659A2C9C5F8900CF2271 /* JWPlayerKit */ = { isa = XCSwiftPackageProductDependency; - package = 521CB0FE2C493DB80085BDF8 /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */; + package = 526765992C9C5F8900CF2271 /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */; productName = JWPlayerKit; }; 5282DB282C92D73B00465BA1 /* GoogleInteractiveMediaAds */ = { diff --git a/WOKA/Cart/CartDataCache.swift b/WOKA/Cart/CartDataCache.swift index 531b3a6..9083d38 100644 --- a/WOKA/Cart/CartDataCache.swift +++ b/WOKA/Cart/CartDataCache.swift @@ -101,7 +101,7 @@ class BadgeBarBtn { badgeLabel.text = text button.addShadowAndCorner(radius: button.frame.width / 2, shadowColor: .darkGray, shadowOpacity: 0.5, shadowOffset: CGSize(width: 0, height: 0.8), shadowRadius: 6) - + // Add the badge label to the button if not already added if badgeLabel.superview != button { button.addSubview(badgeLabel) diff --git a/WOKA/Games/Controller/GamesDetailVC.swift b/WOKA/Games/Controller/GamesDetailVC.swift index 0fe9f5c..aa39d4e 100644 --- a/WOKA/Games/Controller/GamesDetailVC.swift +++ b/WOKA/Games/Controller/GamesDetailVC.swift @@ -281,18 +281,38 @@ class GamesDetailVC: UIViewController { } private func setupAds(){ - Task { - do { - interstitial = try await GADInterstitialAd.load( - withAdUnitID: K.GoogleAdIDs.gamesDetailsInterStial, request: GADRequest()) - interstitial?.fullScreenContentDelegate = self - } catch { - if reachability?.isReachable == true{ - setupAds() - } + GADInterstitialAd.load(withAdUnitID: K.GoogleAdIDs.gamesDetailsInterStial, request: GADRequest()) { [weak self] ad, error in + if let error = error { print("Failed to load interstitial ad with error: \(error.localizedDescription)") + + // If internet is reachable, try to load the ad again + if self?.reachability?.isReachable == true { + self?.setupAds() + } + return } + + // Successfully loaded the interstitial ad + self?.interstitial = ad + self?.interstitial?.fullScreenContentDelegate = self + print("Interstitial ad loaded successfully.") } +// Task { +// do { +// interstitial = try await GADInterstitialAd.load( +// withAdUnitID: K.GoogleAdIDs.gamesDetailsInterStial, request: GADRequest()) +// +// GADInterstitialAd.load(withAdUnitID: K.GoogleAdIDs.gamesDetailsInterStial, request: GADRequest()) { ad, error in +// +// } +// interstitial?.fullScreenContentDelegate = self +// } catch { +// if reachability?.isReachable == true{ +// setupAds() +// } +// print("Failed to load interstitial ad with error: \(error.localizedDescription)") +// } +// } } private func navigateToGamesWebView(){ @@ -324,7 +344,7 @@ extension GamesDetailVC : GADFullScreenContentDelegate{ func ad(_ ad: GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) { print("Ad did fail to present full screen content.") } - + /// Tells the delegate that the ad will present full screen content. func adWillPresentFullScreenContent(_ ad: GADFullScreenPresentingAd) { print("Ad will present full screen content.") diff --git a/WOKA/Games/Games.storyboard b/WOKA/Games/Games.storyboard index ce7884f..390f6da 100644 --- a/WOKA/Games/Games.storyboard +++ b/WOKA/Games/Games.storyboard @@ -588,10 +588,10 @@ - + - + @@ -608,8 +608,8 @@ - - + diff --git a/WOKA/Home/Home.storyboard b/WOKA/Home/Home.storyboard index ddc1a84..ff1410f 100644 --- a/WOKA/Home/Home.storyboard +++ b/WOKA/Home/Home.storyboard @@ -1,9 +1,9 @@ - + - + @@ -1657,10 +1657,10 @@ - + - + diff --git a/WOKA/Home/ViewModel/MyListVM.swift b/WOKA/Home/ViewModel/MyListVM.swift index 994295a..80643bd 100644 --- a/WOKA/Home/ViewModel/MyListVM.swift +++ b/WOKA/Home/ViewModel/MyListVM.swift @@ -49,14 +49,17 @@ class MyListVM{ } func startShimmer(load : Bool){ - vc.shimmerView.forEach { shimmer in - if load{ - shimmer.gradientColorOne = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1).cgColor - shimmer.startShimmer() - }else{ - shimmer.stopShimmer() + DispatchQueue.main.async { + self.vc.shimmerView.forEach { shimmer in + if load{ + shimmer.gradientColorOne = #colorLiteral(red: 0.5310008526, green: 0.9853085876, blue: 0.9737406373, alpha: 1) + shimmer.startShimmer() + }else{ + shimmer.stopShimmer() + } } } + vc.shimmerStack.isHidden = !load } diff --git a/WOKA/Karaoke/Controller/JWKaraokePlayerVC.swift b/WOKA/Karaoke/Controller/JWKaraokePlayerVC.swift index b74ac91..b03cf0d 100644 --- a/WOKA/Karaoke/Controller/JWKaraokePlayerVC.swift +++ b/WOKA/Karaoke/Controller/JWKaraokePlayerVC.swift @@ -52,10 +52,20 @@ class JWKaraokePlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate //Disable Picture in Picture playerView.allowsPictureInPicturePlayback = false playerView.captionStyle = .none + + let skinStylingBuilder = JWPlayerSkinBuilder() + .adCueColor(.yellow) + // .buttonsColor(.blue) + // .backgroundColor(.cyan) + + let skinStyling = try? skinStylingBuilder.build() + self.styling = skinStyling + self.setVisibility(.hidden, for: [.fullscreenButton, .pictureInPictureButton, .settingsButton,.languagesButton, .airplayButton]) + self.view.bringSubviewToFront(outerStack) self.view.bringSubviewToFront(backButton) self.view.bringSubviewToFront(adView) - + // Add observers NotificationCenter.default.addObserver(self,selector: #selector(appDidEnterBackground),name: UIApplication.didEnterBackgroundNotification,object: nil) NotificationCenter.default.addObserver(self,selector: #selector(appWillEnterForeground),name: UIApplication.willEnterForegroundNotification,object: nil) @@ -356,7 +366,11 @@ extension JWKaraokePlayerVC { extension JWKaraokePlayerVC : GADBannerViewDelegate{ func bannerViewDidReceiveAd(_ bannerView: GADBannerView) { print("bannerViewDidReceiveAd") + bannerView.alpha = 0 bannerView.backgroundColor = #colorLiteral(red: 0.01960784314, green: 0, blue: 0.2196078431, alpha: 1) + UIView.animate(withDuration: 0.2, animations: { + bannerView.alpha = 1 + }) } func bannerView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: Error) { diff --git a/WOKA/Karaoke/Karaoke.storyboard b/WOKA/Karaoke/Karaoke.storyboard index 456c0a1..86b3056 100644 --- a/WOKA/Karaoke/Karaoke.storyboard +++ b/WOKA/Karaoke/Karaoke.storyboard @@ -1,9 +1,9 @@ - + - + @@ -764,11 +764,8 @@ - + - - - @@ -777,11 +774,12 @@ - + + diff --git a/WOKA/Karaoke/ViewModel/JWKaraokePlayerVM.swift b/WOKA/Karaoke/ViewModel/JWKaraokePlayerVM.swift index 7f61092..0a30bed 100644 --- a/WOKA/Karaoke/ViewModel/JWKaraokePlayerVM.swift +++ b/WOKA/Karaoke/ViewModel/JWKaraokePlayerVM.swift @@ -31,7 +31,10 @@ class JWKaraokePlayerVM{ var headerBannerView = GADBannerView() func initView(){ - AdReusable.sharedInstance.setupBannerAd(bannerView: self.headerBannerView, in: vc.adView, adUnitID: K.GoogleAdIDs.themeTwo, viewController: self.vc) + DispatchQueue.main.asyncAfter(deadline: .now() + 0.8, execute: { [weak self] in + guard let self else{return} + AdReusable.sharedInstance.setupBannerAd(bannerView: self.headerBannerView, in: vc.adView, adUnitID: K.GoogleAdIDs.themeTwo, viewController: self.vc) + }) startTimeStamp = Date() vc.downloadRecordingBtn.isEnabled = false diff --git a/WOKA/Main/JWPlayerManager.swift b/WOKA/Main/JWPlayerManager.swift index d0b33d2..0b44912 100644 --- a/WOKA/Main/JWPlayerManager.swift +++ b/WOKA/Main/JWPlayerManager.swift @@ -54,8 +54,16 @@ class JWPlayerManager { continue } +// let source = try JWVideoSourceBuilder() +// .defaultVideo(true) +// .file(url) +// .label("0") +// .build() + + let item = try JWPlayerItemBuilder() .file(url) +// .videoSources([source]) .title(singleItem.titles ?? "") .posterImage(URL(string: singleItem.poster ?? "")!) .build() diff --git a/WOKA/SideBarNav/ViewModel/MyOrdersVM.swift b/WOKA/SideBarNav/ViewModel/MyOrdersVM.swift index 88645e4..e3e7e65 100644 --- a/WOKA/SideBarNav/ViewModel/MyOrdersVM.swift +++ b/WOKA/SideBarNav/ViewModel/MyOrdersVM.swift @@ -19,6 +19,7 @@ class MyOrdersVM{ let refreshControl = UIRefreshControl() let feedbackGenerator = UIImpactFeedbackGenerator(style: .light) + func initView(){ vc.title = "MY ORDERS".localized(loc: AuthFunc.shareInstance.languageSelected.rawValue) diff --git a/WOKA/Theme/Base.lproj/Theme.storyboard b/WOKA/Theme/Base.lproj/Theme.storyboard index 65544fc..504ccdd 100644 --- a/WOKA/Theme/Base.lproj/Theme.storyboard +++ b/WOKA/Theme/Base.lproj/Theme.storyboard @@ -776,6 +776,7 @@ + @@ -1424,7 +1425,7 @@ - + diff --git a/WOKA/Theme/Controller/MoreVC.swift b/WOKA/Theme/Controller/MoreVC.swift index 013f09a..f8ad982 100644 --- a/WOKA/Theme/Controller/MoreVC.swift +++ b/WOKA/Theme/Controller/MoreVC.swift @@ -21,6 +21,7 @@ class MoreVC: UIViewController { @IBOutlet weak var songRetryStack: UIStackView! @IBOutlet weak var songActivityIndicator: UIActivityIndicatorView! @IBOutlet weak var songRetry: LocalisedElementsButton! + @IBOutlet weak var trailerTask: UIStackView! var vm = MoreVM() var timeObserverToken: Any? @@ -29,14 +30,15 @@ class MoreVC: UIViewController { super.viewDidLoad() vm.vc = self vm.initView() + + NotificationCenter.default.addObserver(self,selector: #selector(appDidEnterBackground),name: UIApplication.didEnterBackgroundNotification,object: nil) + NotificationCenter.default.addObserver(self,selector: #selector(appWillEnterForeground),name: UIApplication.didBecomeActiveNotification,object: nil) } - override func viewWillAppear(_ animated: Bool) { - NotificationCenter.default.post(name: .enableDisableSideBar, object: nil, userInfo: ["type": false]) - } - - override func viewWillDisappear(_ animated: Bool) { + deinit{ NotificationCenter.default.post(name: .enableDisableSideBar, object: nil, userInfo: ["type": true]) + NotificationCenter.default.removeObserver(self,name: UIApplication.didEnterBackgroundNotification, object: nil) + NotificationCenter.default.removeObserver(self,name: UIApplication.didBecomeActiveNotification, object: nil) do { try AVAudioSession.sharedInstance().setActive(false) } catch { @@ -45,13 +47,34 @@ class MoreVC: UIViewController { vm.player?.pause() } + override func viewWillAppear(_ animated: Bool) { + NotificationCenter.default.post(name: .enableDisableSideBar, object: nil, userInfo: ["type": false]) + } + @IBAction func playTrailerBtnTapped(_ sender: LocalisedElementsButton) { PersistentStorage.shared.addTrailerCount() let item = JwPlayerItemCreate(url: APIEndPoints.StaticURLs.masilaUrl, poster: nil, titles: "Masila") JWPlayerManager.shared.presentPlayer(from: self, playerItems: [item], contentType: .trailer, videoIDs: [0]) } + @IBAction func retryBtnTapped(_ sender: LocalisedElementsButton) { } + + // MARK: - App Lifecycle + + @objc func appDidEnterBackground() { + if let currentIndexPlayingSong = vm.currentIndexPlayingSong{ + let song = vm.songData[currentIndexPlayingSong] + vm.setupNowPlayingInfo(songTitle: song.title ?? "WOKA Song") + vm.setupRemoteCommandCenter() + } + + } + + @objc func appWillEnterForeground(){ + vm.stopMPNowPlayin() + } + } // MARK: - TableView DataSource , Delegates @@ -98,60 +121,8 @@ extension MoreVC : TableViewSRC{ guard let cell = tableView.cellForRow(at: indexPath) else { return } addAnimation(cell: cell) { [weak self] in guard let self else{return} - PersistentStorage.shared.addOthersCount() - /* - this will declare if the song is playing or not - */ - if let playingIndex = vm.currentIndexPlayingSong { - if indexPath.row == playingIndex{ // if same row is selected pause the row - print(vm.playerStatus) - switch vm.playerStatus{ - case .play: // if player is playing pause it. - print("Player is playing") - vm.player?.pause() - vm.playerStatus = .pause - tableView.reloadRows(at: [IndexPath(row: vm.currentIndexPlayingSong!, section: 0)], with: .none) - case .pause: - vm.player?.play() - vm.playerStatus = .resume - tableView.reloadRows(at: [IndexPath(row: vm.currentIndexPlayingSong!, section: 0)], with: .none) - case .loading: - print("Player is loading") - case .resume: - print("Player is resume") - default: - break - } - }else{ - /* - this means other cell was playing now stop it and play this new cell - first reload the playing cell and pause the audio - */ - //Reset Old Cell - vm.playerStatus = .stopped - tableView.reloadRows(at: [IndexPath(row: vm.currentIndexPlayingSong!, section: 0)], with: .none) - - //Update new cell - vm.currentIndexPlayingSong = indexPath.row - vm.playerStatus = .loading - currentTimePlayer = 0 - tableView.reloadRows(at: [indexPath], with: .none) - let data = vm.songData[indexPath.row] - startPlaying(song: data, at: indexPath) - print("Other cell playing") - } - }else{ - // if there is no playing audio before - vm.playerStatus = .loading - vm.currentIndexPlayingSong = indexPath.row - currentTimePlayer = 0 - tableView.reloadRows(at: [indexPath], with: .none) - let data = vm.songData[indexPath.row] - startPlaying(song: data, at: indexPath) - print("First Play") - } + vm.handleInlinePlay(indexPath: indexPath.row) } - } func addAnimation(cell : UITableViewCell, completion : @escaping () -> Void){ diff --git a/WOKA/Theme/ViewModel/MoreVM.swift b/WOKA/Theme/ViewModel/MoreVM.swift index 8961928..03b26d1 100644 --- a/WOKA/Theme/ViewModel/MoreVM.swift +++ b/WOKA/Theme/ViewModel/MoreVM.swift @@ -175,8 +175,222 @@ class MoreVM{ } } +// MARK: - Handle Media Player for background + +extension MoreVM{ + + func handleInlinePlay(indexPath : Int){ +// guard let self = self.vc else{return} + PersistentStorage.shared.addOthersCount() + /* + this will declare if the song is playing or not + */ + if let playingIndex = currentIndexPlayingSong { + if indexPath == playingIndex{ // if same row is selected pause the row + print(playerStatus) + switch playerStatus{ + case .play: // if player is playing pause it. + print("Player is playing") + player?.pause() + playerStatus = .pause + vc.songTableView.reloadRows(at: [IndexPath(row: currentIndexPlayingSong!, section: 0)], with: .none) + case .pause: + player?.play() + playerStatus = .resume + vc.songTableView.reloadRows(at: [IndexPath(row: currentIndexPlayingSong!, section: 0)], with: .none) + case .loading: + print("Player is loading") + case .resume: + print("Player is resume") + default: + break + } + }else{ + /* + this means other cell was playing now stop it and play this new cell + first reload the playing cell and pause the audio + */ + //Reset Old Cell + playerStatus = .stopped + vc.songTableView.reloadRows(at: [IndexPath(row: currentIndexPlayingSong!, section: 0)], with: .none) + + //Update new cell + currentIndexPlayingSong = indexPath + playerStatus = .loading + currentTimePlayer = 0 + vc.songTableView.reloadRows(at: [IndexPath(row: indexPath, section: 0)], with: .none) + let data = songData[indexPath] + vc.startPlaying(song: data, at: IndexPath(row: indexPath, section: 0)) + print("Other cell playing") + } + }else{ + // if there is no playing audio before + playerStatus = .loading + currentIndexPlayingSong = indexPath + currentTimePlayer = 0 + vc.songTableView.reloadRows(at: [IndexPath(row: indexPath, section: 0)], with: .none) + let data = songData[indexPath] + vc.startPlaying(song: data, at: IndexPath(row: indexPath, section: 0)) + print("First Play") + } + } + + func stopMPNowPlayin(){ + MPNowPlayingInfoCenter.default().nowPlayingInfo = [:] + UIApplication.shared.endReceivingRemoteControlEvents() + let commandCenter = MPRemoteCommandCenter.shared() + + // Disable play/pause commands + commandCenter.playCommand.removeTarget(nil) + commandCenter.pauseCommand.removeTarget(nil) + } + + func setupNowPlayingInfo(songTitle : String) { + let nowPlayingInfoCenter = MPNowPlayingInfoCenter.default() + var nowPlayingInfo: [String: Any] = [:] + + // Set the media title, artist, and album name + + nowPlayingInfo[MPMediaItemPropertyTitle] = songTitle + nowPlayingInfo[MPMediaItemPropertyArtist] = "WOKA Songs" + nowPlayingInfo[MPMediaItemPropertyAlbumTitle] = "" + nowPlayingInfo[MPNowPlayingInfoPropertyIsLiveStream] = true + + if let originalImage = UIImage(named: "ExploreWoka") { + + let artworkImage = imageWithBackground(color: #colorLiteral(red: 0.4495816827, green: 0.2344398499, blue: 0.8120074868, alpha: 1), originalImage: originalImage) + + let artwork = MPMediaItemArtwork(boundsSize: originalImage.size) { size in + return artworkImage ?? originalImage + } + + nowPlayingInfo[MPMediaItemPropertyArtwork] = artwork + + } + + // Set the duration and current playback position + if let currentItem = player?.currentItem { + nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = currentItem.asset.duration.seconds + nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = player?.currentTime().seconds + nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = player?.rate + } + + // Assign the nowPlayingInfo to the center + nowPlayingInfoCenter.nowPlayingInfo = nowPlayingInfo + +// updateNowPlayingInfo() + } + + func setupRemoteCommandCenter() { + let commandCenter = MPRemoteCommandCenter.shared() + + // Enable play command + commandCenter.playCommand.addTarget { [unowned self] event in + if player?.rate == 0.0 { + player?.play() + return .success + } + return .commandFailed + } + + // Enable pause command + commandCenter.pauseCommand.addTarget { [unowned self] event in + if player?.rate == 1.0 { +// player?.pause() + if let currentIndexPlayingSong{ + handleInlinePlay(indexPath: currentIndexPlayingSong) + } + return .success + } + return .commandFailed + } + + // Enable next and previous track commands if needed +// commandCenter.nextTrackCommand.isEnabled = true +// commandCenter.previousTrackCommand.isEnabled = true +// +// +// if let currentIndexPlayingSong = currentIndexPlayingSong{ +// if currentIndexPlayingSong == 0{ +// commandCenter.previousTrackCommand.isEnabled = false +// } +// +// if currentIndexPlayingSong == songData.count - 1{ +// commandCenter.nextTrackCommand.isEnabled = false +// } +// } +// +// +// // Enable next command +// commandCenter.nextTrackCommand.addTarget { [unowned self] event in +// commandCenter.previousTrackCommand.isEnabled = true +// if let currentIndexPlayingSong = currentIndexPlayingSong{ +// if currentIndexPlayingSong == songData.count - 1{ +// //if the song played is the last index disable the next track +// commandCenter.nextTrackCommand.isEnabled = false +// return .commandFailed +// } +// +// handleInlinePlay(indexPath: currentIndexPlayingSong + 1) +// setupNowPlayingInfo(songTitle: songData[currentIndexPlayingSong + 1].title ?? "WOKA") +// updateNowPlayingInfo() +// return .success +// } +// return .commandFailed +// } +// +// // Enable pause command +// commandCenter.previousTrackCommand.addTarget { [unowned self] event in +// commandCenter.nextTrackCommand.isEnabled = true +// if let currentIndexPlayingSong = currentIndexPlayingSong{ +// if currentIndexPlayingSong == 0{ +// //if the song played is the last index disable the previous track +// commandCenter.previousTrackCommand.isEnabled = false +// return .commandFailed +// } +// +// setupNowPlayingInfo(songTitle: songData[currentIndexPlayingSong - 1].title ?? "WOKA") +// handleInlinePlay(indexPath: currentIndexPlayingSong - 1) +// updateNowPlayingInfo() +// return .success +// } +// return .commandFailed +// } + + } + + func imageWithBackground(color: UIColor, originalImage: UIImage) -> UIImage? { + let size = originalImage.size + UIGraphicsBeginImageContextWithOptions(size, false, originalImage.scale) + let rect = CGRect(origin: CGPoint.zero, size: size) + + // Fill the background with a color + color.setFill() + UIRectFill(rect) + + // Draw the original image on top + originalImage.draw(in: rect) + + // Capture the new image with background + let imageWithBackground = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + return imageWithBackground + } + + func updateNowPlayingInfo() { + if let currentItem = player?.currentItem { + var nowPlayingInfo = MPNowPlayingInfoCenter.default().nowPlayingInfo ?? [:] + nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = player?.currentTime().seconds + nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = player?.rate + MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo + } + } +} + import UIKit +import MediaPlayer extension UIView { diff --git a/WOKA/Theme/ViewModel/ThemeOneVM.swift b/WOKA/Theme/ViewModel/ThemeOneVM.swift index e9d2ddb..c2bca72 100644 --- a/WOKA/Theme/ViewModel/ThemeOneVM.swift +++ b/WOKA/Theme/ViewModel/ThemeOneVM.swift @@ -193,7 +193,7 @@ class ThemeOneVM{ print("App entered background") if let rootViewController = UIApplication.shared.mainKeyWindow?.rootViewController { if let topVC = topVC(in: rootViewController) { - if topVC is HomeVC{ + if topVC is HomeVC || topVC is WokaFMVC{ shouldAnimate = false avPlayer.pause() handleBackground() @@ -211,7 +211,7 @@ class ThemeOneVM{ print("App will enter foreground") if let rootViewController = UIApplication.shared.mainKeyWindow?.rootViewController { if let topVC = topVC(in: rootViewController) { - if topVC is HomeVC{ + if topVC is HomeVC || topVC is WokaFMVC{ shouldAnimate = true DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in guard let self else{return} diff --git a/WOKA/WOKAFM/Controller/WokaFMVC.swift b/WOKA/WOKAFM/Controller/WokaFMVC.swift index 7d9971c..d3c1203 100644 --- a/WOKA/WOKAFM/Controller/WokaFMVC.swift +++ b/WOKA/WOKAFM/Controller/WokaFMVC.swift @@ -31,7 +31,7 @@ class WokaFMVC: UIViewController { vm.player?.pause() NotificationCenter.default.removeObserver(self,name: UIApplication.didEnterBackgroundNotification, object: nil) - NotificationCenter.default.removeObserver(self,name: UIApplication.willEnterForegroundNotification, object: nil) + NotificationCenter.default.removeObserver(self,name: UIApplication.didBecomeActiveNotification, object: nil) // Deactivate the audio session if needed do { @@ -46,7 +46,7 @@ class WokaFMVC: UIViewController { vm.vc = self vm.initView() NotificationCenter.default.addObserver(self,selector: #selector(appDidEnterBackground),name: UIApplication.didEnterBackgroundNotification,object: nil) - NotificationCenter.default.addObserver(self,selector: #selector(appWillEnterForeground),name: UIApplication.willEnterForegroundNotification,object: nil) + NotificationCenter.default.addObserver(self,selector: #selector(appWillEnterForeground),name: UIApplication.didBecomeActiveNotification,object: nil) } // MARK: - App LifeCycle HAndler @@ -65,6 +65,8 @@ class WokaFMVC: UIViewController { } } + + @objc func appWillEnterForeground(){ vm.stopMPNowPlayin() } diff --git a/WOKA/WOKAFM/ViewModel/WokaFMVM.swift b/WOKA/WOKAFM/ViewModel/WokaFMVM.swift index fee97d4..d6b0093 100644 --- a/WOKA/WOKAFM/ViewModel/WokaFMVM.swift +++ b/WOKA/WOKAFM/ViewModel/WokaFMVM.swift @@ -56,7 +56,13 @@ class WokaFMVM{ // MARK: - SetupAd func stopMPNowPlayin(){ - MPNowPlayingInfoCenter.default().nowPlayingInfo = nil + MPNowPlayingInfoCenter.default().nowPlayingInfo = [:] + UIApplication.shared.endReceivingRemoteControlEvents() + let commandCenter = MPRemoteCommandCenter.shared() + + // Disable play/pause commands + commandCenter.playCommand.removeTarget(nil) + commandCenter.pauseCommand.removeTarget(nil) } func setupNowPlayingInfo() { @@ -66,16 +72,21 @@ class WokaFMVM{ // Set the media title, artist, and album name nowPlayingInfo[MPMediaItemPropertyTitle] = "Live FM" nowPlayingInfo[MPMediaItemPropertyArtist] = "WOKA" - nowPlayingInfo[MPMediaItemPropertyAlbumTitle] = "Album Name" - - // Optional: Set the artwork - if let artworkImage = UIImage(named: "WokaLogo") { - let artwork = MPMediaItemArtwork(boundsSize: artworkImage.size) { size in - return artworkImage - } - nowPlayingInfo[MPMediaItemPropertyArtwork] = artwork - } + nowPlayingInfo[MPMediaItemPropertyAlbumTitle] = "" + nowPlayingInfo[MPNowPlayingInfoPropertyIsLiveStream] = true + if let originalImage = UIImage(named: "MasilaCharacter") { + + let artworkImage = imageWithBackground(color: #colorLiteral(red: 0.4495816827, green: 0.2344398499, blue: 0.8120074868, alpha: 1), originalImage: originalImage) + + let artwork = MPMediaItemArtwork(boundsSize: originalImage.size) { size in + return artworkImage ?? originalImage + } + + nowPlayingInfo[MPMediaItemPropertyArtwork] = artwork + + } + // Set the duration and current playback position if let currentItem = player.currentItem { nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = currentItem.asset.duration.seconds @@ -86,7 +97,7 @@ class WokaFMVM{ // Assign the nowPlayingInfo to the center nowPlayingInfoCenter.nowPlayingInfo = nowPlayingInfo } - + func setupRemoteCommandCenter() { let commandCenter = MPRemoteCommandCenter.shared() @@ -113,6 +124,25 @@ class WokaFMVM{ commandCenter.previousTrackCommand.isEnabled = false } + func imageWithBackground(color: UIColor, originalImage: UIImage) -> UIImage? { + let size = originalImage.size + UIGraphicsBeginImageContextWithOptions(size, false, originalImage.scale) + let rect = CGRect(origin: CGPoint.zero, size: size) + + // Fill the background with a color + color.setFill() + UIRectFill(rect) + + // Draw the original image on top + originalImage.draw(in: rect) + + // Capture the new image with background + let imageWithBackground = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + return imageWithBackground + } + func updateNowPlayingInfo() { if let currentItem = player.currentItem { var nowPlayingInfo = MPNowPlayingInfoCenter.default().nowPlayingInfo ?? [:] @@ -122,7 +152,6 @@ class WokaFMVM{ } } - func setGoogleAd(){ /*