Merge branch 'main' of ssh://git.zhenbs.com:2222/3-group-ios/Music_Player3

# Conflicts:
#	relax.offline.mp3.music.xcodeproj/project.pbxproj
This commit is contained in:
bluesea 2024-06-05 16:12:09 +08:00
commit a9c62a68f6
12 changed files with 298 additions and 271 deletions

View File

@ -53,7 +53,7 @@
<CommandLineArguments>
<CommandLineArgument
argument = "-FIRDebugEnabled"
isEnabled = "NO">
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
argument = "-FIRDebugDisabled"

View File

@ -39,6 +39,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
switch_lunch()
//
MP_AnalyticsManager.shared.user_launchAction()
// let numbers = [0]
// let _ = numbers[1]
return true
}
func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {

View File

@ -29,70 +29,79 @@ class MP_LunchViewController: UIViewController {
timer.preferredFramesPerSecond = 20
//线
timer.add(to: RunLoop.current, forMode: .common)
//idfa
_ = requestTrackingAuthorization(self)
// MP_AnalyticsManager.shared.getOpenStatus { [weak self] open in
// guard let self = self else {return}
// if open {
// //ip
// MP_NetWorkManager.shared.requestIPInfo { statu in
// if statu == true {
// //b
// print("BLog")
// self.completionBlock = {
// DispatchQueue.main.async {
// [weak self] in
// guard let self = self else {return}
// //
// timer.isPaused = true
// //
// accessAppdelegate.switch_positive()
// }
// }
// }else {
// print("ALog")
// //A
// self.completionBlock = {
// DispatchQueue.main.async {
// [weak self] in
// guard let self = self else {return}
// //
// timer.isPaused = true
// //
// accessAppdelegate.switch_aSide()
// }
// }
// }
// }
// }else {
// print("ALog")
// //A
// completionBlock = {
// DispatchQueue.main.async {
// [weak self] in
// guard let self = self else {return}
// //
// timer.isPaused = true
// //
// accessAppdelegate.switch_aSide()
// }
// }
// }
// }
//
timer.isPaused = false
self.completionBlock = {
DispatchQueue.main.async {
[weak self] in
guard let self = self else {return}
//
timer.isPaused = true
//
accessAppdelegate.switch_positive()
//
MPPositive_BrowseLoadViewModel.shared.reloadBrowseLists()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
[weak self] in
guard let self = self else {return}
requestTrackingAuthorization { idfa in
if let idfa = idfa {
print("用户同意授权-idfa:\(idfa)")
}
}
}
MP_AnalyticsManager.shared.getOpenStatus { [weak self] open in
guard let self = self else {return}
if open {
//ip
MP_NetWorkManager.shared.requestIPInfo { statu in
if statu == true {
//b
print("BLog")
self.completionBlock = {
DispatchQueue.main.async {
[weak self] in
guard let self = self else {return}
//
timer.isPaused = true
//
accessAppdelegate.switch_positive()
//
MPPositive_BrowseLoadViewModel.shared.reloadBrowseLists()
}
}
}else {
print("ALog")
//A
self.completionBlock = {
DispatchQueue.main.async {
[weak self] in
guard let self = self else {return}
//
timer.isPaused = true
//
accessAppdelegate.switch_aSide()
}
}
}
}
}else {
print("ALog")
//A
completionBlock = {
DispatchQueue.main.async {
[weak self] in
guard let self = self else {return}
//
timer.isPaused = true
//
accessAppdelegate.switch_aSide()
}
}
}
}
//
timer.isPaused = false
// self.completionBlock = {
// DispatchQueue.main.async {
// [weak self] in
// guard let self = self else {return}
// //
// timer.isPaused = true
// //
// accessAppdelegate.switch_positive()
// //
// MPPositive_BrowseLoadViewModel.shared.reloadBrowseLists()
// }
// }
}
deinit {
//

View File

@ -177,43 +177,45 @@ func switchPlayTypeBtnIcon(_ btn:UIButton) {
}
}
///广
func requestTrackingAuthorization(_ observe:UIViewController,max:Int = 0) -> Bool {
func requestTrackingAuthorization(completion: @escaping (String?) -> Void) {
if #available(iOS 14, *) {
//
let status = ATTrackingManager.trackingAuthorizationStatus
switch status {
case .notDetermined:
//
print("未知的跟踪状态")
var attemptsLeft = 3
func requestAuth() {
ATTrackingManager.requestTrackingAuthorization { status in
let isAuthorized = status == .authorized
DispatchQueue.main.async {
let new = max + 1
if new < 3 {
_ = requestTrackingAuthorization(observe, max: new)
switch status {
case .authorized:
let idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString
print("Authorized: IDFA = \(idfa)")
completion(idfa)
case .denied, .restricted:
print("Denied or Restricted")
completion(nil)
case .notDetermined:
print("Not Determined")
attemptsLeft -= 1
if attemptsLeft > 0 {
requestAuth() //
} else {
print("Reached maximum number of attempts")
completion(nil)
}
@unknown default:
print("Unknown status")
completion(nil)
}
}
case .authorized:
// IDFA
print("用户授权跟踪")
return true
case .denied:
print("用户拒绝跟踪")
default:()
print("跟踪状态受限")
}
return false
requestAuth() //
} else {
return true
}
}
///IDFA
func getIDFA(_ observe:UIViewController) -> UUID? {
if requestTrackingAuthorization(observe) {
let idfa = ASIdentifierManager.shared().advertisingIdentifier
return idfa
}else {
return nil
if ASIdentifierManager.shared().isAdvertisingTrackingEnabled {
let idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString
print("Tracking enabled: IDFA = \(idfa)")
completion(idfa)
} else {
print("Tracking not enabled")
completion(nil)
}
}
}

View File

@ -63,16 +63,16 @@ class MP_NetWorkManager: NSObject {
private let youTubeKeys:[String] = ["MUSIC_VIDEO_TYPE_ATV","MUSIC_VIDEO_TYPE_OMV","MUSIC_PAGE_TYPE_ALBUM","MUSIC_PAGE_TYPE_ARTIST","MUSIC_PAGE_TYPE_PLAYLIST","MUSIC_PAGE_TYPE_TRACK_LYRICS","MUSIC_PAGE_TYPE_TRACK_RELATED"]
///IP
private let banIPs:[String] = [
"CN",
"HK",
"TW",
"JP",
"KR",
"GB",
"CH",
"BE",
"MO",
"SG"
// "CN",
// "HK",
// "TW",
// "JP",
// "KR",
// "GB",
// "CH",
// "BE",
// "MO",
// "SG"
]
//
enum NetWorkStatus: String {

View File

@ -56,13 +56,19 @@ class MPPositive_MoreSongOperationsViewController: UIViewController {
private let MPPositive_MoreOperationDownLoadTableViewCellID = "MPPositive_MoreOperationDownLoadTableViewCell"
private var song:MPPositive_SongItemModel!{
didSet{
iconImageView.kf.setImage(with: URL(string: song.reviewUrls?.last ?? ""), placeholder: placeholderImage)
titleLabel.text = song.title
subtitleLabel.text = song.shortBylineText
//
collectionBtn.isSelected = MPPositive_CollectionSongModel.fetch(.init(format: "videoId == %@", song.videoId)).count != 0
//
isLoaded = MPPositive_DownloadItemModel.fetch(.init(format: "videoId == %@", song.videoId)).count != 0
DispatchQueue.main.async {
[weak self] in
guard let self = self else {return}
// MP_HUD.hideNow()
view.isUserInteractionEnabled = true
iconImageView.kf.setImage(with: URL(string: song.reviewUrls?.last ?? ""), placeholder: placeholderImage)
titleLabel.text = song.title
subtitleLabel.text = song.shortBylineText
//
collectionBtn.isSelected = MPPositive_CollectionSongModel.fetch(.init(format: "videoId == %@", song.videoId)).count != 0
//
isLoaded = MPPositive_DownloadItemModel.fetch(.init(format: "videoId == %@", song.videoId)).count != 0
}
}
}
private var isLoaded:Bool = false{
@ -83,7 +89,120 @@ class MPPositive_MoreSongOperationsViewController: UIViewController {
self?.song = song
}
}
//browseViewModel
init(_ browseViewModel:MPPositive_BrowseItemViewModel) {
super.init(nibName: nil, bundle: nil)
view.isUserInteractionEnabled = false
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
[weak self] in
guard let self = self else {return}
// MP_HUD.loading()
//
MP_NetWorkManager.shared.requestNextList("", videoId: browseViewModel.browseItem.videoId ?? "") { [weak self] listSongs in
guard let first = listSongs.first else {return}
let group = DispatchGroup()
group.enter()
improveDataforLycirsAndRelated(first) {[weak self] (result) in
first.lyricsID = result.0
first.relatedID = result.1
group.leave()
}
group.enter()
//
improveDataforResouceAndCover(first) {[weak self] resourceUrls, coverUrls in
if let resourceUrls = resourceUrls {
first.resourceUrls = resourceUrls.0
first.itags = resourceUrls.1
first.mimeTypes = resourceUrls.2
}
first.coverUrls = coverUrls
group.leave()
}
group.notify(queue: .main, execute: {
[weak self] in
//
guard let self = self else {return}
song = first
})
}
}
}
//SearchResultItemViewModel
init(_ searchResultItemViewModel:MPPositive_SearchResultItemViewModel) {
super.init(nibName: nil, bundle: nil)
view.isUserInteractionEnabled = false
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
[weak self] in
guard let self = self else {return}
// MP_HUD.loading()
//
MP_NetWorkManager.shared.requestNextList("", videoId: searchResultItemViewModel.item.videoId ?? "") { [weak self] listSongs in
guard let first = listSongs.first else {return}
let group = DispatchGroup()
group.enter()
improveDataforLycirsAndRelated(first) {[weak self] (result) in
first.lyricsID = result.0
first.relatedID = result.1
group.leave()
}
group.enter()
//
improveDataforResouceAndCover(first) {[weak self] resourceUrls, coverUrls in
if let resourceUrls = resourceUrls {
first.resourceUrls = resourceUrls.0
first.itags = resourceUrls.1
first.mimeTypes = resourceUrls.2
}
first.coverUrls = coverUrls
group.leave()
}
group.notify(queue: .main, execute: {
[weak self] in
//
guard let self = self else {return}
song = first
})
}
}
}
//collectionSongViewModel
init(_ collectionSongViewModel:MPPositive_CollectionSongViewModel) {
super.init(nibName: nil, bundle: nil)
view.isUserInteractionEnabled = false
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
[weak self] in
guard let self = self else {return}
// MP_HUD.loading()
//
MP_NetWorkManager.shared.requestNextList("", videoId: collectionSongViewModel.collectionSong.videoId ?? ""){ [weak self] listSongs in
guard let first = listSongs.first else {return}
let group = DispatchGroup()
group.enter()
improveDataforLycirsAndRelated(first) {[weak self] (result) in
first.lyricsID = result.0
first.relatedID = result.1
group.leave()
}
group.enter()
//
improveDataforResouceAndCover(first) {[weak self] resourceUrls, coverUrls in
if let resourceUrls = resourceUrls {
first.resourceUrls = resourceUrls.0
first.itags = resourceUrls.1
first.mimeTypes = resourceUrls.2
}
first.coverUrls = coverUrls
group.leave()
}
group.notify(queue: .main, execute: {
[weak self] in
//
guard let self = self else {return}
song = first
})
}
}
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
@ -170,6 +289,9 @@ class MPPositive_MoreSongOperationsViewController: UIViewController {
MPPositive_LoadCoreModel.shared.reloadCollectionSongViewModel(nil)
MP_AnalyticsManager.shared.player_b_love_clickAction(song.videoId, videoname: song.title ?? "", artistname: song.shortBylineText ?? "")
}
if MP_PlayerManager.shared.loadPlayer?.currentVideo != nil {
MP_PlayerManager.shared.loadPlayer?.currentVideo?.reloadCollectionAndDownLoad()
}
if collectionBlock != nil {
collectionBlock!()
}
@ -291,6 +413,9 @@ extension MPPositive_MoreSongOperationsViewController:UITableViewDataSource, UIT
break
}
}
if MP_PlayerManager.shared.loadPlayer?.currentVideo != nil {
MP_PlayerManager.shared.loadPlayer?.currentVideo?.reloadCollectionAndDownLoad()
}
}
}
}

View File

@ -71,44 +71,20 @@ extension MPPositive_LoveSongsViewController: UITableViewDataSource, UITableView
[weak self] in
guard let self = self else {return}
MPPositive_Debouncer.shared.call {
MP_NetWorkManager.shared.requestNextList("", videoId: MPPositive_LoadCoreModel.shared.songViewModels[indexPath.row].collectionSong.videoId ?? ""){ [weak self] listSongs in
guard let first = listSongs.first else {return}
let group = DispatchGroup()
group.enter()
improveDataforLycirsAndRelated(first) {[weak self] (result) in
first.lyricsID = result.0
first.relatedID = result.1
group.leave()
}
group.enter()
//
improveDataforResouceAndCover(first) {[weak self] resourceUrls, coverUrls in
if let resourceUrls = resourceUrls {
first.resourceUrls = resourceUrls.0
first.itags = resourceUrls.1
first.mimeTypes = resourceUrls.2
}
first.coverUrls = coverUrls
group.leave()
}
group.notify(queue: .main, execute: {
[weak self] in
MPPositive_ModalType = .MoreOperations
let moreVC = MPPositive_MoreSongOperationsViewController(first)
moreVC.removeBlock = {
self?.reload()
}
moreVC.disMissBlock = {
self?.reload()
}
moreVC.collectionBlock = {
self?.reload()
}
moreVC.transitioningDelegate = self
moreVC.modalPresentationStyle = .custom
self?.present(moreVC, animated: true)
})
MPPositive_ModalType = .MoreOperations
let moreVC = MPPositive_MoreSongOperationsViewController(MPPositive_LoadCoreModel.shared.songViewModels[indexPath.row])
moreVC.removeBlock = {
self.reload()
}
moreVC.disMissBlock = {
self.reload()
}
moreVC.collectionBlock = {
self.reload()
}
moreVC.transitioningDelegate = self
moreVC.modalPresentationStyle = .custom
self.present(moreVC, animated: true)
}
}
return cell

View File

@ -227,7 +227,6 @@ extension MPPositive_ArtistShowViewController: JXPagingViewDelegate{
let lodaViewModel = MPPositive_PlayerLoadViewModel(listSongs, currentVideoId: item.browseItem.videoId ?? "")
lodaViewModel.improveData(item.browseItem.videoId ?? "")
MP_PlayerManager.shared.loadPlayer = lodaViewModel
// NotificationCenter.notificationKey.post(notificationName: .pup_player_vc)
}
}
case .none:
@ -238,35 +237,11 @@ extension MPPositive_ArtistShowViewController: JXPagingViewDelegate{
[weak self] (itemView) in
guard let self = self else {return}
MPPositive_Debouncer.shared.call {
MP_NetWorkManager.shared.requestNextList("", videoId: itemView.browseItem.videoId ?? ""){ [weak self] listSongs in
guard let first = listSongs.first else {return}
let group = DispatchGroup()
group.enter()
improveDataforLycirsAndRelated(first) {[weak self] (result) in
first.lyricsID = result.0
first.relatedID = result.1
group.leave()
}
group.enter()
//
improveDataforResouceAndCover(first) {[weak self] resourceUrls, coverUrls in
if let resourceUrls = resourceUrls {
first.resourceUrls = resourceUrls.0
first.itags = resourceUrls.1
first.mimeTypes = resourceUrls.2
}
first.coverUrls = coverUrls
group.leave()
}
group.notify(queue: .main, execute: {
[weak self] in
MPPositive_ModalType = .MoreOperations
let moreVC = MPPositive_MoreSongOperationsViewController(first)
moreVC.transitioningDelegate = self
moreVC.modalPresentationStyle = .custom
self?.present(moreVC, animated: true)
})
}
MPPositive_ModalType = .MoreOperations
let moreVC = MPPositive_MoreSongOperationsViewController(itemView)
moreVC.transitioningDelegate = self
moreVC.modalPresentationStyle = .custom
self.present(moreVC, animated: true)
}
}
return showView

