URLSession的Data任务在我尝试使对象符合Identifiable协议时返回Nil。

huangapple go评论57阅读模式
英文:

URLSession's Data Task returning Nil when I try to conform the object to Identifiable protocol

问题

I'm trying to run a simple http request to Spotify's api to get the recent played tracks

"https://api.spotify.com/v1/me/player/recently-played?limit=2&before=1676369852305"

Everything works and I do get the result back, but when I add the Identifiable protocol with id variable to my struct objects the decoder fails (nil).
(I want to conform to Identifiable because I need to use the data in a List/ForEach loop

Here's my code

//objects
struct Recent: Codable {   //or Codable, Identifiable
    //let id: UUID?
    let items: [Item]?
    let next: String?
    let limit: Int?
    let href: String?
}
struct Item: Codable {    //or Codable, Identifiable
    // let id: UUID?
    let track: Track?
    let played_at: String?
}
struct Track: Codable {    //or Codable, Identifiable  
    //let id: String?  
    let name: String?
    let popularity: Int?
    let trackNumber: Int?
    let type, uri: String?
}


//function
func getRecentPlayed(miliTime: String) {
        //let miliTime = "1676369852305"
        let urlString = "https://api.spotify.com/v1/me/player/recently-played?limit=10&before=\(miliTime)"

        let url = URL(string: urlString)
      
        let urlSessionConfig = URLSessionConfiguration.default
        urlSessionConfig.httpAdditionalHeaders = ["Authorization": "Bearer \(OAuthToken)"]
        
        let urlSession = URLSession(configuration: urlSessionConfig)
        let sessionTask = urlSession.dataTask(with: url!) { data, response, error in
            
            if (error == nil && data != nil) {
                let jsondecoder = JSONDecoder()
                let recentPlayedData = try? jsondecoder.decode(Recent.self, from: data!)
                print (recentPlayedData)
                recent = recentPlayedData
            } else {
                print (error)
            }
        }
        sessionTask.resume()
    }

What I want:
Run the following loop in swiftui but it screams saying

"Referencing initializer on 'ForEach' requires that 'Item' conform to 'Identifiable"
//swiftui
@State var recent: Recent?

if let r = recent {
       NavigationView {
            List {
                 ForEach(r.items!) { item in
                            Text((item.track?.name)!)
                 }
            }
            .navigationTitle("Recently played")
       }
}

Any idea anyone?

英文:

I'm trying to run a simple http request to Spotify's api to get the recent played tracks

"https://api.spotify.com/v1/me/player/recently-played?limit=2&before=1676369852305"

Everything works and I do get the result back, but when I add the Identifiable protocol with id variable to my struct objects the decoder fails (nil).
(I want to conform to Identifiable because I need to use the data in a List/ForEach loop

Here's my code

//objects
struct Recent: Codable {   //or Codable, Identifiable
    //let id: UUID?
    let items: [Item]?
    let next: String?
    let limit: Int?
    let href: String?
}
struct Item: Codable {    //or Codable, Identifiable
    // let id: UUID?
    let track: Track?
    let played_at: String?
}
struct Track: Codable {    //or Codable, Identifiable  
    //let id: String?  
    let name: String?
    let popularity: Int?
    let trackNumber: Int?
    let type, uri: String?
}


//function
func getRecentPlayed(miliTime: String) {
        //let miliTime = "1676369852305"
        let urlString = "https://api.spotify.com/v1/me/player/recently-played?limit=10&before=\(miliTime)"

        let url = URL(string: urlString)
      
        let urlSessionConfig = URLSessionConfiguration.default
        urlSessionConfig.httpAdditionalHeaders = ["Authorization": "Bearer \(OAuthToken)"]
        
        let urlSession = URLSession(configuration: urlSessionConfig)
        let sessionTask = urlSession.dataTask(with: url!) { data, response, error in
            
            if (error == nil && data != nil) {
                let jsondecoder = JSONDecoder()
                let recentPlayedData = try? jsondecoder.decode(Recent.self, from: data!)
                print (recentPlayedData)
                recent = recentPlayedData
            } else {
                print (error)
            }
        }
        sessionTask.resume()
    }

What I want:
Run the following loop in swiftui but it screams saying

"Referencing initializer on 'ForEach' requires that 'Item' conform to 'Identifiable"
//swiftui
@State var recent: Recent?

if let r = recent {
       NavigationView {
            List {
                 ForEach(r.items!) { item in
                            Text((item.track?.name)!)
                 }
            }
            .navigationTitle("Recently played")
       }
}

Any idea anyone?

答案1

得分: 1

struct Recent: Codable {
var id: String?{
href
}
let items: [Item]?
let next: String?
let limit: Int?
let href: String?
}
struct Item: Codable, Identifiable {
var id: String?{
track?.id
}
let track: Track?
let played_at: String?
}
struct Track: Codable, Identifiable {
var id: String?{
uri
}
let name: String?
let popularity: Int?
let trackNumber: Int?
let type, uri: String?
}

英文:

You can use what you have that is already unique

    struct Recent: Codable {
        var id: String?{
            href
        }
        let items: [Item]?
        let next: String?
        let limit: Int?
        let href: String?
    }
    struct Item: Codable, Identifiable {
        var id:String?{
            track?.id
        }
        let track: Track?
        let played_at: String?
    }
    struct Track: Codable, Identifiable {    //or Codable, Identifiable
        var id: String?{
            uri
        }
        let name: String?
        let popularity: Int?
        let trackNumber: Int?
        let type, uri: String?
    }

答案2

得分: 0

以下是翻译好的部分:

struct Track: Codable, Identifiable {
    let id = UUID() //或者其他内容,不清楚你的id是什么
    let name: String?
    let popularity: Int?
    let trackNumber: Int?
    let type, uri: String?
}
英文:

It is not possible exactly as you want, I think that the closest thing to what you want is this:

struct Track: Codable, Identifiable{    //or   
    let id = UUID() //or something else, it is not clear what is your id  
    let name: String?
    let popularity: Int?
    let trackNumber: Int?
    let type, uri: String?
}

huangapple
  • 本文由 发表于 2023年2月14日 22:13:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75449088.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定