jsonswiftlast.fm

Last.fm api json not being read with swift decoder


I'm trying to make a simple song search app using the last.fm api and swift ui. When I use the decoder with the itunes api it works fine but when I try using last.fm my view is blank so i'm assuming that maybe the objects i've defined for the json are wrong? Kinda new to swift especially reading json files from apis so very confused. Any help/tips would be really appreciated.

api link: https://www.last.fm/api/show/track.search

json link: http://ws.audioscrobbler.com/2.0/?method=track.search&track=hello&api_key=d527fc1829aecc7e54b63367b3d4621a&format=json


struct TracksRow: View {
    @State var term = "hello"
    @State var results = [Tracks]()
    
    var body: some View {
        List(results, id: \.songName){ item in
            VStack(alignment: .leading) {
                Text(item.songName)
                    .font(.headline)
                Text(item.singerName)
            }
        }.onAppear(perform: loadData)
        
    }
    
    func loadData(){
        guard let url = URL(string: "http://ws.audioscrobbler.com/2.0/?method=track.search&track=\(term)&api_key=d527fc1829aecc7e54b63367b3d4621a&format=json") else {
            print("Invalid URL")
            return
        }
        
        let request = URLRequest(url: url)
        
        URLSession.shared.dataTask(with: request) { data, response, error in
            if let data = data {
                if let decodedResponse = try? JSONDecoder().decode(SongResponse.self, from: data) {
                    
                    DispatchQueue.main.async {
                        self.results = decodedResponse.songs.trackMatches.matches
                    }
                    
                    return
                }
            }
            
        }.resume()
        
        
    }
}

struct TracksRow_Previews: PreviewProvider {
    static var previews: some View {
        TracksRow()
    }
}

JSON Objects:


struct SongResponse: Codable{
    let songs : TrackResults
    
    enum CodingKeys: String, CodingKey {
        case songs = "results"
    }
}

struct TrackResults: Codable {
    var trackMatches: TrackMatches
   
    enum CodingKeys: String, CodingKey {
        case trackMatches = "trackmatches"
    }
}

struct TrackMatches: Codable {
    let matches : [Tracks]
    
    enum CodingKeys: String, CodingKey {
        case matches = "track"
    }
}

struct Tracks: Codable {
     let songName: String
     let singerName: String
     let albumImage: [TrackImage]
    
    enum CodingKeys: String, CodingKey {
        case songName = "name"
        case singerName = "artist"
        case albumImage = "image"
    }
}

struct TrackImage: Codable{
    let url: String
    let size: String
    
    enum CodingKeys: String, CodingKey{
        case url = "#text"
        case size
    }
}

Solution

  • I did't get any problem while parsing the API, with your code. I don't think there is any issue with JSON parsing, Have you updated info.plist with App Transport security?

    enter image description here

    This is what your code displays after assuming you have added the above key.

    enter image description here