1.1.1数据结构更新
This commit is contained in:
parent
45455e7c6d
commit
130fefd189
@ -1312,7 +1312,9 @@ extension MP_NetWorkManager {
|
|||||||
content.musicCarouselShelfRenderer?.contents?.forEach({ content in
|
content.musicCarouselShelfRenderer?.contents?.forEach({ content in
|
||||||
//设置标题、歌手、专辑/列表
|
//设置标题、歌手、专辑/列表
|
||||||
if let musicResponsiveListItemRenderer = content.musicResponsiveListItemRenderer {
|
if let musicResponsiveListItemRenderer = content.musicResponsiveListItemRenderer {
|
||||||
browse.items.append(.init(parsingMusicResponsiveListItemRenderer(musicResponsiveListItemRenderer)))
|
if let item = parsingMusicResponsiveListItemRenderer(musicResponsiveListItemRenderer) {
|
||||||
|
browse.items.append(.init(item))
|
||||||
|
}
|
||||||
}else if let musicTwoRowItemRenderer = content.musicTwoRowItemRenderer {
|
}else if let musicTwoRowItemRenderer = content.musicTwoRowItemRenderer {
|
||||||
browse.items.append(.init(parsingMusicTwoRowItemRenderer(musicTwoRowItemRenderer)))
|
browse.items.append(.init(parsingMusicTwoRowItemRenderer(musicTwoRowItemRenderer)))
|
||||||
}
|
}
|
||||||
@ -1392,7 +1394,9 @@ extension MP_NetWorkManager {
|
|||||||
content.musicCarouselShelfRenderer?.contents?.forEach({ content in
|
content.musicCarouselShelfRenderer?.contents?.forEach({ content in
|
||||||
//设置标题、歌手、专辑/列表
|
//设置标题、歌手、专辑/列表
|
||||||
if let musicResponsiveListItemRenderer = content.musicResponsiveListItemRenderer {
|
if let musicResponsiveListItemRenderer = content.musicResponsiveListItemRenderer {
|
||||||
browse.items.append(.init(parsingMusicResponsiveListItemRenderer(musicResponsiveListItemRenderer)))
|
if let item = parsingMusicResponsiveListItemRenderer(musicResponsiveListItemRenderer) {
|
||||||
|
browse.items.append(.init(item))
|
||||||
|
}
|
||||||
}else if let musicTwoRowItemRenderer = content.musicTwoRowItemRenderer {
|
}else if let musicTwoRowItemRenderer = content.musicTwoRowItemRenderer {
|
||||||
browse.items.append(.init(parsingMusicTwoRowItemRenderer(musicTwoRowItemRenderer)))
|
browse.items.append(.init(parsingMusicTwoRowItemRenderer(musicTwoRowItemRenderer)))
|
||||||
}
|
}
|
||||||
@ -1421,7 +1425,9 @@ extension MP_NetWorkManager {
|
|||||||
musicPlaylistShelfRenderer.contents?.forEach({ content in
|
musicPlaylistShelfRenderer.contents?.forEach({ content in
|
||||||
//设置标题、歌手、专辑/列表
|
//设置标题、歌手、专辑/列表
|
||||||
if let musicResponsiveListItemRenderer = content.musicResponsiveListItemRenderer {
|
if let musicResponsiveListItemRenderer = content.musicResponsiveListItemRenderer {
|
||||||
items.append(.init(parsingMusicResponsiveListItemRenderer(musicResponsiveListItemRenderer)))
|
if let item = parsingMusicResponsiveListItemRenderer(musicResponsiveListItemRenderer) {
|
||||||
|
items.append(.init(item))
|
||||||
|
}
|
||||||
}else if let musicTwoRowItemRenderer = content.musicTwoRowItemRenderer {
|
}else if let musicTwoRowItemRenderer = content.musicTwoRowItemRenderer {
|
||||||
items.append(.init(parsingMusicTwoRowItemRenderer(musicTwoRowItemRenderer)))
|
items.append(.init(parsingMusicTwoRowItemRenderer(musicTwoRowItemRenderer)))
|
||||||
}
|
}
|
||||||
@ -1430,7 +1436,9 @@ extension MP_NetWorkManager {
|
|||||||
musicShelfRenderer.contents?.forEach({ content in
|
musicShelfRenderer.contents?.forEach({ content in
|
||||||
//设置标题、歌手、专辑/列表
|
//设置标题、歌手、专辑/列表
|
||||||
if let musicResponsiveListItemRenderer = content.musicResponsiveListItemRenderer {
|
if let musicResponsiveListItemRenderer = content.musicResponsiveListItemRenderer {
|
||||||
items.append(.init(parsingMusicResponsiveListItemRenderer(musicResponsiveListItemRenderer)))
|
if let item = parsingMusicResponsiveListItemRenderer(musicResponsiveListItemRenderer) {
|
||||||
|
items.append(.init(item))
|
||||||
|
}
|
||||||
}else if let musicTwoRowItemRenderer = content.musicTwoRowItemRenderer {
|
}else if let musicTwoRowItemRenderer = content.musicTwoRowItemRenderer {
|
||||||
items.append(.init(parsingMusicTwoRowItemRenderer(musicTwoRowItemRenderer)))
|
items.append(.init(parsingMusicTwoRowItemRenderer(musicTwoRowItemRenderer)))
|
||||||
}
|
}
|
||||||
@ -1449,7 +1457,9 @@ extension MP_NetWorkManager {
|
|||||||
musicPlaylistShelfRenderer.contents?.forEach({ content in
|
musicPlaylistShelfRenderer.contents?.forEach({ content in
|
||||||
//设置标题、歌手、专辑/列表
|
//设置标题、歌手、专辑/列表
|
||||||
if let musicResponsiveListItemRenderer = content.musicResponsiveListItemRenderer {
|
if let musicResponsiveListItemRenderer = content.musicResponsiveListItemRenderer {
|
||||||
items.append(.init(parsingMusicResponsiveListItemRenderer(musicResponsiveListItemRenderer)))
|
if let item = parsingMusicResponsiveListItemRenderer(musicResponsiveListItemRenderer) {
|
||||||
|
items.append(.init(item))
|
||||||
|
}
|
||||||
}else if let musicTwoRowItemRenderer = content.musicTwoRowItemRenderer {
|
}else if let musicTwoRowItemRenderer = content.musicTwoRowItemRenderer {
|
||||||
items.append(.init(parsingMusicTwoRowItemRenderer(musicTwoRowItemRenderer)))
|
items.append(.init(parsingMusicTwoRowItemRenderer(musicTwoRowItemRenderer)))
|
||||||
}
|
}
|
||||||
@ -1458,7 +1468,9 @@ extension MP_NetWorkManager {
|
|||||||
musicShelfRenderer.contents?.forEach({ content in
|
musicShelfRenderer.contents?.forEach({ content in
|
||||||
//设置标题、歌手、专辑/列表
|
//设置标题、歌手、专辑/列表
|
||||||
if let musicResponsiveListItemRenderer = content.musicResponsiveListItemRenderer {
|
if let musicResponsiveListItemRenderer = content.musicResponsiveListItemRenderer {
|
||||||
items.append(.init(parsingMusicResponsiveListItemRenderer(musicResponsiveListItemRenderer)))
|
if let item = parsingMusicResponsiveListItemRenderer(musicResponsiveListItemRenderer) {
|
||||||
|
items.append(.init(item))
|
||||||
|
}
|
||||||
}else if let musicTwoRowItemRenderer = content.musicTwoRowItemRenderer {
|
}else if let musicTwoRowItemRenderer = content.musicTwoRowItemRenderer {
|
||||||
items.append(.init(parsingMusicTwoRowItemRenderer(musicTwoRowItemRenderer)))
|
items.append(.init(parsingMusicTwoRowItemRenderer(musicTwoRowItemRenderer)))
|
||||||
}
|
}
|
||||||
@ -1540,8 +1552,8 @@ extension MP_NetWorkManager {
|
|||||||
params = musicShelfRenderer.title?.runs?.first?.navigationEndpoint?.browseEndpoint?.params
|
params = musicShelfRenderer.title?.runs?.first?.navigationEndpoint?.browseEndpoint?.params
|
||||||
//解析模块内容
|
//解析模块内容
|
||||||
musicShelfRenderer.contents?.forEach({ item in
|
musicShelfRenderer.contents?.forEach({ item in
|
||||||
if item.musicResponsiveListItemRenderer != nil {
|
if let musicResponsiveListItemRenderer = item.musicResponsiveListItemRenderer, let asd = parsingMusicResponsiveListItemRenderer(musicResponsiveListItemRenderer) {
|
||||||
itemViews.append(.init(parsingMusicResponsiveListItemRenderer(item.musicResponsiveListItemRenderer!)))
|
itemViews.append(.init(asd))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -1573,7 +1585,9 @@ extension MP_NetWorkManager {
|
|||||||
//是音视频
|
//是音视频
|
||||||
musicPlaylistShelfRenderer.contents?.forEach({ item in
|
musicPlaylistShelfRenderer.contents?.forEach({ item in
|
||||||
if let musicResponsiveListItemRenderer = item.musicResponsiveListItemRenderer {
|
if let musicResponsiveListItemRenderer = item.musicResponsiveListItemRenderer {
|
||||||
array.append(.init(parsingMusicResponsiveListItemRenderer(musicResponsiveListItemRenderer)))
|
if let asd = parsingMusicResponsiveListItemRenderer(musicResponsiveListItemRenderer) {
|
||||||
|
array.append(.init(asd))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
continuation = musicPlaylistShelfRenderer.continuations?.first?.nextContinuationData?.continuation
|
continuation = musicPlaylistShelfRenderer.continuations?.first?.nextContinuationData?.continuation
|
||||||
@ -1601,7 +1615,9 @@ extension MP_NetWorkManager {
|
|||||||
if let contents = musicPlaylistShelfContinuation.contents {
|
if let contents = musicPlaylistShelfContinuation.contents {
|
||||||
contents.forEach { item in
|
contents.forEach { item in
|
||||||
if let musicResponsiveListItemRenderer = item.musicResponsiveListItemRenderer {
|
if let musicResponsiveListItemRenderer = item.musicResponsiveListItemRenderer {
|
||||||
array.append(.init(parsingMusicResponsiveListItemRenderer(musicResponsiveListItemRenderer)))
|
if let asd = parsingMusicResponsiveListItemRenderer(musicResponsiveListItemRenderer) {
|
||||||
|
array.append(.init(asd))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1810,9 +1826,10 @@ extension MP_NetWorkManager {
|
|||||||
let list = MPPositive_RecommendListViewModel()
|
let list = MPPositive_RecommendListViewModel()
|
||||||
list.title = section.musicCarouselShelfRenderer?.header?.musicCarouselShelfBasicHeaderRenderer?.title?.runs?.reduce("", { $0 + ($1.text ?? "")})
|
list.title = section.musicCarouselShelfRenderer?.header?.musicCarouselShelfBasicHeaderRenderer?.title?.runs?.reduce("", { $0 + ($1.text ?? "")})
|
||||||
section.musicCarouselShelfRenderer?.contents?.forEach({ content in
|
section.musicCarouselShelfRenderer?.contents?.forEach({ content in
|
||||||
if content.musicResponsiveListItemRenderer != nil {
|
if let musicResponsiveListItemRenderer = content.musicResponsiveListItemRenderer{
|
||||||
let item = parsingMusicResponsiveListItemRenderer(content.musicResponsiveListItemRenderer!)
|
if let item = parsingMusicResponsiveListItemRenderer(musicResponsiveListItemRenderer) {
|
||||||
list.items.append(.init(item))
|
list.items.append(.init(item))
|
||||||
|
}
|
||||||
}else if content.musicTwoRowItemRenderer != nil {
|
}else if content.musicTwoRowItemRenderer != nil {
|
||||||
let item = parsingMusicTwoRowItemRenderer(content.musicTwoRowItemRenderer!)
|
let item = parsingMusicTwoRowItemRenderer(content.musicTwoRowItemRenderer!)
|
||||||
list.items.append(.init(item))
|
list.items.append(.init(item))
|
||||||
@ -1968,45 +1985,7 @@ extension MP_NetWorkManager {
|
|||||||
//设置内容块
|
//设置内容块
|
||||||
musicShelfRenderer.contents?.forEach({ content in
|
musicShelfRenderer.contents?.forEach({ content in
|
||||||
//专辑/列表/单曲视频/艺术家
|
//专辑/列表/单曲视频/艺术家
|
||||||
let item = MPPositive_BrowseItemModel()
|
if let musicResponsiveListItemRenderer = content.musicResponsiveListItemRenderer, let item = parsingMusicResponsiveListItemRenderer(musicResponsiveListItemRenderer) {
|
||||||
if (content.musicResponsiveListItemRenderer?.playlistItemData != nil || content.musicResponsiveListItemRenderer?.navigationEndpoint != nil) && (content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE") {
|
|
||||||
//设置内容块的封面
|
|
||||||
item.coverUrls = content.musicResponsiveListItemRenderer?.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.map({$0.url ?? ""})
|
|
||||||
//设置一级标题与二级标题
|
|
||||||
for (index, flexColumn) in (content.musicResponsiveListItemRenderer?.flexColumns ?? []).enumerated() {
|
|
||||||
if index == 0 {
|
|
||||||
//一级标题
|
|
||||||
item.title = flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.reduce("", { $0 + ($1.text ?? "")})
|
|
||||||
item.pageType = flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.first?.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType
|
|
||||||
}else {
|
|
||||||
//二级标题
|
|
||||||
item.subtitle = (item.subtitle ?? "") + (flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.reduce("", { $0 + ($1.text ?? "")}) ?? "")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
item.playListId = content.musicResponsiveListItemRenderer?.menu?.menuRenderer?.items?.first?.menuNavigationItemRenderer?.navigationEndpoint?.watchEndpoint?.playlistId
|
|
||||||
//设置id和类型
|
|
||||||
if content.musicResponsiveListItemRenderer?.playlistItemData != nil {
|
|
||||||
//是单曲
|
|
||||||
item.itemType = .single
|
|
||||||
item.videoId = content.musicResponsiveListItemRenderer?.playlistItemData?.videoId
|
|
||||||
}else {
|
|
||||||
//是专辑列表/艺术家
|
|
||||||
item.browseId = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId
|
|
||||||
let pageType = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType
|
|
||||||
if youTubeKeys.contains(pageType ?? "") == true && pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE" {
|
|
||||||
//判断细分
|
|
||||||
if pageType == "MUSIC_PAGE_TYPE_ARTIST" {
|
|
||||||
item.artistId = content.musicResponsiveListItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId
|
|
||||||
//是艺术家
|
|
||||||
item.itemType = .artist
|
|
||||||
}else {
|
|
||||||
//是列表/专辑
|
|
||||||
item.itemType = .list
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if item.itemType != nil, item.title != nil, item.pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE" {
|
|
||||||
resultList.previewItemViews.append(.init(item))
|
resultList.previewItemViews.append(.init(item))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -2146,55 +2125,87 @@ extension MP_NetWorkManager {
|
|||||||
return (array, continuation, clickTrackingParams)
|
return (array, continuation, clickTrackingParams)
|
||||||
}
|
}
|
||||||
//MARK: - 解析具体内容形式
|
//MARK: - 解析具体内容形式
|
||||||
//解析musicResponsiveListItemRenderer(通常是音视频内容)
|
//解析musicResponsiveListItemRenderer(四组件内容)
|
||||||
private func parsingMusicResponsiveListItemRenderer(_ musicResponsiveListItemRenderer: RootMusicResponsiveListItemRenderer) -> MPPositive_BrowseItemModel {
|
private func parsingMusicResponsiveListItemRenderer(_ musicResponsiveListItemRenderer: RootMusicResponsiveListItemRenderer) -> MPPositive_BrowseItemModel? {
|
||||||
//生成一个音乐模型接收数据
|
//生成一个音乐模型接收数据
|
||||||
let item = MPPositive_BrowseItemModel()
|
let item = MPPositive_BrowseItemModel()
|
||||||
//预览图片路径
|
//预览图片路径
|
||||||
item.coverUrls = musicResponsiveListItemRenderer.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.compactMap({$0.url})
|
item.coverUrls = musicResponsiveListItemRenderer.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.compactMap({$0.url})
|
||||||
//设置主副标题
|
//判断预览项性质,并继续补完数据
|
||||||
if let flexColumns = musicResponsiveListItemRenderer.flexColumns {
|
|
||||||
for (index,flexColumn) in flexColumns.enumerated() {
|
|
||||||
if index == 0 {
|
|
||||||
//添加主标题
|
|
||||||
item.title = flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.reduce("", { $0 + ($1.text ?? "")})
|
|
||||||
item.playListId = flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.first?.navigationEndpoint?.watchEndpoint?.playlistId
|
|
||||||
}else{
|
|
||||||
item.subtitle = (item.subtitle ?? "") + (flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.reduce("", { $0 + ($1.text ?? "")}) ?? "")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if item.playListId == nil {
|
|
||||||
//通过操作菜单获取playListId
|
|
||||||
item.playListId = musicResponsiveListItemRenderer.menu?.menuRenderer?.items?.first?.menuNavigationItemRenderer?.navigationEndpoint?.watchEndpoint?.playlistId
|
|
||||||
}
|
|
||||||
//判断这个内容是音视频还是专辑列表艺术家
|
|
||||||
if let playlistItemData = musicResponsiveListItemRenderer.playlistItemData {
|
if let playlistItemData = musicResponsiveListItemRenderer.playlistItemData {
|
||||||
//是音视频
|
//当前预览项是视频/单曲
|
||||||
item.itemType = .single
|
item.itemType = .single
|
||||||
item.videoId = playlistItemData.videoId
|
item.videoId = playlistItemData.videoId
|
||||||
item.pageType = "MUSIC_VIDEO_TYPE_ATV"
|
//设置主副标题
|
||||||
}
|
guard var flexColumns = musicResponsiveListItemRenderer.flexColumns, flexColumns.isEmpty != true else {
|
||||||
if let navigationEndpoint = musicResponsiveListItemRenderer.navigationEndpoint {
|
return nil
|
||||||
//是专辑列表艺术家
|
|
||||||
if navigationEndpoint.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType == "MUSIC_PAGE_TYPE_ARTIST" && navigationEndpoint.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE" {
|
|
||||||
//是艺术家
|
|
||||||
item.itemType = .artist
|
|
||||||
item.artistId = navigationEndpoint.browseEndpoint?.browseId
|
|
||||||
item.pageType = "MUSIC_PAGE_TYPE_ARTIST"
|
|
||||||
}else {
|
|
||||||
if navigationEndpoint.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType != "MUSIC_PAGE_TYPE_NON_MUSIC_AUDIO_TRACK_PAGE" {
|
|
||||||
//是专辑列表
|
|
||||||
item.itemType = .list
|
|
||||||
item.pageType = navigationEndpoint.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType
|
|
||||||
item.browseId = navigationEndpoint.browseEndpoint?.browseId
|
|
||||||
item.params = navigationEndpoint.browseEndpoint?.params
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
//主标题为第一位,同时VideoId,PlayListId,pageType都以第一个flexColumn为主
|
||||||
|
let first = flexColumns.removeFirst()
|
||||||
|
item.title = first.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.reduce("", { $0 + ($1.text ?? "")})
|
||||||
|
//判断watchEndpoint(资源导向)是否存在
|
||||||
|
guard let watchEndpoint = first.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.first?.navigationEndpoint?.watchEndpoint else {return nil}
|
||||||
|
//watchEndpoint内容赋值给item
|
||||||
|
item.playListId = watchEndpoint.playlistId
|
||||||
|
item.pageType = watchEndpoint.watchEndpointMusicSupportedConfigs?.watchEndpointMusicConfig?.musicVideoType
|
||||||
|
//设置副标题,通常为作者/专辑
|
||||||
|
flexColumns.forEach { flexColumn in
|
||||||
|
item.subtitle = (item.subtitle ?? "") + (flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.reduce("", { $0 + ($1.text ?? "")}) ?? "")
|
||||||
}
|
}
|
||||||
|
//继续补完videoId,检索是否具备playListId,当playListId为空时,说明并没有成功补完,需要使用菜单结构补全内容
|
||||||
|
guard (item.playListId ?? "").isEmpty == true else {
|
||||||
|
//不为空,说明需要的数据已经补完了
|
||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
//解析musicResponsiveListItemRenderer(是列表专辑内容)
|
//未补完,继续
|
||||||
|
if let watchItem = musicResponsiveListItemRenderer.menu?.menuRenderer?.items?.first(where: {$0.menuNavigationItemRenderer?.navigationEndpoint?.watchEndpoint != nil}) {
|
||||||
|
item.playListId = watchItem.menuNavigationItemRenderer?.navigationEndpoint?.watchEndpoint?.playlistId
|
||||||
|
return item
|
||||||
|
}else {
|
||||||
|
//补完失败
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}else if let navigationEndpoint = musicResponsiveListItemRenderer.navigationEndpoint {
|
||||||
|
//是专辑/艺术家/歌单
|
||||||
|
//设置主副标题
|
||||||
|
guard var flexColumns = musicResponsiveListItemRenderer.flexColumns, flexColumns.isEmpty != true else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
//主标题为第一位,其余内容都是副标题
|
||||||
|
let first = flexColumns.removeFirst()
|
||||||
|
item.title = first.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.reduce("", { $0 + ($1.text ?? "")})
|
||||||
|
//设置副标题,通常为作者/专辑
|
||||||
|
flexColumns.forEach { flexColumn in
|
||||||
|
item.subtitle = (item.subtitle ?? "") + (flexColumn.musicResponsiveListItemFlexColumnRenderer?.text?.runs?.reduce("", { $0 + ($1.text ?? "")}) ?? "")
|
||||||
|
}
|
||||||
|
//设置预览Id
|
||||||
|
guard let browseEndpoint = navigationEndpoint.browseEndpoint else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
item.browseId = browseEndpoint.browseId
|
||||||
|
//根据pageType确定导航至何处
|
||||||
|
guard let pageType = browseEndpoint.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType else {return nil}
|
||||||
|
item.pageType = pageType
|
||||||
|
if pageType == "MUSIC_PAGE_TYPE_ALBUM" {
|
||||||
|
//专辑
|
||||||
|
item.itemType = .list
|
||||||
|
return item
|
||||||
|
}else if pageType == "MUSIC_PAGE_TYPE_PLAYLIST" {
|
||||||
|
//列表
|
||||||
|
item.itemType = .list
|
||||||
|
return item
|
||||||
|
}else if pageType == "MUSIC_PAGE_TYPE_ARTIST" {
|
||||||
|
//艺术家
|
||||||
|
item.itemType = .artist
|
||||||
|
return item
|
||||||
|
}else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//解析musicResponsiveListItemRenderer(三组件结构)
|
||||||
private func parsingMusicTwoRowItemRenderer(_ musicTwoRowItemRenderer: RootMusicTwoRowItemRenderer) -> MPPositive_BrowseItemModel {
|
private func parsingMusicTwoRowItemRenderer(_ musicTwoRowItemRenderer: RootMusicTwoRowItemRenderer) -> MPPositive_BrowseItemModel {
|
||||||
//生成一个音乐模型接收数据
|
//生成一个音乐模型接收数据
|
||||||
let item = MPPositive_BrowseItemModel()
|
let item = MPPositive_BrowseItemModel()
|
||||||
@ -2224,7 +2235,6 @@ extension MP_NetWorkManager {
|
|||||||
item.itemType = .list
|
item.itemType = .list
|
||||||
item.pageType = browseEndpoint.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType
|
item.pageType = browseEndpoint.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType
|
||||||
item.browseId = browseEndpoint.browseId
|
item.browseId = browseEndpoint.browseId
|
||||||
item.params = browseEndpoint.params
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return item
|
return item
|
||||||
|
|||||||
@ -469,32 +469,33 @@ struct JsonBrowses: Codable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//MARK: - 图像信息数据结构
|
//MARK: - 图像信息数据结构
|
||||||
///单曲/视频结构(通常是四组件构成,封面,一级标题,二级标题,额外包含ID内容)
|
///四组件结构(通常是四组件构成,封面,一级标题,二级标题,额外包含ID内容),根据playlistItemData和navigationEndpoint两者来敲定该预览项属于(播放/导航)一种,并继续下分
|
||||||
struct RootMusicResponsiveListItemRenderer: Codable {
|
struct RootMusicResponsiveListItemRenderer: Codable {
|
||||||
///指向封面图像
|
///指向封面图像
|
||||||
let thumbnail:Thumbnail?
|
let thumbnail:Thumbnail?
|
||||||
///指向标题歌手专辑(通常有多位,0位是标题,后续都为副标题)
|
///指向标题歌手专辑(通常有多位,0位是标题,后续都为副标题)
|
||||||
let flexColumns:[FlexColumn]?
|
let flexColumns:[FlexColumn]?
|
||||||
///菜单操作(某些情况下flexColumns无法拿到playListId)
|
|
||||||
let menu:Menu?
|
|
||||||
///单曲/视频ID(playlistItemData存在说明这条数据单曲/视频)
|
///单曲/视频ID(playlistItemData存在说明这条数据单曲/视频)
|
||||||
let playlistItemData:PlaylistItemData?
|
let playlistItemData:PlaylistItemData?
|
||||||
///专辑/歌单ID(navigationEndpoint存在说明这条数据是专辑/歌单)
|
///页面导向(navigationEndpoint存在时,说明这条数据将会作为跳转内容导向一个页面)
|
||||||
let navigationEndpoint:NavigationEndpoint?
|
let navigationEndpoint:NavigationEndpoint?
|
||||||
|
///菜单(当playlistItemData存在,且无法通过flexColumns获得PlayListID时,调用菜单强制获得playListId)
|
||||||
|
let menu:Menu?
|
||||||
|
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
case thumbnail = "thumbnail"
|
case thumbnail = "thumbnail"
|
||||||
case flexColumns = "flexColumns"
|
case flexColumns = "flexColumns"
|
||||||
case menu = "menu"
|
|
||||||
case playlistItemData = "playlistItemData"
|
case playlistItemData = "playlistItemData"
|
||||||
case navigationEndpoint = "navigationEndpoint"
|
case navigationEndpoint = "navigationEndpoint"
|
||||||
|
case menu = "menu"
|
||||||
}
|
}
|
||||||
init(from decoder: Decoder) throws {
|
init(from decoder: Decoder) throws {
|
||||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail)
|
thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail)
|
||||||
flexColumns = try values.decodeIfPresent([FlexColumn].self, forKey: .flexColumns)
|
flexColumns = try values.decodeIfPresent([FlexColumn].self, forKey: .flexColumns)
|
||||||
menu = try values.decodeIfPresent(Menu.self, forKey: .menu)
|
|
||||||
playlistItemData = try values.decodeIfPresent(PlaylistItemData.self, forKey: .playlistItemData)
|
playlistItemData = try values.decodeIfPresent(PlaylistItemData.self, forKey: .playlistItemData)
|
||||||
navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint)
|
navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint)
|
||||||
|
menu = try values.decodeIfPresent(Menu.self, forKey: .menu)
|
||||||
}
|
}
|
||||||
//含有封面图像
|
//含有封面图像
|
||||||
struct Thumbnail: Codable {
|
struct Thumbnail: Codable {
|
||||||
@ -573,6 +574,7 @@ struct RootMusicResponsiveListItemRenderer: Codable {
|
|||||||
struct Run: Codable {
|
struct Run: Codable {
|
||||||
///标题文本
|
///标题文本
|
||||||
let text:String?
|
let text:String?
|
||||||
|
///文本导航
|
||||||
let navigationEndpoint:NavigationEndpoint?
|
let navigationEndpoint:NavigationEndpoint?
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
case text = "text"
|
case text = "text"
|
||||||
@ -583,108 +585,9 @@ struct RootMusicResponsiveListItemRenderer: Codable {
|
|||||||
text = try values.decodeIfPresent(String.self, forKey: .text)
|
text = try values.decodeIfPresent(String.self, forKey: .text)
|
||||||
navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint)
|
navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint)
|
||||||
}
|
}
|
||||||
|
//文本导航
|
||||||
struct NavigationEndpoint: Codable {
|
struct NavigationEndpoint: Codable {
|
||||||
let watchEndpoint:WatchEndpoint?
|
///资源特化
|
||||||
let browseEndpoint:BrowseEndpoint?
|
|
||||||
enum CodingKeys: String, CodingKey {
|
|
||||||
case watchEndpoint = "watchEndpoint"
|
|
||||||
case browseEndpoint = "browseEndpoint"
|
|
||||||
}
|
|
||||||
init(from decoder: Decoder) throws {
|
|
||||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
|
||||||
watchEndpoint = try values.decodeIfPresent(WatchEndpoint.self, forKey: .watchEndpoint)
|
|
||||||
browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint)
|
|
||||||
}
|
|
||||||
struct WatchEndpoint: Codable {
|
|
||||||
let playlistId:String?
|
|
||||||
enum CodingKeys: String, CodingKey {
|
|
||||||
case playlistId = "playlistId"
|
|
||||||
}
|
|
||||||
init(from decoder: Decoder) throws {
|
|
||||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
|
||||||
playlistId = try values.decodeIfPresent(String.self, forKey: .playlistId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
struct BrowseEndpoint: Codable {
|
|
||||||
let browseId:String?
|
|
||||||
let params:String?
|
|
||||||
let browseEndpointContextSupportedConfigs:BrowseEndpointContextSupportedConfigs?
|
|
||||||
enum CodingKeys: String, CodingKey {
|
|
||||||
case browseId = "browseId"
|
|
||||||
case params = "params"
|
|
||||||
case browseEndpointContextSupportedConfigs = "browseEndpointContextSupportedConfigs"
|
|
||||||
}
|
|
||||||
init(from decoder: Decoder) throws {
|
|
||||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
|
||||||
browseId = try values.decodeIfPresent(String.self, forKey: .browseId)
|
|
||||||
params = try values.decodeIfPresent(String.self, forKey: .params)
|
|
||||||
browseEndpointContextSupportedConfigs = try values.decodeIfPresent(BrowseEndpointContextSupportedConfigs.self, forKey: .browseEndpointContextSupportedConfigs)
|
|
||||||
}
|
|
||||||
struct BrowseEndpointContextSupportedConfigs: Codable {
|
|
||||||
let browseEndpointContextMusicConfig:BrowseEndpointContextMusicConfig?
|
|
||||||
enum CodingKeys: String, CodingKey {
|
|
||||||
case browseEndpointContextMusicConfig = "browseEndpointContextMusicConfig"
|
|
||||||
}
|
|
||||||
init(from decoder: Decoder) throws {
|
|
||||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
|
||||||
browseEndpointContextMusicConfig = try values.decodeIfPresent(BrowseEndpointContextMusicConfig.self, forKey: .browseEndpointContextMusicConfig)
|
|
||||||
}
|
|
||||||
struct BrowseEndpointContextMusicConfig: Codable {
|
|
||||||
let pageType:String?
|
|
||||||
enum CodingKeys: String, CodingKey {
|
|
||||||
case pageType = "pageType"
|
|
||||||
}
|
|
||||||
init(from decoder: Decoder) throws {
|
|
||||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
|
||||||
pageType = try values.decodeIfPresent(String.self, forKey: .pageType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//菜单操作
|
|
||||||
struct Menu: Codable {
|
|
||||||
let menuRenderer:MenuRenderer?
|
|
||||||
enum CodingKeys: String, CodingKey {
|
|
||||||
case menuRenderer = "menuRenderer"
|
|
||||||
}
|
|
||||||
init(from decoder: Decoder) throws {
|
|
||||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
|
||||||
menuRenderer = try values.decodeIfPresent(MenuRenderer.self, forKey: .menuRenderer)
|
|
||||||
}
|
|
||||||
struct MenuRenderer: Codable {
|
|
||||||
let items:[Item]?
|
|
||||||
enum CodingKeys: String, CodingKey {
|
|
||||||
case items = "items"
|
|
||||||
}
|
|
||||||
init(from decoder: Decoder) throws {
|
|
||||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
|
||||||
items = try values.decodeIfPresent([Item].self, forKey: .items)
|
|
||||||
}
|
|
||||||
struct Item: Codable {
|
|
||||||
let menuNavigationItemRenderer:MenuNavigationItemRenderer?
|
|
||||||
enum CodingKeys: String, CodingKey {
|
|
||||||
case menuNavigationItemRenderer = "menuNavigationItemRenderer"
|
|
||||||
}
|
|
||||||
init(from decoder: Decoder) throws {
|
|
||||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
|
||||||
menuNavigationItemRenderer = try values.decodeIfPresent(MenuNavigationItemRenderer.self, forKey: .menuNavigationItemRenderer)
|
|
||||||
}
|
|
||||||
struct MenuNavigationItemRenderer: Codable {
|
|
||||||
let navigationEndpoint:NavigationEndpoint?
|
|
||||||
enum CodingKeys: String, CodingKey {
|
|
||||||
case navigationEndpoint = "navigationEndpoint"
|
|
||||||
}
|
|
||||||
init(from decoder: Decoder) throws {
|
|
||||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
|
||||||
navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint)
|
|
||||||
}
|
|
||||||
|
|
||||||
struct NavigationEndpoint: Codable {
|
|
||||||
let watchEndpoint:WatchEndpoint?
|
let watchEndpoint:WatchEndpoint?
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
case watchEndpoint = "watchEndpoint"
|
case watchEndpoint = "watchEndpoint"
|
||||||
@ -693,14 +596,43 @@ struct RootMusicResponsiveListItemRenderer: Codable {
|
|||||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
watchEndpoint = try values.decodeIfPresent(WatchEndpoint.self, forKey: .watchEndpoint)
|
watchEndpoint = try values.decodeIfPresent(WatchEndpoint.self, forKey: .watchEndpoint)
|
||||||
}
|
}
|
||||||
|
//导向播放
|
||||||
struct WatchEndpoint: Codable {
|
struct WatchEndpoint: Codable {
|
||||||
|
///资源ID
|
||||||
|
let videoId:String?
|
||||||
|
///对应歌单ID(未必存在)
|
||||||
let playlistId:String?
|
let playlistId:String?
|
||||||
|
///指向资源类型
|
||||||
|
let watchEndpointMusicSupportedConfigs:WatchEndpointMusicSupportedConfigs?
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case videoId = "videoId"
|
||||||
case playlistId = "playlistId"
|
case playlistId = "playlistId"
|
||||||
|
case watchEndpointMusicSupportedConfigs = "watchEndpointMusicSupportedConfigs"
|
||||||
}
|
}
|
||||||
init(from decoder: Decoder) throws {
|
init(from decoder: Decoder) throws {
|
||||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
videoId = try values.decodeIfPresent(String.self, forKey: .videoId)
|
||||||
playlistId = try values.decodeIfPresent(String.self, forKey: .playlistId)
|
playlistId = try values.decodeIfPresent(String.self, forKey: .playlistId)
|
||||||
|
watchEndpointMusicSupportedConfigs = try values.decodeIfPresent(WatchEndpointMusicSupportedConfigs.self, forKey: .watchEndpointMusicSupportedConfigs)
|
||||||
|
}
|
||||||
|
struct WatchEndpointMusicSupportedConfigs: Codable {
|
||||||
|
let watchEndpointMusicConfig:WatchEndpointMusicConfig?
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case watchEndpointMusicConfig = "watchEndpointMusicConfig"
|
||||||
|
}
|
||||||
|
init(from decoder: Decoder) throws {
|
||||||
|
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
watchEndpointMusicConfig = try values.decodeIfPresent(WatchEndpointMusicConfig.self, forKey: .watchEndpointMusicConfig)
|
||||||
|
}
|
||||||
|
struct WatchEndpointMusicConfig: Codable {
|
||||||
|
///资源类型
|
||||||
|
let musicVideoType:String?
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case musicVideoType = "musicVideoType"
|
||||||
|
}
|
||||||
|
init(from decoder: Decoder) throws {
|
||||||
|
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
musicVideoType = try values.decodeIfPresent(String.self, forKey: .musicVideoType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -708,6 +640,9 @@ struct RootMusicResponsiveListItemRenderer: Codable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//歌曲详细数据内容
|
||||||
struct PlaylistItemData: Codable {
|
struct PlaylistItemData: Codable {
|
||||||
let videoId:String?
|
let videoId:String?
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
@ -718,6 +653,7 @@ struct RootMusicResponsiveListItemRenderer: Codable {
|
|||||||
videoId = try values.decodeIfPresent(String.self, forKey: .videoId)
|
videoId = try values.decodeIfPresent(String.self, forKey: .videoId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//页面导向
|
||||||
struct NavigationEndpoint: Codable {
|
struct NavigationEndpoint: Codable {
|
||||||
let browseEndpoint:BrowseEndpoint?
|
let browseEndpoint:BrowseEndpoint?
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
@ -728,18 +664,16 @@ struct RootMusicResponsiveListItemRenderer: Codable {
|
|||||||
browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint)
|
browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint)
|
||||||
}
|
}
|
||||||
struct BrowseEndpoint: Codable {
|
struct BrowseEndpoint: Codable {
|
||||||
|
///预览ID,根据类型不同,视作不同作用
|
||||||
let browseId:String?
|
let browseId:String?
|
||||||
let params:String?
|
|
||||||
let browseEndpointContextSupportedConfigs:BrowseEndpointContextSupportedConfigs?
|
let browseEndpointContextSupportedConfigs:BrowseEndpointContextSupportedConfigs?
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
case browseId = "browseId"
|
case browseId = "browseId"
|
||||||
case params = "params"
|
|
||||||
case browseEndpointContextSupportedConfigs = "browseEndpointContextSupportedConfigs"
|
case browseEndpointContextSupportedConfigs = "browseEndpointContextSupportedConfigs"
|
||||||
}
|
}
|
||||||
init(from decoder: Decoder) throws {
|
init(from decoder: Decoder) throws {
|
||||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
browseId = try values.decodeIfPresent(String.self, forKey: .browseId)
|
browseId = try values.decodeIfPresent(String.self, forKey: .browseId)
|
||||||
params = try values.decodeIfPresent(String.self, forKey: .params)
|
|
||||||
browseEndpointContextSupportedConfigs = try values.decodeIfPresent(BrowseEndpointContextSupportedConfigs.self, forKey: .browseEndpointContextSupportedConfigs)
|
browseEndpointContextSupportedConfigs = try values.decodeIfPresent(BrowseEndpointContextSupportedConfigs.self, forKey: .browseEndpointContextSupportedConfigs)
|
||||||
}
|
}
|
||||||
struct BrowseEndpointContextSupportedConfigs: Codable {
|
struct BrowseEndpointContextSupportedConfigs: Codable {
|
||||||
@ -752,6 +686,7 @@ struct RootMusicResponsiveListItemRenderer: Codable {
|
|||||||
browseEndpointContextMusicConfig = try values.decodeIfPresent(BrowseEndpointContextMusicConfig.self, forKey: .browseEndpointContextMusicConfig)
|
browseEndpointContextMusicConfig = try values.decodeIfPresent(BrowseEndpointContextMusicConfig.self, forKey: .browseEndpointContextMusicConfig)
|
||||||
}
|
}
|
||||||
struct BrowseEndpointContextMusicConfig: Codable {
|
struct BrowseEndpointContextMusicConfig: Codable {
|
||||||
|
///预览类型
|
||||||
let pageType:String?
|
let pageType:String?
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
case pageType = "pageType"
|
case pageType = "pageType"
|
||||||
@ -763,11 +698,106 @@ struct RootMusicResponsiveListItemRenderer: Codable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
//菜单
|
||||||
|
struct Menu: Codable {
|
||||||
|
let menuRenderer:MenuRenderer?
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case menuRenderer = "menuRenderer"
|
||||||
|
}
|
||||||
|
init(from decoder: Decoder) throws {
|
||||||
|
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
menuRenderer = try values.decodeIfPresent(MenuRenderer.self, forKey: .menuRenderer)
|
||||||
|
}
|
||||||
|
struct MenuRenderer: Codable {
|
||||||
|
///菜单选项
|
||||||
|
let items:[Item]?
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case items = "items"
|
||||||
|
}
|
||||||
|
init(from decoder: Decoder) throws {
|
||||||
|
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
items = try values.decodeIfPresent([Item].self, forKey: .items)
|
||||||
|
}
|
||||||
|
struct Item: Codable {
|
||||||
|
///具备播放功能的选项(默认取包含watchEndpoint)
|
||||||
|
let menuNavigationItemRenderer:MenuNavigationItemRenderer?
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case menuNavigationItemRenderer = "menuNavigationItemRenderer"
|
||||||
|
}
|
||||||
|
init(from decoder: Decoder) throws {
|
||||||
|
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
menuNavigationItemRenderer = try values.decodeIfPresent(MenuNavigationItemRenderer.self, forKey: .menuNavigationItemRenderer)
|
||||||
|
}
|
||||||
|
struct MenuNavigationItemRenderer: Codable {
|
||||||
|
///文本导航
|
||||||
|
let navigationEndpoint:NavigationEndpoint?
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case navigationEndpoint = "navigationEndpoint"
|
||||||
|
}
|
||||||
|
init(from decoder: Decoder) throws {
|
||||||
|
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint)
|
||||||
|
}
|
||||||
|
//文本导航
|
||||||
|
struct NavigationEndpoint: Codable {
|
||||||
|
///资源特化
|
||||||
|
let watchEndpoint:WatchEndpoint?
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case watchEndpoint = "watchEndpoint"
|
||||||
|
}
|
||||||
|
init(from decoder: Decoder) throws {
|
||||||
|
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
watchEndpoint = try values.decodeIfPresent(WatchEndpoint.self, forKey: .watchEndpoint)
|
||||||
|
}
|
||||||
|
//导向播放
|
||||||
|
struct WatchEndpoint: Codable {
|
||||||
|
///资源ID
|
||||||
|
let videoId:String?
|
||||||
|
///对应歌单ID(未必存在)
|
||||||
|
let playlistId:String?
|
||||||
|
///指向资源类型
|
||||||
|
let watchEndpointMusicSupportedConfigs:WatchEndpointMusicSupportedConfigs?
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case videoId = "videoId"
|
||||||
|
case playlistId = "playlistId"
|
||||||
|
case watchEndpointMusicSupportedConfigs = "watchEndpointMusicSupportedConfigs"
|
||||||
|
}
|
||||||
|
init(from decoder: Decoder) throws {
|
||||||
|
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
videoId = try values.decodeIfPresent(String.self, forKey: .videoId)
|
||||||
|
playlistId = try values.decodeIfPresent(String.self, forKey: .playlistId)
|
||||||
|
watchEndpointMusicSupportedConfigs = try values.decodeIfPresent(WatchEndpointMusicSupportedConfigs.self, forKey: .watchEndpointMusicSupportedConfigs)
|
||||||
|
}
|
||||||
|
struct WatchEndpointMusicSupportedConfigs: Codable {
|
||||||
|
let watchEndpointMusicConfig:WatchEndpointMusicConfig?
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case watchEndpointMusicConfig = "watchEndpointMusicConfig"
|
||||||
|
}
|
||||||
|
init(from decoder: Decoder) throws {
|
||||||
|
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
watchEndpointMusicConfig = try values.decodeIfPresent(WatchEndpointMusicConfig.self, forKey: .watchEndpointMusicConfig)
|
||||||
|
}
|
||||||
|
struct WatchEndpointMusicConfig: Codable {
|
||||||
|
///资源类型
|
||||||
|
let musicVideoType:String?
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case musicVideoType = "musicVideoType"
|
||||||
|
}
|
||||||
|
init(from decoder: Decoder) throws {
|
||||||
|
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
musicVideoType = try values.decodeIfPresent(String.self, forKey: .musicVideoType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
///列表/专辑结构(通常是三组件构成,封面,一级标题,二级标题,额外包含ID内容)
|
///列表/专辑/歌手结构(通常是三组件构成,封面,一级标题,二级标题,额外包含ID内容)
|
||||||
struct RootMusicTwoRowItemRenderer: Codable {
|
struct RootMusicTwoRowItemRenderer: Codable {
|
||||||
///内容预览图片
|
///内容预览图片
|
||||||
let thumbnailRenderer:ThumbnailRenderer?
|
let thumbnailRenderer:ThumbnailRenderer?
|
||||||
|
|||||||
@ -20,9 +20,7 @@ class MPPositive_BrowseItemModel: NSObject, Codable {
|
|||||||
var playListId:String?
|
var playListId:String?
|
||||||
///列表专辑预览ID
|
///列表专辑预览ID
|
||||||
var browseId:String?
|
var browseId:String?
|
||||||
///列表专辑预览参数
|
///艺术家Id(当pageType == “MUSIC_PAGE_TYPE_ARTIST”时,与browseId等价)
|
||||||
var params:String?
|
|
||||||
///艺术家Id
|
|
||||||
var artistId:String?
|
var artistId:String?
|
||||||
///页面类型
|
///页面类型
|
||||||
var pageType:String?
|
var pageType:String?
|
||||||
|
|||||||
@ -72,7 +72,7 @@ class MPPositive_BaseViewController: MP_BaseViewController, UIGestureRecognizerD
|
|||||||
}
|
}
|
||||||
//pop上一个页面
|
//pop上一个页面
|
||||||
@objc func popActionClick(_ sender:UIButton) {
|
@objc func popActionClick(_ sender:UIButton) {
|
||||||
MPPositive_Debouncer.shared.call {
|
MPPositive_Debouncer.shared.call(0.1) {
|
||||||
[weak self] in
|
[weak self] in
|
||||||
guard let self = self else {return}
|
guard let self = self else {return}
|
||||||
navigationController?.popViewController(animated: true)
|
navigationController?.popViewController(animated: true)
|
||||||
|
|||||||
@ -137,7 +137,6 @@ class MPPositive_HomeViewController: MPPositive_BaseViewController, UIViewContro
|
|||||||
func presentGuide() {
|
func presentGuide() {
|
||||||
guard UserDefaults.standard.bool(forKey: "isGuide") != true else {
|
guard UserDefaults.standard.bool(forKey: "isGuide") != true else {
|
||||||
//已经评论过了
|
//已经评论过了
|
||||||
print("已经评论过了")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//检索活跃天数是否达到3天
|
//检索活跃天数是否达到3天
|
||||||
@ -267,7 +266,7 @@ extension MPPositive_HomeViewController: UITableViewDataSource, UITableViewDeleg
|
|||||||
cell.requestNextBlock = {
|
cell.requestNextBlock = {
|
||||||
[weak self] (item) in
|
[weak self] (item) in
|
||||||
guard let self = self else {return}
|
guard let self = self else {return}
|
||||||
MP_AnalyticsManager.shared.home_b_module_clickAction(MPPositive_BrowseLoadViewModel.shared.browseModuleLists[indexPath.section].title ?? "")
|
MP_AnalyticsManager.shared.home_b_module_clickAction(item.browseItem.pageType ?? "")
|
||||||
switch item.browseItem.itemType {
|
switch item.browseItem.itemType {
|
||||||
case .single:
|
case .single:
|
||||||
//单曲/视频跳转
|
//单曲/视频跳转
|
||||||
@ -299,7 +298,7 @@ extension MPPositive_HomeViewController: UITableViewDataSource, UITableViewDeleg
|
|||||||
case .list:
|
case .list:
|
||||||
isFirstAppearance = false
|
isFirstAppearance = false
|
||||||
//列表专辑
|
//列表专辑
|
||||||
let listVC = MPPositive_ListShowViewController(item.browseItem.browseId ?? "", params: item.browseItem.params ?? "", title: item.title ?? "", subtitle: item.subtitle ?? "")
|
let listVC = MPPositive_ListShowViewController(item.browseItem.browseId ?? "", params: "", title: item.title ?? "", subtitle: item.subtitle ?? "")
|
||||||
navigationController?.pushViewController(listVC, animated: true)
|
navigationController?.pushViewController(listVC, animated: true)
|
||||||
case .artist:
|
case .artist:
|
||||||
isFirstAppearance = false
|
isFirstAppearance = false
|
||||||
|
|||||||
@ -166,7 +166,7 @@ extension MPPositive_MoreContentViewController: UICollectionViewDataSource, UICo
|
|||||||
navigationController?.pushViewController(artistVC, animated: true)
|
navigationController?.pushViewController(artistVC, animated: true)
|
||||||
default:
|
default:
|
||||||
//列表专辑
|
//列表专辑
|
||||||
let listVC = MPPositive_ListShowViewController(browseModuleList.items[indexPath.row].browseItem.browseId ?? "", params: browseModuleList.items[indexPath.row].browseItem.params ?? "", title: browseModuleList.items[indexPath.row].title ?? "", subtitle: browseModuleList.items[indexPath.row].subtitle ?? "")
|
let listVC = MPPositive_ListShowViewController(browseModuleList.items[indexPath.row].browseItem.browseId ?? "", params: "", title: browseModuleList.items[indexPath.row].title ?? "", subtitle: browseModuleList.items[indexPath.row].subtitle ?? "")
|
||||||
navigationController?.pushViewController(listVC, animated: true)
|
navigationController?.pushViewController(listVC, animated: true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,27 +36,9 @@ class MPPositive_HomeSinglesTableViewCell: UITableViewCell, UIViewControllerTran
|
|||||||
didSet{
|
didSet{
|
||||||
titleLabel.text = browseViewModel.title
|
titleLabel.text = browseViewModel.title
|
||||||
collectionView.reloadData()
|
collectionView.reloadData()
|
||||||
// let groupSize = browseViewModel.items.count / 3 // 每组的元素数量
|
|
||||||
// var remainder = browseViewModel.items.count % 3 // 不完整组的元素数量
|
|
||||||
// let numberOfGroups = 3 // 组数
|
|
||||||
// var groups = [[MPPositive_BrowseItemViewModel]]() // 存储分组结果的数组
|
|
||||||
// var start = 0
|
|
||||||
// for _ in 0..<numberOfGroups {
|
|
||||||
// let end = start + groupSize + (remainder > 0 ? 1 : 0)
|
|
||||||
// let group = Array(browseViewModel.items[start..<end])
|
|
||||||
// groups.append(group)
|
|
||||||
// start = end
|
|
||||||
// remainder -= 1
|
|
||||||
// }
|
|
||||||
// items = groups
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
///刷新数据组
|
|
||||||
// private var items:[[MPPositive_BrowseItemViewModel]] = []{
|
|
||||||
// didSet{
|
|
||||||
// collectionView.reloadData()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||||
@ -143,6 +125,7 @@ extension MPPositive_HomeSinglesTableViewCell:UICollectionViewDataSource, UIColl
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
let item = self.browseViewModel.items[indexPath.row]
|
let item = self.browseViewModel.items[indexPath.row]
|
||||||
|
MP_AnalyticsManager.shared.home_b_module_clickAction(item.browseItem.pageType ?? "")
|
||||||
MP_AnalyticsManager.shared.song_clickAction("Home")
|
MP_AnalyticsManager.shared.song_clickAction("Home")
|
||||||
//优先清除数据
|
//优先清除数据
|
||||||
MP_PlayerManager.shared.loadPlayer = nil
|
MP_PlayerManager.shared.loadPlayer = nil
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user