View File

@ -307,36 +307,13 @@ extension MPPositive_ListShowViewController: UITableViewDataSource, UITableViewD
cell.moreBlock = {
[weak self] in
guard let self = self else {return}
MPPositive_Debouncer.shared.call {
MP_NetWorkManager.shared.requestNextList("", videoId: self.listOrAlbum.items[indexPath.row].browseItem.videoId ?? ""){ [weak self] listSongs in
guard let first = listSongs.first else {return}
let group = DispatchGroup()
group.enter()
improveDataforLycirsAndRelated(first) {[weak self] (result) in
first.lyricsID = result.0
first.relatedID = result.1
group.leave()
}
group.enter()
//
improveDataforResouceAndCover(first) {[weak self] resourceUrls, coverUrls in
if let resourceUrls = resourceUrls {
first.resourceUrls = resourceUrls.0
first.itags = resourceUrls.1
first.mimeTypes = resourceUrls.2
}
first.coverUrls = coverUrls
group.leave()
}
group.notify(queue: .main, execute: {
[weak self] in
MPPositive_ModalType = .MoreOperations
let moreVC = MPPositive_MoreSongOperationsViewController(first)
moreVC.transitioningDelegate = self
moreVC.modalPresentationStyle = .custom
self?.present(moreVC, animated: true)
})
}
MPPositive_ModalType = .MoreOperations
let moreVC = MPPositive_MoreSongOperationsViewController(self.listOrAlbum.items[indexPath.row])
moreVC.transitioningDelegate = self
moreVC.modalPresentationStyle = .custom
self.present(moreVC, animated: true)
}
}
return cell

