@ -17,6 +17,9 @@ typealias ListRequestResultBlock = (_ list:MPPositive_ListAlbumListViewModel) ->
class MP_NetWorkManager : NSObject {
// 单 例 工 具
static let shared = MP_NetWorkManager ( )
// MARK: - 网 络 请 求 会 话
// / 会 话 实 例
private let MPSession = Alamofire . Session ( interceptor : MP_CustomRetrier ( ) )
// MARK: - A P I 接 口
// / 域 名 链 接
private let header : String = " https://music.youtube.com "
@ -129,6 +132,25 @@ class MP_NetWorkManager: NSObject {
let queue = DispatchQueue ( label : " MPNetWorkManager " )
monitor . start ( queue : queue )
}
// / 网 络 请 求 检 测
private func requestStatusToYouTube ( _ isAilable : @ escaping ( Bool ) -> Void ) {
// 设 置 一 个 节 点
let reachabilityManager = NetworkReachabilityManager ( host : " https://music.youtube.com/ " )
// 通 过 p i n g 节 点 确 认 是 否 能 执 行 网 络 请 求
reachabilityManager ? . startListening ( onUpdatePerforming : { status in
switch status {
case . unknown : // 未 知 状 况
isAilable ( false )
print ( " 网络情况未知 " )
case . notReachable : // 网 络 不 可 用
isAilable ( false )
print ( " 网络不可用 " )
case . reachable ( . ethernetOrWiFi ) , . reachable ( . cellular ) : // 网 络 可 用 , 且 做 出 了 分 类
// 网 络 可 用
isAilable ( true )
}
} )
}
}
// MARK: - A P I 请 求
extension MP_NetWorkManager {
@ -167,16 +189,19 @@ extension MP_NetWorkManager {
]
]
]
requestPostHomeBrowse ( url , parameters : parameters )
requestStatusToYouTube { isAvailable in
if isAvailable = = true {
self . requestPostHomeBrowse ( url , parameters : parameters )
}
}
}
}
// 请 求 首 页 预 览 内 容 ( 执 行 多 次 )
private func requestPostHomeBrowse ( _ url : URL , parameters : Parameters ) {
// 发 送 p o s t 请 求 , 并 将 结 果 转 为 R o o t B r o w s e s
AF . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonBrowses . self ) { [ weak self ] ( response ) in
MPSession . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonBrowses . self ) { [ weak self ] ( response ) in
guard let self = self else { return }
switch response . result {
case . success ( let value ) :
if value . responseContext ? . visitorData != nil {
@ -230,14 +255,18 @@ extension MP_NetWorkManager {
]
]
]
requestPostAlbumOrList ( url , parameters : parameters ) { results in
requestStatusToYouTube { isAvailable in
if isAvailable = = true {
self . requestPostAlbumOrList ( url , parameters : parameters ) { results in
comletion ( results )
}
}
}
}
// 请 求 列 表 / 专 辑 数 据
private func requestPostAlbumOrList ( _ url : URL , parameters : Parameters , comletion : @ escaping ( MPPositive_ListAlbumListViewModel ) -> Void ) {
// 发 送 p o s t 请 求 , 并 将 结 果 转 为 R o o t B r o w s e s
AF . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonListOrAlbum . self ) { [ weak self ] ( response ) in
MPSession . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonListOrAlbum . self ) { [ weak self ] ( response ) in
guard let self = self else { return }
switch response . result {
case . success ( let value ) :
@ -286,14 +315,18 @@ extension MP_NetWorkManager {
]
]
]
requestPostArtist ( url , parameters : parameters ) { result in
requestStatusToYouTube { isAvailable in
if isAvailable = = true {
self . requestPostArtist ( url , parameters : parameters ) { result in
comletion ( result )
}
}
}
}
// 请 求 艺 术 家 信 息
private func requestPostArtist ( _ url : URL , parameters : Parameters , comletion : @ escaping ( MPPositive_ArtistViewModel ) -> Void ) {
// 发 送 p o s t 请 求 , 并 将 结 果 转 为 R o o t B r o w s e s
AF . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonArtist . self ) { [ weak self ] ( response ) in
MPSession . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonArtist . self ) { [ weak self ] ( response ) in
guard let self = self else { return }
switch response . result {
case . success ( let value ) :
@ -341,14 +374,18 @@ extension MP_NetWorkManager {
]
]
]
requestPostArtistMore ( url , parameters : parameters ) { result in
requestStatusToYouTube { isAvailable in
if isAvailable = = true {
self . requestPostArtistMore ( url , parameters : parameters ) { result in
comletion ( result )
}
}
}
}
// / 请 求 艺 术 家 更 多 数 据
private func requestPostArtistMore ( _ url : URL , parameters : Parameters , comletion : @ escaping ( ( [ MPPositive_BrowseItemViewModel ] , String ? , String ? ) ) -> Void ) {
// 发 送 p o s t 请 求 , 并 将 结 果 转 为 R o o t B r o w s e s
AF . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonArtistMore . self ) { [ weak self ] ( response ) in
MPSession . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonArtistMore . self ) { [ weak self ] ( response ) in
guard let self = self else { return }
switch response . result {
case . success ( let value ) :
@ -393,14 +430,18 @@ extension MP_NetWorkManager {
]
]
]
requestPostArtistMoreContinuation ( url , parameters : parameters ) { result in
requestStatusToYouTube { isAvailable in
if isAvailable = = true {
self . requestPostArtistMoreContinuation ( url , parameters : parameters ) { result in
comletion ( result )
}
}
}
}
// / 请 求 艺 术 家 更 多 数 据 继 续
private func requestPostArtistMoreContinuation ( _ url : URL , parameters : Parameters , comletion : @ escaping ( ( [ MPPositive_BrowseItemViewModel ] , String ? , String ? ) ) -> Void ) {
// 发 送 p o s t 请 求 , 并 将 结 果 转 为 R o o t B r o w s e s
AF . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonArtistMore . self ) { [ weak self ] ( response ) in
MPSession . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonArtistMore . self ) { [ weak self ] ( response ) in
guard let self = self else { return }
switch response . result {
case . success ( let value ) :
@ -446,16 +487,20 @@ extension MP_NetWorkManager {
]
]
]
requestStatusToYouTube { isAvailable in
if isAvailable = = true {
// 发 送 n e x t 列 表 请 求
requestPostNextList ( url , parameters : parameters ) { listSongs in
self . requestPostNextList ( url , parameters : parameters ) { listSongs in
// 成 功 拿 到 列 表 所 有 歌 曲 ( 内 容 尚 不 完 善 )
completion ( listSongs )
}
}
}
}
// 请 求 n e x t 列 表
private func requestPostNextList ( _ url : URL , parameters : Parameters , completion : @ escaping ( ( [ MPPositive_SongItemModel ] ) -> Void ) ) {
// 发 送 p o s t 请 求
AF . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonNext . self ) { [ weak self ] ( response ) in
MPSession . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonNext . self ) { [ weak self ] ( response ) in
guard let self = self else { return }
switch response . result {
case . success ( let value ) :
@ -497,15 +542,19 @@ extension MP_NetWorkManager {
]
]
]
requestStatusToYouTube { isAvailable in
if isAvailable = = true {
// 发 送 n e x t 列 表 歌 词 / 相 关 内 容 请 求
requestPostNextLyricsAndRelated ( url , parameters : parameters ) { result in
self . requestPostNextLyricsAndRelated ( url , parameters : parameters ) { result in
completion ( result )
}
}
}
}
// 请 求 请 求 N e x t 歌 词 / 相 关 内 容
private func requestPostNextLyricsAndRelated ( _ url : URL , parameters : Parameters , completion : @ escaping ( ( ( String ? , String ? ) ) -> Void ) ) {
// 发 送 p o s t 请 求
AF . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonNext . self ) { [ weak self ] ( response ) in
MPSession . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonNext . self ) { [ weak self ] ( response ) in
guard let self = self else { return }
switch response . result {
case . success ( let value ) :
@ -547,14 +596,18 @@ extension MP_NetWorkManager {
]
]
]
requestPostPlayer ( url , parameters : parameters ) { resourceUlrs , coverUrls in
requestStatusToYouTube { isAvailable in
if isAvailable = = true {
self . requestPostPlayer ( url , parameters : parameters ) { resourceUlrs , coverUrls in
completion ( resourceUlrs , coverUrls )
}
}
}
}
// 请 求 单 曲 / 视 频
private func requestPostPlayer ( _ url : URL , parameters : Parameters , completion : @ escaping ( ( ( [ String ] , [ String ] ) , [ String ] ? ) -> Void ) ) {
// 发 送 p o s t 请 求
AF . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonPlayer . self ) { [ weak self ] ( response ) in
MPSession . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonPlayer . self ) { [ weak self ] ( response ) in
guard let self = self else { return }
switch response . result {
@ -598,14 +651,18 @@ extension MP_NetWorkManager {
]
]
]
requestPostLyric ( url , parameters : parameters ) { lyrics in
requestStatusToYouTube { isAvailable in
if isAvailable = = true {
self . requestPostLyric ( url , parameters : parameters ) { lyrics in
completion ( lyrics )
}
}
}
}
// 请 求 歌 词
private func requestPostLyric ( _ url : URL , parameters : Parameters , completion : @ escaping ( ( String ) -> Void ) ) {
// 发 送 p o s t 请 求
AF . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonLyrics . self ) { [ weak self ] ( response ) in
MPSession . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonLyrics . self ) { [ weak self ] ( response ) in
guard let self = self else { return }
switch response . result {
case . success ( let value ) :
@ -644,14 +701,18 @@ extension MP_NetWorkManager {
]
]
]
requestPostRecommend ( url , parameters : parameters ) { results in
requestStatusToYouTube { isAvailable in
if isAvailable = = true {
self . requestPostRecommend ( url , parameters : parameters ) { results in
completion ( results )
}
}
}
}
// / 请 求 相 关 内 容
private func requestPostRecommend ( _ url : URL , parameters : Parameters , completion : @ escaping ( [ MPPositive_RecommendListViewModel ] ) -> Void ) {
// 发 送 p o s t 请 求
AF . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonRecommend . self ) { [ weak self ] ( response ) in
MPSession . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonRecommend . self ) { [ weak self ] ( response ) in
guard let self = self else { return }
switch response . result {
case . success ( let value ) :
@ -696,14 +757,18 @@ extension MP_NetWorkManager {
]
]
]
requestPostSearchSuggestions ( url , parameters : parameters ) { result in
requestStatusToYouTube { isAvailable in
if isAvailable = = true {
self . requestPostSearchSuggestions ( url , parameters : parameters ) { result in
completion ( result )
}
}
}
}
// 请 求 搜 索 建 议
private func requestPostSearchSuggestions ( _ url : URL , parameters : Parameters , completion : @ escaping ( ( [ [ MPPositive_SearchSuggestionItemModel ] ] ) -> Void ) ) {
// 发 送 p o s t 请 求
AF . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonSearchSuggestions . self ) { [ weak self ] ( response ) in
MPSession . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonSearchSuggestions . self ) { [ weak self ] ( response ) in
guard let self = self else { return }
switch response . result {
case . success ( let value ) :
@ -746,14 +811,18 @@ extension MP_NetWorkManager {
]
]
]
requestPostSearchPreviewResults ( url , parameters : parameters ) { result in
requestStatusToYouTube { isAvailable in
if isAvailable = = true {
self . requestPostSearchPreviewResults ( url , parameters : parameters ) { result in
completion ( result )
}
}
}
}
// 请 求 搜 索 预 览 结 果
private func requestPostSearchPreviewResults ( _ url : URL , parameters : Parameters , completion : @ escaping ( ( [ MPPositive_SearchResultListViewModel ] ) -> Void ) ) {
// 发 送 p o s t 请 求
AF . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonSearchPreviewResults . self ) { [ weak self ] ( response ) in
MPSession . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonSearchPreviewResults . self ) { [ weak self ] ( response ) in
guard let self = self else { return }
switch response . result {
case . success ( let value ) :
@ -802,14 +871,18 @@ extension MP_NetWorkManager {
]
]
]
requestPostSearchTypeResults ( url , parameters : parameters ) { result in
requestStatusToYouTube { isAvailable in
if isAvailable = = true {
self . requestPostSearchTypeResults ( url , parameters : parameters ) { result in
completion ( result )
}
}
}
}
// 请 求 搜 索 分 类 结 果
private func requestPostSearchTypeResults ( _ url : URL , parameters : Parameters , completion : @ escaping ( ( [ MPPositive_SearchResultItemViewModel ] , String ? , String ? ) ) -> Void ) {
// 发 送 p o s t 请 求
AF . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonSearchTypeResults . self ) { [ weak self ] ( response ) in
MPSession . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonSearchTypeResults . self ) { [ weak self ] ( response ) in
guard let self = self else { return }
switch response . result {
case . success ( let value ) :
@ -858,14 +931,18 @@ extension MP_NetWorkManager {
]
]
]
requestPostSearchTypeContinuation ( url , parameters : parameters ) { result in
requestStatusToYouTube { isAvailable in
if isAvailable = = true {
self . requestPostSearchTypeContinuation ( url , parameters : parameters ) { result in
completion ( result )
}
}
}
}
// 请 求 搜 索 分 类 继 续 结 果
private func requestPostSearchTypeContinuation ( _ url : URL , parameters : Parameters , completion : @ escaping ( ( [ MPPositive_SearchResultItemViewModel ] , String ? , String ? ) ) -> Void ) {
// 发 送 p o s t 请 求
AF . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonSearchTypeContinuation . self ) { [ weak self ] ( response ) in
MPSession . request ( url , method : . post , parameters : parameters , encoding : JSONEncoding . default ) . responseDecodable ( of : JsonSearchTypeContinuation . self ) { [ weak self ] ( response ) in
guard let self = self else { return }
switch response . result {
case . success ( let value ) :
@ -1674,4 +1751,33 @@ extension MP_NetWorkManager {
return decodedString
}
}
// MARK: - 自 动 重 试
// / 重 试 策 略 类
class MP_CustomRetrier : RequestInterceptor {
// 尝 试 重 试 次 数 的 最 大 值
private let maximumRetryCount = 3
// 请 求 与 其 对 应 的 重 试 次 数
private var retryCounts : [ String : Int ] = [ : ]
func retry ( _ request : Alamofire . Request , for session : Alamofire . Session , dueTo error : any Error , completion : @ escaping ( Alamofire . RetryResult ) -> Void ) {
// 根 据 请 求 的 i d 获 取 当 前 的 重 试 次 数
let requestID = request . id
let currentRetryCount = retryCounts [ requestID . uuidString ] ? ? 0
// 判 断 是 否 需 要 重 试 , 可 以 基 于 错 误 类 型 或 请 求 状 态 码 来 决 定
if currentRetryCount < maximumRetryCount , let response = request . task ? . response as ? HTTPURLResponse , response . statusCode = = 503 {
// 更 新 请 求 的 重 试 次 数
retryCounts [ requestID . uuidString ] = currentRetryCount + 1
// 在 1 秒 后 重 试 此 请 求
completion ( . retryWithDelay ( 1 ) )
print ( " 请求 \( requestID . uuidString ) 执行重复请求 " )
} else {
// 不 重 试 , 清 除 此 请 求 的 重 试 记 录
retryCounts [ requestID . uuidString ] = nil
completion ( . doNotRetry )
}
}
// 在 请 求 成 功 完 成 时 , 清 除 重 试 计 数
func requestDidFinish ( _ request : Request ) {
let requestID = request . id
retryCounts [ requestID . uuidString ] = nil
}
}