- made theme 2 banner dynamic, if ad loads then only it will be shown

- made radio ad dynamic, now ad will show up only if ad is received
- added a retry count to fm, it will try 4 times to connect to the server if not then showing the reload btn
- Worked on radio, now when playing in background media player will b shown on Lock Screen, where user can interact with the ongoing streams.
- Woka songs are now controllable from the notification panel
- Fixed shimmer loading issue in my list
- Now loading interstitial ad when the app loads so it will be easy to load it when user goes on gameswebview
- Fixed ad spacing in karaoke player vc.
This commit is contained in:
2024-09-19 19:13:19 +05:30
parent dcbbfc3417
commit 626d7a783a
17 changed files with 380 additions and 116 deletions

View File

@@ -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 */ = {

View File

@@ -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)

View File

@@ -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.")

View File

@@ -588,10 +588,10 @@
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="UBq-Ug-nVj">
<rect key="frame" x="0.0" y="0.0" width="414" height="796"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<subviews>
<wkWebView contentMode="scaleToFill" allowsLinkPreview="NO" translatesAutoresizingMaskIntoConstraints="NO" id="k9t-dv-nhb">
<rect key="frame" x="0.0" y="0.0" width="414" height="794"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="894"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<wkWebViewConfiguration key="configuration" allowsAirPlayForMediaPlayback="NO" allowsPictureInPictureMediaPlayback="NO">
<dataDetectorTypes key="dataDetectorTypes" none="YES"/>
@@ -608,8 +608,8 @@
<constraint firstItem="k9t-dv-nhb" firstAttribute="leading" secondItem="UBq-Ug-nVj" secondAttribute="leading" id="XhR-Si-hmd"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Kme-E0-ysm">
<rect key="frame" x="0.0" y="796" width="414" height="100"/>
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Kme-E0-ysm">
<rect key="frame" x="0.0" y="0.0" width="414" height="100"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
</subviews>

View File

@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="jHz-IY-SVp">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23094" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="jHz-IY-SVp">
<device id="retina6_72" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23084"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
@@ -1657,10 +1657,10 @@
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="systemGreenColor">
<color red="0.20392156862745098" green="0.7803921568627451" blue="0.34901960784313724" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.20392156859999999" green="0.78039215689999997" blue="0.34901960780000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemMintColor">
<color red="0.0" green="0.7803921568627451" blue="0.74509803921568629" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.0" green="0.78039215689999997" blue="0.74509803919999995" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
</resources>
</document>

View File

@@ -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
}

View File

@@ -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) {

View File

@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23094" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23084"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
@@ -764,11 +764,8 @@
</subviews>
</stackView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XDD-DO-5GP">
<rect key="frame" x="5" y="128" width="404" height="140"/>
<rect key="frame" x="5" y="123" width="404" height="120"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="140" id="WCG-7C-BhF"/>
</constraints>
</view>
</subviews>
<viewLayoutGuide key="safeArea" id="fhs-yV-fEZ"/>
@@ -777,11 +774,12 @@
<constraint firstItem="yek-VM-Cus" firstAttribute="centerY" secondItem="fhs-yV-fEZ" secondAttribute="centerY" constant="200" id="0CQ-IK-CSM"/>
<constraint firstItem="yek-VM-Cus" firstAttribute="leading" secondItem="fhs-yV-fEZ" secondAttribute="leading" constant="20" id="0qJ-R4-ZTb"/>
<constraint firstItem="Nuf-TE-5LZ" firstAttribute="top" secondItem="fhs-yV-fEZ" secondAttribute="top" constant="15" id="7jB-UT-Xqq"/>
<constraint firstItem="XDD-DO-5GP" firstAttribute="top" secondItem="Nuf-TE-5LZ" secondAttribute="bottom" constant="20" id="LGq-aG-tZc"/>
<constraint firstItem="XDD-DO-5GP" firstAttribute="top" secondItem="Nuf-TE-5LZ" secondAttribute="bottom" constant="15" id="LGq-aG-tZc"/>
<constraint firstItem="fhs-yV-fEZ" firstAttribute="trailing" secondItem="yek-VM-Cus" secondAttribute="trailing" constant="20" id="Omt-Ig-58p"/>
<constraint firstItem="Nuf-TE-5LZ" firstAttribute="leading" secondItem="fhs-yV-fEZ" secondAttribute="leading" constant="10" id="Tcl-yf-D2V"/>
<constraint firstItem="XDD-DO-5GP" firstAttribute="leading" secondItem="fhs-yV-fEZ" secondAttribute="leading" constant="5" id="U0b-N4-Qqs"/>
<constraint firstItem="fhs-yV-fEZ" firstAttribute="trailing" secondItem="XDD-DO-5GP" secondAttribute="trailing" constant="5" id="rIF-aH-16u"/>
<constraint firstItem="XDD-DO-5GP" firstAttribute="height" secondItem="h1e-2a-Kjb" secondAttribute="height" multiplier="0.133929" id="stT-AO-7RR"/>
</constraints>
</view>
<connections>

View File

@@ -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

View File

@@ -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()

View File

@@ -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)

View File

@@ -776,6 +776,7 @@
<outlet property="songRetry" destination="zAr-x7-tdY" id="0TO-oQ-fEw"/>
<outlet property="songRetryStack" destination="xv5-81-JIV" id="HNO-pe-3Gt"/>
<outlet property="songTableView" destination="31Z-fz-1ec" id="K2B-qg-URW"/>
<outlet property="trailerTask" destination="U0W-18-4oe" id="15h-sx-Ww7"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="kvq-vw-eSu" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
@@ -1424,7 +1425,7 @@
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="systemBrownColor">
<color red="0.63529411759999999" green="0.51764705879999995" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color red="0.63529411764705879" green="0.51764705882352946" blue="0.36862745098039218" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
</resources>
</document>

View File

@@ -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){

View File

@@ -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 {

View File

@@ -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}

View File

@@ -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()
}

View File

@@ -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(){
/*