View File

@ -295,8 +295,15 @@ class MPPositive_PlayerViewController: MPPositive_BaseViewController, UIViewCont
make.center.equalTo(playBtn)
make.width.height.equalTo(playBtn)
}
activityIndicator.isHidden = false
activityIndicator.startAnimating()
let state = MP_PlayerManager.shared.getPlayState()
switch state {
case .Null:
activityIndicator.isHidden = false
activityIndicator.startAnimating()
default:
activityIndicator.isHidden = false
activityIndicator.stopAnimating()
}
bottomView.addSubview(listBtn)
listBtn.snp.makeConstraints { make in
make.right.equalToSuperview().offset(-20*width)
@ -311,13 +318,13 @@ class MPPositive_PlayerViewController: MPPositive_BaseViewController, UIViewCont
}
bottomView.addSubview(nextBtn)
nextBtn.snp.makeConstraints { make in
make.width.height.equalTo(20*width)
make.width.height.equalTo(30*width)
make.centerY.equalTo(playBtn.snp.centerY)
make.right.equalToSuperview().offset(-98*width)
}
bottomView.addSubview(perviousBtn)
perviousBtn.snp.makeConstraints { make in
make.width.height.equalTo(20*width)
make.width.height.equalTo(30*width)
make.centerY.equalTo(playBtn.snp.centerY)
make.left.equalToSuperview().offset(98*width)
}
@ -328,7 +335,7 @@ class MPPositive_PlayerViewController: MPPositive_BaseViewController, UIViewCont
DispatchQueue.main.async {
[weak self] in
guard let self = self else {return}
print("\(MP_PlayerManager.shared.loadPlayer.currentVideo.title ?? "")刷新了页面")
print("\(MP_PlayerManager.shared.loadPlayer?.currentVideo?.title ?? "")刷新了页面")
//
backImageView.kf.setImage(with: MP_PlayerManager.shared.loadPlayer.currentVideo?.coverUrl, placeholder: placeholderImage)
coverView.coverImageView.kf.setImage(with: MP_PlayerManager.shared.loadPlayer.currentVideo?.coverUrl, placeholder: placeholderImage)
@ -341,6 +348,8 @@ class MPPositive_PlayerViewController: MPPositive_BaseViewController, UIViewCont
coverView.downloadButton.isUserInteractionEnabled = !(MP_PlayerManager.shared.loadPlayer.currentVideo?.isDlownd ?? false)
coverView.collectionSongBtn.isSelected = MP_PlayerManager.shared.loadPlayer.currentVideo?.isCollection ?? false
coverView.restoreDownloadProgress()
// activityIndicator.isHidden = true
// activityIndicator.stopAnimating()
}
}
//MARK: -

