英文:
Deezer API failing to decode?
问题
我理解了,你想要将上述代码翻译成中文。以下是翻译好的部分:
我正在尝试从Deezer的API(网址:https://api.deezer.com/genre)中获取“流派类别”数据,用于我的SwiftUI项目,然而在解码并将数据值分配给我的数组的代码行中,却没有发生这种情况。相反,程序跳转到了我的else条件中。我在其他API(苹果的iTunes API和其他公共测试API)上使用了完全相同的程序结构,它们都可以完全正常工作。是Deezer API 或者我的请求本身出了问题吗?
我的 GenreModel 代码:
struct Genre: Codable {
let id: Int
let name: String
let picture: String
}
我的 GenreViewModel 代码:
final class GenreViewModel: ObservableObject {
@Published var genres: [Genre] = []
@Published var hasError = false
@Published var error: UserError?
func fetchGenres() {
// ... (后续部分)
}
// ... (后续部分)
enum UserError: LocalizedError {
case custom(error: Error)
case failedToDecode
var errorDescription: String? {
switch self {
// ... (后续部分)
}
}
}
}
我的 GenreView 代码:
struct GenreView: View {
let genre: Genre
var body: some View {
VStack(alignment: .leading) {
Text("**Genre**: \(genre.id)")
Text("**Name**: \(genre.name)")
Text("**Picture**: \(genre.picture)")
}
}
}
我的 ContentView 代码:
struct ContentView: View {
@StateObject private var gVM = GenreViewModel()
var body: some View {
// ... (后续部分)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
如果你有任何其他需要,请继续提出。
英文:
I'm trying to access "Genre Categories" data from Deezer's API (url: https://api.deezer.com/genre) in my SwiftUI Project, however in the line where I decode and assign the data value to my array, it doesn't happen. Instead the program falls to my else condition. I've used this exact program structure on other API's ( Apple's iTunes API and other public test APIs) and it works with no problem whatsoever. Could there be a problem in Deezer API or my request itself?
My GenreModel Code:
'''
import Foundation
struct Genre: Codable {
let id: Int
let name: String
let picture: String
}
'''
My GenreViewModel Code:
'''
import Foundation
final class GenreViewModel: ObservableObject{
@Published var genres: [Genre] = []
@Published var hasError = false
@Published var error: UserError?
func fetchGenres(){
hasError = false
let genreUrl = "https://api.deezer.com/genre"
if let url = URL(string: genreUrl){
URLSession.shared.dataTask(with: url){ [weak self] data,response, error in
DispatchQueue.main.async {
if let error = error{
self?.hasError = true
self?.error = UserError.custom(error: error)
}
else{
let decoder = JSONDecoder()
//decoder.keyDecodingStrategy = .useDefaultKeys
if let data = data,
let genres = try? decoder.decode([Genre].self, from: data){
self?.genres = genres
}
else{
self?.hasError = true
self?.error = UserError.failedToDecode
}
}
}
}.resume()
}
}
}
extension GenreViewModel{
enum UserError: LocalizedError{
case custom(error: Error)
case failedToDecode
var errorDescription: String?{
switch self{
case .failedToDecode:
return "Failed to decode"
case .custom(let error):
return error.localizedDescription
}
}
}
}
'''
My GenreView Code
'''
import SwiftUI
struct GenreView: View{
let genre: Genre
var body: some View{
VStack(alignment: .leading){
Text("**Genre**: \(genre.id)")
Text("**Name**: \(genre.name)")
Text("**Picture**: \(genre.picture)")
}
}
}
struct GenreView_Previews: PreviewProvider{
static var previews: some View{
GenreView(genre: .init(id: 0, name: "a", picture: "pic"))
}
}
'''
My ContentView Code
'''
import SwiftUI
struct ContentView: View {
@StateObject private var gVM = GenreViewModel()
var body: some View {
NavigationView{
ZStack{
List{
ForEach(gVM.genres, id: \.id){ genre in
GenreView(genre: genre).listStyle(.plain)
}
}.listStyle(.plain).navigationTitle("Users")
.alert(isPresented: $gVM.hasError, error: gVM.error){
Button(action: gVM.fetchGenres){
Text("try again")
}
}
}.onAppear(perform: gVM.fetchGenres)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
'''
答案1
得分: 1
尝试以下示例代码,其中根 ApiResponse
用于解码从服务器获取的 JSON 数据。
struct ApiResponse: Codable {
let data: [Genre]
}
struct Genre: Identifiable, Codable {
let id: Int
let name, picture, type: String
let pictureSmall, pictureMedium, pictureBig, pictureXl: String
enum CodingKeys: String, CodingKey {
case id, name, picture, type
case pictureSmall = "picture_small"
case pictureMedium = "picture_medium"
case pictureBig = "picture_big"
case pictureXl = "picture_xl"
}
}
final class GenreViewModel: ObservableObject {
@Published var genres: [Genre] = []
@Published var hasError = false
@Published var error: UserError?
func fetchGenres() {
hasError = false
let genreUrl = "https://api.deezer.com/genre"
if let url = URL(string: genreUrl) {
URLSession.shared.dataTask(with: url) { data, response, error in
DispatchQueue.main.async {
if let error = error {
self.hasError = true
self.error = UserError.custom(error: error)
} else {
if let data = data {
do {
let decoder = JSONDecoder()
let genres = try decoder.decode(ApiResponse.self, from: data)
self.genres = genres.data
return
} catch {
print(error)
}
}
self.hasError = true
self.error = UserError.failedToDecode
}
}
}.resume()
}
}
}
英文:
Try this example code, where the root ApiResponse
is used to decode the json data you get from the server.
struct ApiResponse: Codable {
let data: [Genre]
}
struct Genre: Identifiable, Codable {
let id: Int
let name, picture, type: String
let pictureSmall, pictureMedium, pictureBig, pictureXl: String
enum CodingKeys: String, CodingKey {
case id, name, picture, type
case pictureSmall = "picture_small"
case pictureMedium = "picture_medium"
case pictureBig = "picture_big"
case pictureXl = "picture_xl"
}
}
final class GenreViewModel: ObservableObject {
@Published var genres: [Genre] = []
@Published var hasError = false
@Published var error: UserError?
func fetchGenres() {
hasError = false
let genreUrl = "https://api.deezer.com/genre"
if let url = URL(string: genreUrl) {
URLSession.shared.dataTask(with: url){ data,response, error in
DispatchQueue.main.async {
if let error = error {
self.hasError = true
self.error = UserError.custom(error: error)
} else {
if let data = data {
do {
let decoder = JSONDecoder()
let genres = try decoder.decode(ApiResponse.self, from: data)
self.genres = genres.data
return
} catch {
print(error)
}
}
self.hasError = true
self.error = UserError.failedToDecode
}
}
}.resume()
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论