Home > Mobile >  Data is missing from API call to Unsplashed using Swift
Data is missing from API call to Unsplashed using Swift

Time:10-11

Problem: I was following a tutorial and I cannot seem to get the data loaded when I get a API call from Unsplashed. I registered for an account and used my personal key.

I created my loadData function that should load the data from the API call:

func loadData() {
        let key = "78zZU5uBelOYbcPfBHxWCJ5N8x9FmuLT2zHSXZqE3vw"
        let url = "https://api.unsplash.com/photos/random/?count=30&client_id=\(key)"
        
        let session = URLSession(configuration: .default)
        
        session.dataTask(with: URL(string: url)!) { (data, _, error) in
                         guard let data = data else {
            print("URLSession dataTask error", error ?? "nil")
            return
        }
            print(data)
            do{
                let json = try JSONDecoder().decode([Photo].self,from: data)
                print(json)
                for photo in json {
                    DispatchQueue.main.async {
                        self.photoArray.append(photo)
                    }
                }
            }catch{
                print("In error")
                print(error.localizedDescription)
            }
        }.resume()
    }

I present my data in the content view as follows:

import SwiftUI

struct ContentView: View {
    
    @ObservedObject var randomImages = UnsplashData()
    
    var body: some View {
        Text("Hello, world!")
            .padding()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

I print the data before I use the JSON decoder and there seems to be data there, but when I go to get the JSON it states this error:

The data couldn’t be read because it is missing.

So is it the way I am using the API key? Or something else?

The photo structure is as follows:

struct Photo: Identifiable, Decodable {
    var id: String
    var alt_description: String
    var urls: [String: String]
}

CodePudding user response:

It's not the data that you're receiving, it's how you're decoding it that seems to be an issue.

For example, this simple playground example works just fine...

import UIKit
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true

struct Sources: Decodable {
    let raw: String
    let full: String
    let regular: String
    let small: String
    let thumbnail: String
}

struct Photo: Decodable {
    let urls: [Sources]
}

let key = "don't post this, that's a bad idea"
let url = "https://api.unsplash.com/photos/random/?count=30&client_id=\(key)"

let session = URLSession(configuration: .default)

session.dataTask(with: URL(string: url)!) { (data, _, error) in
    guard let data = data else {
        print("URLSession dataTask error", error ?? "nil")
        return
    }
    print(String(data: data, encoding: .utf8))
    do{
        let json = try JSONDecoder().decode([Photo].self,from: data)
        print(json)
    }catch{
        print("In error")
        print(error.localizedDescription)
    }
}.resume()

If you change print(error.localizedDescription) to print(error) you'll generally get a more accurate description of the error

  • Related