View File

@ -247,35 +247,11 @@ extension MPPositive_RecommendViewController: JXSegmentedListContainerViewDataSo
[weak self] (itemView) in
guard let self = self else {return}
MPPositive_Debouncer.shared.call {
MP_NetWorkManager.shared.requestNextList("", videoId: itemView.browseItem.videoId ?? ""){ [weak self] listSongs in
guard let first = listSongs.first else {return}
let group = DispatchGroup()
group.enter()
improveDataforLycirsAndRelated(first) {[weak self] (result) in
first.lyricsID = result.0
first.relatedID = result.1
group.leave()
}
group.enter()
//
improveDataforResouceAndCover(first) {[weak self] resourceUrls, coverUrls in
if let resourceUrls = resourceUrls {
first.resourceUrls = resourceUrls.0
first.itags = resourceUrls.1
first.mimeTypes = resourceUrls.2
}
first.coverUrls = coverUrls
group.leave()
}
group.notify(queue: .main, execute: {
[weak self] in
MPPositive_ModalType = .MoreOperations
let moreVC = MPPositive_MoreSongOperationsViewController(first)
moreVC.transitioningDelegate = self
moreVC.modalPresentationStyle = .custom
self?.present(moreVC, animated: true)
})
}
MPPositive_ModalType = .MoreOperations
let moreVC = MPPositive_MoreSongOperationsViewController(itemView)
moreVC.transitioningDelegate = self
moreVC.modalPresentationStyle = .custom
self.present(moreVC, animated: true)
}
}
return showView

