// // ThemeOneVC.swift // WOKA // // Created by Bilal on 03/05/2024. // import UIKit import Alamofire import AVFoundation class ThemeOneVC: UIViewController { @IBOutlet weak var gradientView: UIView! @IBOutlet weak var cloud2: UIImageView! @IBOutlet weak var cloud1: UIImageView! @IBOutlet weak var liveTVView: UIView! @IBOutlet weak var liveTvPlayer: UIView! @IBOutlet weak var homeGrass: UIImageView! @IBOutlet weak var nameLabel: UILabel! @IBOutlet weak var welcomeLabel: LocalisedElementsLabel! @IBOutlet weak var HelloLabel: LocalisedElementsLabel! @IBOutlet weak var liveTVIcon: UIView! @IBOutlet weak var notificationBtnn: UIButton! @IBOutlet weak var avatarImage: UIImageView! @IBOutlet weak var webSeriesView: UIView! @IBOutlet weak var audioBooksView: UIView! @IBOutlet var star: [UIImageView]! @IBOutlet weak var moonImage: UIImageView! @IBOutlet weak var moreStack: UIStackView! @IBOutlet weak var bottomArrow: UIImageView! @IBOutlet weak var gamesView: UIView! @IBOutlet weak var karaokeView: UIView! @IBOutlet weak var shopView: UIView! @IBOutlet weak var allIconView: UIView! @IBOutlet weak var liveTVActivityIndicator: UIActivityIndicatorView! var timer: Timer? var vm = ThemeOneVM() weak var delegate: ChildViewControllerDelegate? // MARK: - LifeCycle deinit{ timer?.invalidate() // Removing observers NotificationCenter.default.removeObserver(self, name: UIApplication.didEnterBackgroundNotification, object: nil) 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: NSNotification.Name.connectivityStatus, object: nil) if let playerItem = vm.playerItem{ playerItem.removeObserver(self, forKeyPath: "status") // playerItem.removeObserver(self, forKeyPath: "isPlaybackBufferEmpty") // playerItem.removeObserver(self, forKeyPath: "isPlaybackLikelyToKeepUp") } if let avPlayer = vm.avPlayer { avPlayer.removeObserver(self, forKeyPath: "timeControlStatus") avPlayer.pause() } NotificationCenter.default.removeObserver(self, name: AVAudioSession.routeChangeNotification, object: nil) } override var preferredStatusBarStyle: UIStatusBarStyle { .darkContent } override func viewDidLoad() { super.viewDidLoad() vm.vc = self vm.initView() if MyListDataTemp.shareInstance.favListingData?.showData == nil { MyListDataTemp.shareInstance.favListingData = FavouriteListingDM.ResultData(totalRecords: nil, showData: FavouriteListingDM.ResultData.ShowData(hindi: [],english: []),videoData: [],gameData: [],singKaraokeData: [],audioData: []) } // NetworkMonitor.shared.startMonitoring() // connectedToNetwork() // PersistentStorage.shared.deleteData() // PersistentStorage.shared.retrieveData() vm.setupAvPlayer() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) setNeedsStatusBarAppearanceUpdate() } override func viewWillDisappear(_ animated: Bool) { vm.shouldAnimate = false if let player = vm.avPlayer{ player.pause() } } override func viewDidAppear(_ animated: Bool) { K.GVar.topView = .theme1 vm.shouldAnimate = true DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in guard let self else{return} vm.moveLiveTVView() } if let player = vm.avPlayer{ player.play() } } override func viewDidLayoutSubviews() { if vm.playerLayer != nil{ vm.playerLayer.frame = self.liveTvPlayer.bounds } } // Define a function to customize tab bar item icon size func customizeTabBarItemIconSize() { // Get a reference to the tab bar controller if let tabBarController = self.tabBarController { // Loop through each tab bar item for item in tabBarController.tabBar.items! { // Adjust the image insets to increase the icon size item.imageInsets = UIEdgeInsets(top: 2, left: -5, bottom: -8, right: -5) item.titlePositionAdjustment.vertical = CGFloat(8) } } } @IBAction func barButtonTapped(_ sender: UIButton) { PersistentStorage.shared.addOthersCount() self.sideMenuController?.revealMenu() } @IBAction func notificationBtnTapped(_ sender: UIButton) { PersistentStorage.shared.addOthersCount() let sb = UIStoryboard(name: K.StoryBoard.theme, bundle: nil) let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Home.userNotificationVC) as! UserNotificationVC self.navigationController?.pushViewController(vcPush, animated: true) PersistentStorage.shared.sendDataToServer() } @IBAction func radioBtnTapped(_ sender: UIButton) { PersistentStorage.shared.addRadioCount() let sb = UIStoryboard(name: K.StoryBoard.wokaFM, bundle: nil) let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.WokaFM.wokaFMVC) as! WokaFMVC vcPush.modalPresentationStyle = .overCurrentContext vcPush.modalTransitionStyle = .crossDissolve self.present(vcPush, animated: true) } } // MARK: - Handle Live TV Observer extension ThemeOneVC{ func startMonitoring(){ NetworkReachibility.shared.startMonitoring { [weak self] isConnected in guard let self else{return} switch isConnected{ case true: // if network is connected than stop // when internet is back we have to setup player again NetworkReachibility.shared.stopMonitoring() // vm.avPlayer.play() print("network connection is back") case false: // if there is no internet connection prompt user and show reload icon self.toast(msg: "Lost Connection.", time: 1.4) liveTVActivityIndicator.stopAnimating() } } } func addObservers() { // Observe the player's status vm.playerItem.addObserver(self, forKeyPath: "status", options: [.new, .old], context: nil) // Observe the player's time control status vm.avPlayer.addObserver(self, forKeyPath: "timeControlStatus", options: [.new, .old], context: nil) // Observe buffering status // vm.playerItem.addObserver(self, forKeyPath: "isPlaybackBufferEmpty", options: [.new, .old], context: nil) // vm.playerItem.addObserver(self, forKeyPath: "isPlaybackLikelyToKeepUp", options: [.new, .old], context: nil) } override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?){ //this will oberver if player loads the url or fails if keyPath == "status" { if vm.playerItem.status == .readyToPlay { print("Theme 1 Player is ready to play") vm.avPlayer.play() } else if vm.playerItem.status == .failed { print("Theme 1 Player failed to load") vm.setupAvPlayer() } } //this will give status of buffering, play pause. if keyPath == "timeControlStatus" { if let player = object as? AVPlayer { switch player.timeControlStatus { case .waitingToPlayAtSpecifiedRate: print("Theme 1 Player Buffering...") switch vm.reachability?.isReachable{ case true: break case false: break // NetworkMonitor.shared.startMonitoring() default: break } vm.startStopActivity(isStart: true) case .playing: print("Theme 1 Player Playing") vm.startStopActivity(isStart: false) case .paused: print("Theme 1 Player Paused") // check if app is in background return it if UIApplication.shared.applicationState == .background {return} if let rootViewController = UIApplication.shared.mainKeyWindow?.rootViewController { if let topVC = topVC(in: rootViewController) { if topVC is HomeVC{ vm.avPlayer.play() } else { print("The top view controller is not HomeVC") } } else { print("No top view controller found") } } @unknown default: print("Theme 1 Player Unknown status") } } } // if keyPath == "status" { // if vm.playerItem.status == .readyToPlay { // print("Player is ready to play") // vm.avPlayer.play() // } else if vm.playerItem.status == .failed { // print("Player failed to load") // if !liveTVActivityIndicator.isAnimating{ // liveTVActivityIndicator.startAnimating() // } // } // } else if keyPath == "timeControlStatus" { // switch vm.avPlayer.timeControlStatus { // case .playing: // print("Player is playing") // liveTVActivityIndicator.stopAnimating() // case .paused: // print("Player is paused") // vm.avPlayer.play() // liveTVActivityIndicator.stopAnimating() // case .waitingToPlayAtSpecifiedRate: // print("Player is Buffering 1") // if !(NetworkReachabilityManager()?.isReachable ?? false){ // if !NetworkReachibility.shared.isMonitoring{ // startMonitoring() // } // } // @unknown default: // break // } // } else if keyPath == "isPlaybackBufferEmpty" { // if vm.playerItem.isPlaybackBufferEmpty { // print("Player is buffering 2") // liveTVActivityIndicator.startAnimating() // startMonitoring() // } // } else if keyPath == "isPlaybackLikelyToKeepUp" { // if vm.playerItem.isPlaybackLikelyToKeepUp { // print("Player is likely to keep up with the playback") // } // } } } class NavigationController: UINavigationController { open override var childForStatusBarHidden: UIViewController? { return self.topViewController } open override var childForStatusBarStyle: UIViewController? { return self.topViewController } } extension UINavigationController { func pushWithPopInAnimation(_ viewController: UIViewController, duration: CFTimeInterval = 0.3) { let transition = CATransition() transition.duration = duration transition.type = CATransitionType.push transition.subtype = CATransitionSubtype.fromRight // Customize the animation to look like a "pop-in" transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) self.view.layer.add(transition, forKey: kCATransition) self.pushViewController(viewController, animated: false) } }