// // MPPositive_LoadMusicModel.swift // MusicPlayer // // Created by Mr.Zhou on 2024/4/25. // import UIKit ///b面音乐数据管理load class MPPositive_BrowseLoadViewModel: NSObject { static let shared = MPPositive_BrowseLoadViewModel() ///预览模块数据组(通过网络请求刷新) var browseModuleLists:[MPPositive_BrowseModuleListViewModel] = [] ///用户个性化模块组 var personalModuleLists:[MPPositive_PersonalListViewModel] = [] ///本地Library组 var libraryList:MPPositive_LibraryListViewModel = .init() //是否发起过埋点 private var isAction:Bool = false //是否下拉刷新中 var isRefresh:Bool = false override init() { super.init() setNetWorkBlock() } //设置网络请求闭包回调 private func setNetWorkBlock() { //当网络请求工具触发browse请求闭包时 MP_NetWorkManager.shared.browseRequestStateBlock = { [weak self] (lists,isCompleted) in guard let self = self else {return} if isAction == false { if (lists.first?.items.count ?? 0) != 0 { print("B面预览数据成功拉取") //加载完毕后 MP_AnalyticsManager.shared.home_b_module_showsucces_actionAction() }else { print("B面预览数据拉取失败") //没有数据 MP_AnalyticsManager.shared.home_b_module_showfailure_errorAction("No Datas") } isAction = true } DispatchQueue.main.async { [weak self] in guard let self = self else {return} //配置预览模块数据 browseModuleLists.append(contentsOf: lists) //移除为空的数据 browseModuleLists = browseModuleLists.filter{($0.items.count != 0)} //通知首页刷新UI NotificationCenter.notificationKey.post(notificationName: .positive_browses_reload) } if isCompleted == true { //将视频移动到最后 DispatchQueue.main.async{ [weak self] in guard let self = self else {return} //查找目标院所索引 if let index = browseModuleLists.firstIndex(where: {$0.items.first?.browseItem.pageType == "MUSIC_PAGE_TYPE_ARTIST"}) { // 移除目标元素 let removedElement = browseModuleLists.remove(at: index) //添加到第二位 browseModuleLists.insert(removedElement, at: 1) } // 查找目标元素的索引 if let index = browseModuleLists.firstIndex(where: {$0.items.first?.browseItem.pageType == "MUSIC_VIDEO_TYPE_OMV"}) { // 移除目标元素 let removedElement = browseModuleLists.remove(at: index) // 将目标元素添加到数组的最后 browseModuleLists.append(removedElement) } NotificationCenter.notificationKey.post(notificationName: .positive_browses_reload) //将加载完毕的数据移入缓存 if browseModuleLists.count != 0 { cacheResponseData(browseModuleLists) } } } } //当网络请求工具触发error闭包时 MP_NetWorkManager.shared.browseRequestErrorBlock = { [weak self] in guard let self = self else {return} //当前因为某原因导致网络请求数据失败,现在从缓存中获取数据 guard let array = chachedData() else { //并没有缓存数据 NotificationCenter.notificationKey.post(notificationName: .netWork_error_deal) return } //有缓存数据 browseModuleLists = array //通知首页刷新UI NotificationCenter.notificationKey.post(notificationName: .positive_browses_reload) } } ///刷新预览数据 func reloadBrowseLists() { //有限更新本地数据组,之后再网络请求更多数据 MPPositive_LoadCoreModel.shared.reloadAll{ [weak self] in guard let self = self else {return} //清空预览模块数据 browseModuleLists.removeAll() //调用网络请求工具的预览请求 MP_NetWorkManager.shared.requestBrowseDatas() //同步更新gride MPPositive_GridLoadViewModel.shared.reloadGrides() //同步更新最近听过数据 getRecentlyData() } } ///获得最近听过数据 func getRecentlyData() { var lists:[MPPositive_PersonalListViewModel] = [] //检索最近听过的数据是否超过三首 let array = MPPositive_LoadCoreModel.shared.recents guard array.count >= 3 else { //发布刷新通知 NotificationCenter.notificationKey.post(notificationName: .positive_browses_reload) return } let recentList1:MPPositive_PersonalListViewModel = .init() recentList1.title = "Recent Played".localizableString() recentList1.isRecently = true //超过三首,生成一个最近听过的数据组 array.forEach { item in let browse = MPPositive_BrowseItemModel() browse.coverUrls = [item.recently.reviewImage ?? ""] browse.title = item.recently.title browse.subtitle = item.recently.subtitle browse.videoId = item.recently.videoId browse.playListId = item.recently.playListID browse.artistId = item.recently.artistID browse.pageType = "MUSIC_VIDEO_TYPE_ATV" browse.itemType = .single recentList1.items.append(.init(browse)) } lists.append(recentList1) let group = DispatchGroup() group.enter() getRecommondFirstNumberData(array) { [weak self] personl in guard let self = self else {return} if let item = personl { lists.insert(item, at: 1) } group.leave() } group.enter() getRecommondSecondNumberData(array) { [weak self] personl in guard let self = self else {return} if let item = personl { lists.append(item) } group.leave() } group.notify(queue: .main) { [weak self] in guard let self = self else {return} personalModuleLists = lists libraryList.reloadLibrarys { [weak self] in print("个性化内容组: \(self?.personalModuleLists.count ?? 0)") NotificationCenter.notificationKey.post(notificationName: .positive_browses_reload) } } } ///返回一个随机项相关数据1号内容 func getRecommondFirstNumberData(_ recents:[MPPositive_RecentlyViewModel], completetion:((MPPositive_PersonalListViewModel?) -> Void)?){ let personal:MPPositive_PersonalListViewModel = .init() //获取一个随机项,展示关联的数据1号内容 if let shuffix = recents.randomElement(), let recommendId = shuffix.recently.relatedID { personal.title = "Because you listen".localizableString() //随机获得一个,创建一个相关数据组(展示第一模块) MP_NetWorkManager.shared.requestRecommend(recommendId) { results in if results.isEmpty == false, let first = results.first { //返回数据不为空,获取第一模块 personal.items = first.items personal.random = shuffix if let block = completetion { block(personal) } }else { if let block = completetion { block(nil) } } } } } ///返回一个随机项相关数据2号内容 func getRecommondSecondNumberData(_ recents:[MPPositive_RecentlyViewModel], completetion:((MPPositive_PersonalListViewModel?) -> Void)?){ let personal:MPPositive_PersonalListViewModel = .init() //获取一个随机项,展示关联的数据1号内容 if let shuffix = recents.randomElement(), let recommendId = shuffix.recently.relatedID { personal.title = "Because you like".localizableString() //随机获得一个,创建一个相关数据组(展示第一模块) MP_NetWorkManager.shared.requestRecommend(recommendId) { results in if results.isEmpty == false, results.count > 1 { let item = results[1] //返回数据不为空,获取第一模块 personal.items = item.items personal.random = shuffix if let block = completetion { block(personal) } }else { if let block = completetion { block(nil) } } } } } ///缓存预览数据 private func cacheResponseData(_ array: [MPPositive_BrowseModuleListViewModel]) { guard browseModuleLists.count != 0 else { print("Home Browse数据未加载,无法缓存") return } //将数据转为jsonData do{ let jsonData = try JSONEncoder().encode(array) //使用UserDefaults存入缓存数据 UserDefaults.standard.set(jsonData, forKey: "HomeBrowse") print("已经将Home Browse数据缓存") }catch{ //转为jsonData失败 print("Home Browse数据转为Data失败,失败原因\(error)") } } //读取预览数据 private func chachedData() -> [MPPositive_BrowseModuleListViewModel]? { guard let cacheData = UserDefaults.standard.data(forKey: "HomeBrowse") else { print("获取Home Browse缓存数据失败") return nil } //将cacheData转为[MPPositive_BrowseModuleListViewModel] do { let array:[MPPositive_BrowseModuleListViewModel] = try JSONDecoder().decode([MPPositive_BrowseModuleListViewModel].self, from: cacheData) print("已经将Home Browse缓存数据取出") return array } catch { //转为jsonData失败 print("获取Home Browse缓存数据失败,失败原因\(error)") return nil } } //下拉刷新 func pullDownRefresh(_ reloadCompleted:(() -> Void)?) { //启动值 isRefresh = true var arrays:[MPPositive_BrowseModuleListViewModel] = [] //执行下拉刷新网络请求 MP_NetWorkManager.shared.requestPullDownHomeBrowse() //覆盖回调闭包 MP_NetWorkManager.shared.browseRequestStateBlock = { [weak self] (lists,isCompleted) in guard let self = self, isRefresh == true else {return} DispatchQueue.main.async { [weak self] in guard let self = self else {return} //配置预览模块数据 arrays.append(contentsOf: lists) //移除为空的数据 arrays = arrays.filter{($0.items.count != 0)} if isCompleted == true { //将视频移动到最后 DispatchQueue.main.async{ [weak self] in guard let self = self else { return } MPPositive_LoadCoreModel.shared.reloadRecents { [weak self] in guard let self = self else { return } getRecentlyData() } //查找目标院所索引 if let index = arrays.firstIndex(where: {$0.items.first?.browseItem.pageType == "MUSIC_PAGE_TYPE_ARTIST"}) { // 移除目标元素 let removedElement = arrays.remove(at: index) //添加到第二位 arrays.insert(removedElement, at: 1) } // 查找目标元素的索引 if let index = arrays.firstIndex(where: {$0.items.first?.browseItem.pageType == "MUSIC_VIDEO_TYPE_OMV"}) { // 移除目标元素 let removedElement = arrays.remove(at: index) // 将目标元素添加到数组的最后 arrays.append(removedElement) } //有缓存数据 browseModuleLists = arrays isRefresh = false print("更新下拉刷新") if let block = reloadCompleted { block() } } } } } } }