View File

@ -136,35 +136,11 @@ class MPPositive_SearchResultShowViewController: MPPositive_BaseViewController,
[weak self] (itemView) in
guard let self = self else {return}
MPPositive_Debouncer.shared.call {
MP_NetWorkManager.shared.requestNextList("", videoId: itemView.item.videoId ?? ""){ [weak self] listSongs in
guard let first = listSongs.first else {return}
let group = DispatchGroup()
group.enter()
improveDataforLycirsAndRelated(first) {[weak self] (result) in
first.lyricsID = result.0
first.relatedID = result.1
group.leave()
}
group.enter()
//
improveDataforResouceAndCover(first) {[weak self] resourceUrls, coverUrls in
if let resourceUrls = resourceUrls {
first.resourceUrls = resourceUrls.0
first.itags = resourceUrls.1
first.mimeTypes = resourceUrls.2
}
first.coverUrls = coverUrls
group.leave()
}
group.notify(queue: .main, execute: {
[weak self] in
MPPositive_ModalType = .MoreOperations
let moreVC = MPPositive_MoreSongOperationsViewController(first)
moreVC.transitioningDelegate = self
moreVC.modalPresentationStyle = .custom
self?.present(moreVC, animated: true)
})
}
MPPositive_ModalType = .MoreOperations
let moreVC = MPPositive_MoreSongOperationsViewController(itemView)
moreVC.transitioningDelegate = self
moreVC.modalPresentationStyle = .custom
self.present(moreVC, animated: true)
}
}
errorBlock = {