Задача данных URLSession возвращает Nil, когда я пытаюсь согласовать объект с идентифицируемым протоколом

Я пытаюсь запустить простой http-запрос к API Spotify, чтобы получить последние воспроизведенные треки.

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

Все работает, и я получаю результат обратно, но когда я добавляю идентифицируемый протокол с переменной id к своим объектам структуры, декодер дает сбой (ноль). (Я хочу соответствовать Идентифицируемым, потому что мне нужно использовать данные в цикле List/ForEach

Вот мой код

//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()
    }

Что я хочу: Запустите следующий цикл в swiftui, но он кричит:

"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")
       }
}

Любая идея?

Не try?, никогда try?, вы игнорируете важную информацию; catch ошибку и распечатать. Он сообщает вам keyNotFound. Вы должны добавить CodingKeys и опустить id. И почему все опционально? Тем более объявлять id необязательным бессмысленно.

vadian 14.02.2023 15:17
id опущен. я не получаю никакой ошибки, но он запрашивает идентификацию, хочу ли я использовать объект с ForEach. Я постараюсь добавить CodingKeys и дам вам знать
ccmsd18 14.02.2023 16:05

Свойство id для Identifiable должно быть необязательным. Напишите let id = UUID() и добавьте CodingKeys.

vadian 14.02.2023 16:07

Я попробовал это с CodingKeys enum, и это тоже сработало. Большое спасибо!

ccmsd18 15.02.2023 18:48
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Калькулятор CGPA 12 для семестра
Калькулятор CGPA 12 для семестра
Чтобы запустить этот код и рассчитать CGPA, необходимо сохранить код как HTML-файл, а затем открыть его в веб-браузере. Для этого выполните следующие...
ONLBest Online HTML CSS JAVASCRIPT Training In INDIA 2023
ONLBest Online HTML CSS JAVASCRIPT Training In INDIA 2023
О тренинге HTML JavaScript :HTML (язык гипертекстовой разметки) и CSS (каскадные таблицы стилей) - две основные технологии для создания веб-страниц....
Как собрать/развернуть часть вашего приложения Angular
Как собрать/развернуть часть вашего приложения Angular
Вам когда-нибудь требовалось собрать/развернуть только часть вашего приложения Angular или, возможно, скрыть некоторые маршруты в определенных средах?
Запуск PHP на IIS без использования программы установки веб-платформы
Запуск PHP на IIS без использования программы установки веб-платформы
Установщик веб-платформы, предлагаемый компанией Microsoft, перестанет работать 31 декабря 2022 года. Его закрытие привело к тому, что мы не можем...
Оптимизация React Context шаг за шагом в 4 примерах
Оптимизация React Context шаг за шагом в 4 примерах
При использовании компонентов React в сочетании с Context вы можете оптимизировать рендеринг, обернув ваш компонент React в React.memo сразу после...
0
4
57
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете использовать то, что у вас есть, что уже уникально

    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?
    }

Большое спасибо, это сработало! Это было очень умно, если честно. Хорошего настроения :)

ccmsd18 14.02.2023 21:03

@ ccmsd18 рад помочь, не могли бы вы нажать на зеленую галочку, чтобы принять ответ и, возможно, проголосовать?

lorem ipsum 14.02.2023 21:53

Это невозможно именно так, как вы хотите, я думаю, что самое близкое к тому, что вы хотите, это:

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?
}

Другие вопросы по теме