问题描述
我正在尝试使用返回JSON的dataTaskPublisher(用于:URLRequest)从Apple Music API中获取数据。然后,我解码数据并将其转换为播放列表。我已经尝试了几种方法,但这是目前的样子。
class LibraryPlaylistviewmodel: ObservableObject {
@Published private(set) var state = State()
var subscriptions: Set<AnyCancellable> = Set()
struct State {
var playlists: [LibraryPlaylist] = []
}
func getNextOffsetIfAvailable() {
AppleMusicAPIEnum.fetchGetAllLibraryPlaylists()
.sink(receiveCompletion: onReceive,receiveValue: onReceive)
.store(in: &subscriptions)
}
private func onReceive(_ completion: Subscribers.Completion<Error>) {
switch completion {
case .finished:
break
case .failure:
print("something went wrong")
}
}
private func onReceive(_ batch: [LibraryPlaylist]) {
state.playlists += batch
}
}
struct EndlessListContainer: View {
@Observedobject var viewmodel: LibraryPlaylistviewmodel
var body: some View {
EndlessList(
libraryPlaylists: viewmodel.state.playlists
)
.onAppear(perform: viewmodel.getNextOffsetIfAvailable)
}
}
struct EndlessList: View {
let libraryPlaylists: [LibraryPlaylist]
var body: some View {
List {
ForEach(libraryPlaylists,id: \.uniqueID) { playlist in
PlaylistRow(playlist: playlist)
}
}
}
}
struct PlaylistRow: View {
let playlist: LibraryPlaylist
var body: some View {
vstack {
Text(playlist.attributes.name ?? "").font(.title)
}
.frame(idealWidth: .infinity,maxWidth: .infinity,alignment: .center)
}
}
我用于网络请求的枚举:
enum AppleMusicAPIEnum {
static let musicAPI = AppleMusicAPI()
static func fetchGetAllLibraryPlaylists() -> AnyPublisher<[LibraryPlaylist],Error> {
let url = URL(string: "https://api.music.apple.com/v1/me/library/playlists")
print("\(url!)")
var request = URLRequest(url: url!)
request.httpMethod = "GET"
request.addValue("Bearer \(self.musicAPI.developerToken)",forHTTPHeaderField: "Authorization")
request.addValue(self.musicAPI.getUserToken(),forHTTPHeaderField: "Music-User-Token")
print("Set up request")
return URLSession.shared
.dataTaskPublisher(for: request)
.tryMap { try JSONDecoder().decode(AllLibraryPlaylistsResponse<LibraryPlaylist>.self,from: $0.data).data }
.receive(on: dispatchQueue.main)
.erasetoAnyPublisher()
}
}
以及解码JSON的结构:
struct AllLibraryPlaylistsResponse<T: Codable>: Codable {
let data: [T]
}
struct LibraryPlaylist: Codable {
let attributes: Attributes
let href,id,type: String
}
struct LibraryPlaylistAttributes: Codable {
let canEdit: Bool?
let attributesDescription: PlaylistDescription?
let name: String
let playParams: PlaylistPlayParams
enum CodingKeys: String,CodingKey {
case canEdit
case attributesDescription = "description"
case name,playParams
}
}
struct PlaylistDescription: Codable {
let standard: String?
}
struct PlaylistPlayParams: Codable {
let id: String?
let isLibrary: Bool?
let kind: String?
}
然后我有了一个带有NavigationLink的视图,我用它来打开包含如下播放列表的视图:
NavigationLink(destination: EndlessListContainer(viewmodel: LibraryPlaylistviewmodel())) {
// Content
}
点击NavigationLink后,它会高亮显示,并且应用程序会无限期挂起,而不会切换到新视图。
我知道我输入fetchGetAllLibraryPlaylists()
是因为可以打印该URL,但出于某种原因print("Set up request")
却没有。我以前曾将此URLRequest与dataTask(with request: URLRequest)
配合使用良好,所以我认为并非如此。
想知道我哪里做错了,还有没有更简洁的方法呢?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)