NEW: Download Kickstart, the app that helps indie developers succeed on the App Store! >>

SOLVED: API Call Help

Forums > iOS

Hi all,

Longtime listener, first time caller. Finally able to sit down with URLSession.shared.dataTaskPublisher and play around.

Not sure why but I can't get a response from APIs like SpaceX or RickandMorty. Threw various links that worked into Postman and I noticed the ones that don't work open the reponse with '{' where Paul's url user-messages.json opens the reponse with '['

Below is an example of my attempt with the SpaceX API - Latest Launches. Any advise would be great because clearly I'm missing something fundamental.

import SwiftUI
import Combine

struct SpaceX: Codable {
    var flight_number: Int
    var name: String
}

struct ContentView: View {
    @State private var requests = Set<AnyCancellable>()
    @State private var launchesLatest = [SpaceX]()

    var body: some View {
        NavigationView {
            List(launchesLatest, id: \.name) { launches in
                Text(launches.name)
            }
        .navigationBarTitle("SpaceX")
        }
        .onAppear {
            let url = URL(string: "https://api.spacexdata.com/v4/launches/latest")!

            self.fetch(url, defaultValue: [SpaceX]()) {
                self.launchesLatest = $0
            }
        }
    }

    func fetch<T: Decodable>(_ url: URL, defaultValue: T, completion: @escaping (T) -> Void) {

        let decoder = JSONDecoder()

        URLSession.shared.dataTaskPublisher(for: url)
            .retry(1)
            .map(\.data)
            .decode(type: T.self, decoder: decoder)
            .replaceError(with: defaultValue)
            .receive(on: DispatchQueue.main)
            .sink(receiveValue: completion)
            .store(in: &requests)
    }
}

3      

Hi @teamsuperpanda,

It because the JSON is not an Array [ ] there forewill only return one value. Add to your struct SpaceX

struct SpaceX: Decodable {
  var flight_number: Int
  var name: String

  static let `default` = SpaceX(flight_number: 0, name: "Unknown")
}

then change the ContentView

@State private var requests = Set<AnyCancellable>()
@State var spaceX: SpaceX

var body: some View {
  NavigationView {
      VStack {
        Text(spaceX.flight_number)
        Text(spaceX.name)
      }
      .navigationBarTitle("SpaceX")
  }
  .onAppear {
      let url = URL(string: "https://api.spacexdata.com/v4/launches/latest")!

      self.fetch(url, defaultValue: SpaceX.default) {
          self.spaceX.name = $0.name
          self.spaceX.flight_number = $0.flight_number
      }
  }
}

and that should return the number and name.

PS you need to add ContentView(spaceX: SpaceX.default) to Previews etc to get rid of errors

3      

Hey thanks for the help.

Was looking at it and tried different things. I'm at the point where I understand concepts on their own but putting things together is the tricky part.

Appreciate the time.

3      

Hacking with Swift is sponsored by Swiftsonic.

SPONSORED It's the final countdown! Swiftsonic is an all-new event for Swift developers taking place in Nashville, November 20–22. Build alongside fellow Swift and iOS developers with practical talks, the best in AI, fresh ideas, and conversations that make you pumped to ship again. So what are you waiting for? Get your pass and let’s dial the volume up to 11!

Learn more

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account