diff --git a/relax.offline.mp3.music.xcworkspace/xcuserdata/zhou.xcuserdatad/UserInterfaceState.xcuserstate b/relax.offline.mp3.music.xcworkspace/xcuserdata/zhou.xcuserdatad/UserInterfaceState.xcuserstate index 63dec7e..c8a0bd5 100644 Binary files a/relax.offline.mp3.music.xcworkspace/xcuserdata/zhou.xcuserdatad/UserInterfaceState.xcuserstate and b/relax.offline.mp3.music.xcworkspace/xcuserdata/zhou.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/relax.offline.mp3.music/Info.plist b/relax.offline.mp3.music/Info.plist index c56431b..5d44b05 100644 --- a/relax.offline.mp3.music/Info.plist +++ b/relax.offline.mp3.music/Info.plist @@ -7,18 +7,18 @@ CFBundleURLSchemes - fb820013496431805 + fb515287044709010 FacebookAppID - 820013496431805 + 515287044709010 FacebookAutoLogAppEventsEnabled FacebookClientToken - 8e591aa271d43fdd3e7a778d59c85282 + f7ec7d15be9315aee02f6deb37b52e15 FacebookDisplayName - Musiclax + HiMelody iOS GADApplicationIdentifier ca-app-pub-1371732277241593~3881310073 SKAdNetworkItems diff --git a/relax.offline.mp3.music/MP/Common/Extension(扩展)/Devices.swift b/relax.offline.mp3.music/MP/Common/Extension(扩展)/Devices.swift index 4c84cee..009aa33 100644 --- a/relax.offline.mp3.music/MP/Common/Extension(扩展)/Devices.swift +++ b/relax.offline.mp3.music/MP/Common/Extension(扩展)/Devices.swift @@ -16,7 +16,6 @@ extension UIDevice { guard let value = element.value as? Int8, value != 0 else { return identifier } return identifier + String(UnicodeScalar(UInt8(value))) } - return mapToDevice(identifier: identifier) } diff --git a/relax.offline.mp3.music/MP/Common/Macro(宏定义与全局量)/Macro.swift b/relax.offline.mp3.music/MP/Common/Macro(宏定义与全局量)/Macro.swift index 78382f2..68f164b 100644 --- a/relax.offline.mp3.music/MP/Common/Macro(宏定义与全局量)/Macro.swift +++ b/relax.offline.mp3.music/MP/Common/Macro(宏定义与全局量)/Macro.swift @@ -467,20 +467,24 @@ func saveLoadVideoItem(_ song:MPPositive_SongItemModel?, completion:(() -> Void) item?.playListID = song.playListID //同步生成一个独特的数据 - let recent = try? MPPositive_RecentlyModel.create() - recent?.coverImage = song.coverUrls?.last - recent?.reviewImage = song.reviewUrls?.last - recent?.title = song.title - recent?.subtitle = "\(song.longBylineText ?? "")\(song.shortBylineText ?? "")" - recent?.videoId = song.videoId - recent?.lyricsID = song.lyricsID - recent?.relatedID = song.relatedID - recent?.addTime = Date() - recent?.level = 3 - recent?.artistID = song.artistID - recent?.albumID = song.albumID - recent?.playListID = song.playListID - + MPPositive_RecentlyModel.fetch(predicate: .init(format: "videoId == %@", (song.videoId ?? ""))) { results in + if results.isEmpty { + let recent = try? MPPositive_RecentlyModel.create() + recent?.coverImage = song.coverUrls?.last + recent?.reviewImage = song.reviewUrls?.last + recent?.title = song.title + recent?.subtitle = "\(song.longBylineText ?? "")\(song.shortBylineText ?? "")" + recent?.videoId = song.videoId + recent?.lyricsID = song.lyricsID + recent?.relatedID = song.relatedID + recent?.addTime = Date() + recent?.level = 3 + recent?.artistID = song.artistID + recent?.albumID = song.albumID + recent?.playListID = song.playListID + MPPositive_RecentlyModel.save() + } + } //保存下载数据 MPPositive_DownloadItemModel.save() completion?() diff --git a/relax.offline.mp3.music/MP/Common/Tool(工具封装)/MP_NetWorkManager.swift b/relax.offline.mp3.music/MP/Common/Tool(工具封装)/MP_NetWorkManager.swift index ed76919..0f0fb06 100644 --- a/relax.offline.mp3.music/MP/Common/Tool(工具封装)/MP_NetWorkManager.swift +++ b/relax.offline.mp3.music/MP/Common/Tool(工具封装)/MP_NetWorkManager.swift @@ -153,7 +153,8 @@ class MP_NetWorkManager: NSObject { ///预览内容键值 private var browseContext:[String:Any]{ let client = ["client":browseClient] - return ["context":client] + return ["context":client, + "key":netKeyCode] } ///预览访客键值 private var browseClient:[String:String]{ @@ -187,7 +188,8 @@ class MP_NetWorkManager: NSObject { "gl": "US" ] ], - "params": "CgIQBg" + "params": "CgIQBg", + "key":netKeyCode ] } } @@ -380,7 +382,7 @@ extension MP_NetWorkManager { //拼接出browse路径 let path = header+point+browse //设置url - guard let pathUrl = URL(string: path), let url = try? URLEncoding.default.encode(URLRequest(url: pathUrl), with: ["key":netKeyCode]).url else { + guard let url = URL(string: path) else { print("Url is Incorrect") return } @@ -393,7 +395,7 @@ extension MP_NetWorkManager { //更多请求 func requestContinuationBrowseDatas() { //当获取新值后,判断新值是否存在,存在则继续串行异步请求 - guard let continuation = continuationAndItct?.continuation, let itct = continuationAndItct?.itct, let pathUrl = URL(string: header+point+browse), let url = try? URLEncoding.default.encode(URLRequest(url: pathUrl), with: ["key":netKeyCode]).url else { + guard let continuation = continuationAndItct?.continuation, let itct = continuationAndItct?.itct, let url = URL(string: header+point+browse) else { //首页基础数据已经获取完毕,不需要继续调用接口拉取数据 print("首页数据已经加载完毕") NotificationCenter.notificationKey.post(notificationName: .positive_browses_completion) @@ -451,7 +453,7 @@ extension MP_NetWorkManager { //拼接出browse路径 let path = header+point+browse //设置url - guard let pathUrl = URL(string: path), let url = try? URLEncoding.default.encode(URLRequest(url: pathUrl), with: ["key":netKeyCode]).url else { + guard let url = URL(string: path) else { print("Url is Incorrect") return } @@ -489,7 +491,7 @@ extension MP_NetWorkManager { //拼接出browse路径 let path = header+point+browse //设置url - guard let pathUrl = URL(string: path), let url = try? URLEncoding.default.encode(URLRequest(url: pathUrl), with: ["key":netKeyCode]).url else { + guard let url = URL(string: path) else { print("Url is Incorrect") return } @@ -524,7 +526,7 @@ extension MP_NetWorkManager { //拼接出browse路径 let path = header+point+browse //设置url - guard let pathUrl = URL(string: path), let url = try? URLEncoding.default.encode(URLRequest(url: pathUrl), with: ["key":netKeyCode]).url else { + guard let url = URL(string: path) else { print("Url is Incorrect") return } @@ -573,7 +575,7 @@ extension MP_NetWorkManager { //拼接出browse路径 let path = header+point+browse //设置url - guard let pathUrl = URL(string: path), let url = try? URLEncoding.default.encode(URLRequest(url: pathUrl), with: ["key":netKeyCode]).url else { + guard let url = URL(string: path) else { print("Url is Incorrect") return } @@ -612,7 +614,7 @@ extension MP_NetWorkManager { //拼接出browse路径 let path = header+point+browse //设置url - guard let pathUrl = URL(string: path), let url = try? URLEncoding.default.encode(URLRequest(url: pathUrl), with: ["key":netKeyCode]).url else { + guard let url = URL(string: path) else { print("Url is Incorrect") return } @@ -648,7 +650,7 @@ extension MP_NetWorkManager { //拼接出browse路径 let path = header+point+browse //设置url - guard let pathUrl = URL(string: path), let url = try? URLEncoding.default.encode(URLRequest(url: pathUrl), with: ["key":netKeyCode]).url else { + guard let url = URL(string: path) else { print("Url is Incorrect") return } @@ -686,7 +688,7 @@ extension MP_NetWorkManager { //拼接出browse路径 let path = header+point+browse //设置url - guard let pathUrl = URL(string: path), let url = try? URLEncoding.default.encode(URLRequest(url: pathUrl), with: ["key":netKeyCode]).url else { + guard let url = URL(string: path) else { print("Url is Incorrect") return } @@ -720,7 +722,7 @@ extension MP_NetWorkManager { //拼接出browse路径 let path = header+point+browse //设置url - guard let pathUrl = URL(string: path), let url = try? URLEncoding.default.encode(URLRequest(url: pathUrl), with: ["key":netKeyCode]).url else { + guard let url = URL(string: path) else { print("Url is Incorrect") return } @@ -760,7 +762,7 @@ extension MP_NetWorkManager { //拼接出next路径 let path = header+point+next //设置url - guard let pathUrl = URL(string: path), let url = try? URLEncoding.default.encode(URLRequest(url: pathUrl), with: ["key":netKeyCode]).url else { + guard let url = URL(string: path) else { print("Url is Incorrect") return } @@ -801,7 +803,7 @@ extension MP_NetWorkManager { //拼接出next路径 let path = header+point+next //设置url - guard let pathUrl = URL(string: path), let url = try? URLEncoding.default.encode(URLRequest(url: pathUrl), with: ["key":netKeyCode]).url, let videoId = item.videoId else { + guard let url = URL(string: path), let videoId = item.videoId else { print("Url is Incorrect") return } @@ -846,8 +848,9 @@ extension MP_NetWorkManager { //拼接出player路径 let path = header+point+player //设置url - guard let pathUrl = URL(string: path), let url = try? URLEncoding.default.encode(URLRequest(url: pathUrl), with: ["key":netKeyCode]).url else { + guard let url = URL(string: path) else { print("Url is Incorrect") + completion(nil,nil) return } //设置参数,videoId与params参数是必定携带内容 @@ -860,22 +863,44 @@ extension MP_NetWorkManager { failure?(statu) } } - private func requestAndroidPostPlayer(_ url:URL, videoId:String, parameters:Parameters, completion:@escaping((([String],[Int],[String])?, [String]?) -> Void), failure:((Bool) -> Void)? = nil) { + private func requestAndroidPostPlayer(_ url:URL, videoId:String, parameters:Parameters, index:Int = 0, completion:@escaping((([String],[Int],[String])?, [String]?) -> Void), failure:((Bool) -> Void)? = nil) { //发送post请求 let request = PlayerSeesion.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default).responseDecodable(of: JsonAndroidPlayer.self) { [weak self] (response) in guard let self = self else {return} - self.playerRequests[videoId] = nil // 清除请求 switch response.result { case .success(let value): parsingAndroidPlayer(value) { resourceUlrs, coverUrls in + if self.playerRequests[videoId] != nil { + self.playerRequests[videoId] = nil // 清除请求 + } //成功获得资源 completion(resourceUlrs, coverUrls) } failure: { statu in - //失败 + if self.playerRequests[videoId] != nil { + self.playerRequests[videoId] = nil // 清除请求 + } failure?(statu) + } resetion: { + //需要重启网络请求 + if index < 3 { + print("对于歌曲:\(videoId),进行重复请求") + //可以继续请求 + let next = index + 1 + self.requestAndroidPostPlayer(url, videoId: videoId, parameters: parameters, index: next, completion: completion, failure: failure) + }else { + //重复请求超过限制了,不再重复请求,结束请求 + print("对于歌曲:\(videoId),请求超限,不再继续") + if self.playerRequests[videoId] != nil { + self.playerRequests[videoId] = nil // 清除请求 + } + failure?(false) + self.setNumbersFailures() + } } - case .failure(let error): + if self.playerRequests[videoId] != nil { + self.playerRequests[videoId] = nil // 清除请求 + } //当前无数据 failure?(false) // 请求失败,处理错误 @@ -953,7 +978,7 @@ extension MP_NetWorkManager { //拼接出browse路径 let path = header+point+browse //设置url - guard let pathUrl = URL(string: path), let url = try? URLEncoding.default.encode(URLRequest(url: pathUrl), with: ["key":netKeyCode]).url else { + guard let url = URL(string: path) else { print("Url is Incorrect") return } @@ -985,7 +1010,7 @@ extension MP_NetWorkManager { //拼接出browse路径 let path = header+point+browse //设置url - guard let pathUrl = URL(string: path), let url = try? URLEncoding.default.encode(URLRequest(url: pathUrl), with: ["key":netKeyCode]).url else { + guard let url = URL(string: path) else { print("Url is Incorrect") return } @@ -1063,7 +1088,7 @@ extension MP_NetWorkManager { //拼接路径 let path = header+point+search //设置url - guard let pathUrl = URL(string: path), let url = try? URLEncoding.default.encode(URLRequest(url: pathUrl), with: ["key":netKeyCode]).url else { + guard let url = URL(string: path) else { print("Url is Incorrect") return } @@ -1117,7 +1142,7 @@ extension MP_NetWorkManager { //拼接路径 let path = header+point+search //设置url - guard let pathUrl = URL(string: path), let url = try? URLEncoding.default.encode(URLRequest(url: pathUrl), with: ["key":netKeyCode]).url else { + guard let url = URL(string: path) else { print("Url is Incorrect") return } @@ -1163,7 +1188,7 @@ extension MP_NetWorkManager { //拼接路径 let path = header+point+search //设置url - guard let pathUrl = URL(string: path), let url = try? URLEncoding.default.encode(URLRequest(url: pathUrl), with: ["key":netKeyCode]).url else { + guard let url = URL(string: path) else { print("Url is Incorrect") return } @@ -1799,7 +1824,15 @@ extension MP_NetWorkManager { // } // } // } - private func parsingAndroidPlayer(_ player:JsonAndroidPlayer,completion:@escaping((([String],[Int],[String]), [String]?) -> Void), failure:((Bool) -> Void)? = nil){ + private func parsingAndroidPlayer(_ player:JsonAndroidPlayer,completion:@escaping((([String],[Int],[String]), [String]?) -> Void), failure:((Bool) -> Void)? = nil, resetion:(() -> Void)? = nil){ + //检索相应内容状态 + guard let statu = player.playabilityStatus?.status, statu == "OK" || statu == "LOGIN_REQUIRED" else { + //检索失败,重新请求 + if let block = resetion { + block() + } + return + } var infos:[String]? //解析player,获取资源库和信息库 if let videoDetails = player.videoDetails { @@ -1815,25 +1848,28 @@ extension MP_NetWorkManager { }else { //不存在资源(通常是IP被拉黑了) failure?(true) - MP_HUD.error("Failed to obtain resource, please try again later".localizableString(), delay: 1.0, completion: nil) - //检索不存在资源的次数 - if let number = UserDefaults.standard.object(forKey: "Number_Failures") as? Int { - //当次数超过8次时,确定为IP被拉黑了 - if number > 6 { - //触发拉黑上传事件 - MP_AnalyticsManager.shared.resource_IP_blackAction() - }else { - //没有达到8次,新增计数值 - UserDefaults.standard.set(number+1, forKey: "Number_Failures") - UserDefaults.standard.synchronize() - } + setNumbersFailures() + } + } + private func setNumbersFailures() { + MP_HUD.error("Failed to obtain resource, please try again later".localizableString(), delay: 1.0, completion: nil) + //检索不存在资源的次数 + if let number = UserDefaults.standard.object(forKey: "Number_Failures") as? Int { + //当次数超过8次时,确定为IP被拉黑了 + if number > 6 { + //触发拉黑上传事件 + MP_AnalyticsManager.shared.resource_IP_blackAction() }else { - //无次数,说明是第一次触发该问题 - UserDefaults.standard.set(1, forKey: "Number_Failures") + //没有达到8次,新增计数值 + UserDefaults.standard.set(number+1, forKey: "Number_Failures") UserDefaults.standard.synchronize() } - MP_AnalyticsManager.shared.player_resource_failureAction(locaton ?? "HK") + }else { + //无次数,说明是第一次触发该问题 + UserDefaults.standard.set(1, forKey: "Number_Failures") + UserDefaults.standard.synchronize() } + MP_AnalyticsManager.shared.player_resource_failureAction(locaton ?? "HK") } /// 解析播放器_StreamingData diff --git a/relax.offline.mp3.music/MP/Common/Tool(工具封装)/MP_PlayerManager.swift b/relax.offline.mp3.music/MP/Common/Tool(工具封装)/MP_PlayerManager.swift index 35611aa..cd9f51c 100644 --- a/relax.offline.mp3.music/MP/Common/Tool(工具封装)/MP_PlayerManager.swift +++ b/relax.offline.mp3.music/MP/Common/Tool(工具封装)/MP_PlayerManager.swift @@ -596,16 +596,20 @@ class MP_PlayerManager:NSObject{ item?.artistID = song.artistID item?.albumID = song.albumID item?.playListID = song.playListID + MPPositive_RecentlyModel.save() }else { //不为空,调整数据 - if let item = results.first { - if (item.level) < level { - item.level = level - } - item.addTime = Date() + var array = results + let first = array.removeFirst() + if first.level < level { + first.level = level + } + first.addTime = Date() + MPPositive_RecentlyModel.save() + array.forEach { item in + MPPositive_RecentlyModel.delete(item) } } - MPPositive_RecentlyModel.save() } } diff --git a/relax.offline.mp3.music/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonPlayer.swift b/relax.offline.mp3.music/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonPlayer.swift index 6e5baf2..4c5f9ca 100644 --- a/relax.offline.mp3.music/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonPlayer.swift +++ b/relax.offline.mp3.music/MP/MPPositive/Models/JsonStructs(js文件结构)/MPPositive_JsonPlayer.swift @@ -127,19 +127,36 @@ struct JsonPlayer: Codable { } ///安卓结构的播放器数据 struct JsonAndroidPlayer: Codable { + ///相应状态 + let playabilityStatus:PlayabilityStatus? ///资源路径块 let streamingData:StreamingData? ///单曲/视频信息块 let videoDetails:VideoDetails? enum CodingKeys: String, CodingKey { + case playabilityStatus = "playabilityStatus" case streamingData = "streamingData" case videoDetails = "videoDetails" } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) + playabilityStatus = try values.decodeIfPresent(PlayabilityStatus.self, forKey: .playabilityStatus) streamingData = try values.decodeIfPresent(StreamingData.self, forKey: .streamingData) videoDetails = try values.decodeIfPresent(VideoDetails.self, forKey: .videoDetails) } + //MARK: - 资源相应状态 + struct PlayabilityStatus: Codable { + let status:String? + enum CodingKeys: String, CodingKey { + case status = "status" + } + init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + status = try values.decodeIfPresent(String.self, forKey: .status) + } + + } + //MARK: - 资源路径(各等级资源) struct StreamingData: Codable { ///允许访问的时间值 diff --git a/relax.offline.mp3.music/MP/MPPositive/Views/Home/MPPositive_ArtistShowSongTableViewCell.swift b/relax.offline.mp3.music/MP/MPPositive/Views/Home/MPPositive_ArtistShowSongTableViewCell.swift index 82c2665..cf91a22 100644 --- a/relax.offline.mp3.music/MP/MPPositive/Views/Home/MPPositive_ArtistShowSongTableViewCell.swift +++ b/relax.offline.mp3.music/MP/MPPositive/Views/Home/MPPositive_ArtistShowSongTableViewCell.swift @@ -253,9 +253,9 @@ class MPPositive_ArtistShowSongTableViewCell: UITableViewCell, PKDownloadButtonD //切换为准备状态 downloadButton.state = .pending //通过网络请求获取当前预览项资源(转为Song) - MP_NetWorkManager.shared.requestNextList(itemView?.browseItem.playListId ?? "", videoId: itemView?.browseItem.videoId ?? "", clickTrackingParams: itemView.browseItem.clickTrackingParams){ + MP_NetWorkManager.shared.requestNextList(itemView?.browseItem.playListId ?? "", videoId: videoId, clickTrackingParams: itemView.browseItem.clickTrackingParams){ [weak self] listSongs in - guard let self = self, let first = listSongs.first else { + guard let self = self, let first = listSongs.first(where: {$0.videoId == videoId}) else { //获取资源失败 self?.setProgress(videoId) return diff --git a/relax.offline.mp3.music/MP/MPPositive/Views/Home/MPPositive_HomeSingleCollectionViewCell.swift b/relax.offline.mp3.music/MP/MPPositive/Views/Home/MPPositive_HomeSingleCollectionViewCell.swift index 625f325..0c11156 100644 --- a/relax.offline.mp3.music/MP/MPPositive/Views/Home/MPPositive_HomeSingleCollectionViewCell.swift +++ b/relax.offline.mp3.music/MP/MPPositive/Views/Home/MPPositive_HomeSingleCollectionViewCell.swift @@ -246,7 +246,7 @@ class MPPositive_HomeSingleCollectionViewCell: UICollectionViewCell, PKDownloadB //通过网络请求获取当前预览项资源(转为Song) MP_NetWorkManager.shared.requestNextList(itemViewModel?.browseItem.playListId ?? "", videoId: videoId, clickTrackingParams: nil){ [weak self] listSongs in - guard let self = self, let first = listSongs.first else { + guard let self = self, let first = listSongs.first(where: {$0.videoId == videoId}) else { //获取资源失败 self?.setProgress(videoId) return diff --git a/relax.offline.mp3.music/MP/MPPositive/Views/Home/MPPositive_MusicItemShowTableViewCell.swift b/relax.offline.mp3.music/MP/MPPositive/Views/Home/MPPositive_MusicItemShowTableViewCell.swift index 726829e..0bf6a34 100644 --- a/relax.offline.mp3.music/MP/MPPositive/Views/Home/MPPositive_MusicItemShowTableViewCell.swift +++ b/relax.offline.mp3.music/MP/MPPositive/Views/Home/MPPositive_MusicItemShowTableViewCell.swift @@ -279,7 +279,7 @@ class MPPositive_MusicItemShowTableViewCell: UITableViewCell, PKDownloadButtonDe //通过网络请求获取当前预览项资源(转为Song) MP_NetWorkManager.shared.requestNextList(itemView?.browseItem.playListId ?? "", videoId: videoId, clickTrackingParams: nil){ [weak self] listSongs in - guard let self = self, let first = listSongs.first else { + guard let self = self, let first = listSongs.first(where: {$0.videoId == videoId}) else { //获取资源失败 self?.setProgress(videoId) return diff --git a/relax.offline.mp3.music/MP/MPPositive/Views/Search/MPPositive_SearchResultShowTableViewCell.swift b/relax.offline.mp3.music/MP/MPPositive/Views/Search/MPPositive_SearchResultShowTableViewCell.swift index b09f6e0..522e43d 100644 --- a/relax.offline.mp3.music/MP/MPPositive/Views/Search/MPPositive_SearchResultShowTableViewCell.swift +++ b/relax.offline.mp3.music/MP/MPPositive/Views/Search/MPPositive_SearchResultShowTableViewCell.swift @@ -325,7 +325,7 @@ class MPPositive_SearchResultShowTableViewCell: UITableViewCell, PKDownloadButto //通过网络请求获取当前预览项资源(转为Song) MP_NetWorkManager.shared.requestNextList(playListId ?? "", videoId: videoId, clickTrackingParams: nil){ [weak self] listSongs in - guard let self = self, let first = listSongs.first else { + guard let self = self, let first = listSongs.first(where: {$0.videoId == videoId}) else { //获取资源失败 self?.setProgress(videoId) return