Files
Woka_Native_iOS/WOKA/Theme/ViewModel/MoreVM.swift
BilalKhanWDI 7950d1961f - Completed blogs
- Added FM Module
- Made a external View to access around all modules
- Added AV Player to play Radio URL.
- Added Observers to handle play pause buffering.
- Added a activity indicator to show buffer.
- Added reload btn if the player doesn’t gets initialised.
- Handled FM from Explore woka to my list , theme 1 and 2.
- Handled Vol- and Vol+ , if volume goes to max vol+ will be disable and vice versa
2024-08-01 19:35:15 +05:30

236 lines
7.7 KiB
Swift

//
// MoreVM.swift
// WOKA
//
// Created by MacBook Pro on 10/06/24.
//
import UIKit
import AVFoundation
enum PlayerStatus{
case play
case loading
case pause
case resume
case stopped
}
var currentTimePlayer = Int()
var totalTime = Int()
class MoreVM{
weak var vc : MoreVC!
var blogData = [BlogDM.Blog]()
var songData = [SongBlogDM.PaintDatum]()
var player : AVPlayer?
var playerObserver: NSKeyValueObservation?
var playerStatus = PlayerStatus.loading
var currentIndexPlayingSong : Int?
func initView(){
getBLogs()
setupAudioSession()
getSong()
setupCell()
vc.songTableView.showsVerticalScrollIndicator = false
vc.songTableView.showsHorizontalScrollIndicator = false
vc.homeBtn.addTapGesture {
self.vc.dismiss(animated: true)
}
}
func setupAudioSession() {
let session = AVAudioSession.sharedInstance()
do {
try session.setCategory(.playback, mode: .default)
try session.setActive(true)
} catch {
print("Failed to set up audio session")
}
}
func observePlayer() {
playerObserver = self.player?.observe(\.timeControlStatus, options: [.new, .old], changeHandler: { [weak self] player, change in
guard let self = self else { return }
switch player.timeControlStatus {
case .playing:
print("Player is playing OOO")
self.playerStatus = .play
vc.songTableView.reloadRows(at: [IndexPath(row: currentIndexPlayingSong ?? 0, section: 0)], with: .none)
case .paused:
print("Player is paused OOO")
// self.playerStatus = .pause
if self.player?.currentTime() == self.player?.currentItem?.duration {
print("Player finished playing")
self.playerStatus = .stopped
self.vc.songTableView.reloadRows(at: [IndexPath(row: currentIndexPlayingSong!, section: 0)], with: .none)
currentIndexPlayingSong = nil
} else {
print("Player is paused")
self.playerStatus = .pause
}
case .waitingToPlayAtSpecifiedRate:
print("Player is waiting to play at specified rate OOO")
self.playerStatus = .loading
@unknown default:
print("Unknown player status OOO")
}
})
}
func setupCell(){
vc.blogsCollectionView.register(UINib(nibName: K.CellIdentifier.Home.blogsCell, bundle: nil), forCellWithReuseIdentifier: K.CellIdentifier.Home.blogsCell)
vc.blogsCollectionView.delegate = vc.self
vc.blogsCollectionView.dataSource = vc.self
vc.songTableView.register(UINib(nibName: K.CellIdentifier.Home.songListCell, bundle: nil), forCellReuseIdentifier: K.CellIdentifier.Home.songListCell)
vc.songTableView.delegate = vc.self
vc.songTableView.dataSource = vc.self
}
// MARK: - Get BLogs Data
func getBLogs(){
Utilities.startProgressHUD()
NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Home.blogs, method: .get) { [weak self](result : Result<BaseResponseModel<BlogDM>, NetworkManager.APIError>) in
guard let self else{return}
switch result{
case .success(let data):
switch data.success{
case 0:
/*
Error
*/
Utilities.dismissProgressHUD()
vc.toast(msg: data.message ?? "Unrecognised error" , time: 2)
case 1:
Utilities.dismissProgressHUD()
guard let data = data.data?.blogs else{return}
blogData = data
vc.blogsCollectionView.reloadData()
default:
break
}
case .failure(let error):
Utilities.dismissProgressHUD()
vc.toast(msg: error.localizedDescription , time: 2)
}
}
}
func getSong(){
NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Home.song_listing, method: .post) { [weak self](result : Result<BaseResponseModel<SongBlogDM>, NetworkManager.APIError>) in
guard let self else{return}
switch result{
case .success(let data):
switch data.success{
case 0:
/*
Error
*/
Utilities.dismissProgressHUD()
vc.toast(msg: data.message ?? "Unrecognised error" , time: 2)
case 1:
Utilities.dismissProgressHUD()
guard let data = data.data?.paintData else{return}
songData = data
vc.songTableView.reloadData()
break
default:
break
}
case .failure(let error):
Utilities.dismissProgressHUD()
vc.toast(msg: error.localizedDescription , time: 2)
}
}
}
}
import UIKit
extension UIView {
private struct AssociatedKeys {
static var loadingView = "loadingView"
}
private var loadingView: LoadingView? {
get {
return objc_getAssociatedObject(self, AssociatedKeys.loadingView) as? LoadingView
}
set {
objc_setAssociatedObject(self, AssociatedKeys.loadingView, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
func showLoading() {
if loadingView == nil {
let newLoadingView = LoadingView(frame: self.bounds)
newLoadingView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(newLoadingView)
NSLayoutConstraint.activate([
newLoadingView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
newLoadingView.trailingAnchor.constraint(equalTo: self.trailingAnchor),
newLoadingView.topAnchor.constraint(equalTo: self.topAnchor),
newLoadingView.bottomAnchor.constraint(equalTo: self.bottomAnchor)
])
loadingView = newLoadingView
}
loadingView?.startLoading()
}
func hideLoading() {
loadingView?.stopLoading()
}
}
class LoadingView: UIView {
private var activityIndicator: UIActivityIndicatorView!
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setupView()
}
private func setupView() {
self.backgroundColor = .clear
activityIndicator = UIActivityIndicatorView(style: .medium)
activityIndicator.translatesAutoresizingMaskIntoConstraints = false
activityIndicator.color = .white
self.addSubview(activityIndicator)
NSLayoutConstraint.activate([
activityIndicator.centerXAnchor.constraint(equalTo: self.centerXAnchor),
activityIndicator.centerYAnchor.constraint(equalTo: self.centerYAnchor),
activityIndicator.heightAnchor.constraint(equalToConstant: self.frame.height - 10),
activityIndicator.widthAnchor.constraint(equalToConstant: self.frame.width - 10)
])
}
func startLoading() {
activityIndicator.startAnimating()
self.isHidden = false
}
func stopLoading() {
activityIndicator.stopAnimating()
self.isHidden = true
}
}