How to get single object JSON API in SwiftUI

I am trying to get the data from this API - (api.solunar.org/solunar/42.66,-84.07,20180207,-4). I found this tutorial (youtube.com/watch?v=gfOhBmU2cPM), but it is for a list of objects JSON API, whereas mine is just 1 single object... Does anyone know how to edit the code from the video to work with my API?
Answered by OOPer in 668996022

I need to edit it to be for a single object. 

Sorry, I have been missing your words my old code the gets a multi-object array.

But you just need to pass the struct type to decode(_:from:) instead of Array type:
For example:
Code Block
struct SingleObject: Codable {
var sunRise: String
//...
}
enum ApiError: Error {
case dataIsNil
}
class ApiCall {
func getSingleObject(completion:@escaping (Result<SingleObject, Error>) -> ()) {
guard let url = URL(string: "...") else { return }
URLSession.shared.dataTask(with: url) { (data, _, error) in
if let error = error {
print(error)
completion(.failure(error))
return
}
guard let data = data else {
print("data is nil")
completion(.failure(ApiError.dataIsNil))
return
}
do {
let singleObject = try JSONDecoder().decode(SingleObject.self, from: data) //<-
print(singleObject)
DispatchQueue.main.async {
completion(.success(singleObject))
}
} catch {
print(error)
completion(.failure(error))
}
}
.resume()
}
}


Could you please select in referenced links and post:
  • the part of code you want to adapt

  • the adaptations you did (what are your own objects to decode)

  • explain what you tried,

  • what doesn't work ?

Not sure many here have time or intent to go and search for relevant code.
I tried using referenced links, but the forums wouldn’t allow them, so I just put them in plain text...

I haven’t attempted editing my old code the gets a multi-object array, as I don’t know where to start. My code is attached



Can you show the example response as JSON text?

And I need to ask one more question. Why the completion of your getUsers(completion:) takes [Launch]?
You say it is a single object, not an Array.
The code I posted is my code for getting a multi-object JSON array, and I need to edit it to be for a single object.






Accepted Answer

I need to edit it to be for a single object. 

Sorry, I have been missing your words my old code the gets a multi-object array.

But you just need to pass the struct type to decode(_:from:) instead of Array type:
For example:
Code Block
struct SingleObject: Codable {
var sunRise: String
//...
}
enum ApiError: Error {
case dataIsNil
}
class ApiCall {
func getSingleObject(completion:@escaping (Result<SingleObject, Error>) -> ()) {
guard let url = URL(string: "...") else { return }
URLSession.shared.dataTask(with: url) { (data, _, error) in
if let error = error {
print(error)
completion(.failure(error))
return
}
guard let data = data else {
print("data is nil")
completion(.failure(ApiError.dataIsNil))
return
}
do {
let singleObject = try JSONDecoder().decode(SingleObject.self, from: data) //<-
print(singleObject)
DispatchQueue.main.async {
completion(.success(singleObject))
}
} catch {
print(error)
completion(.failure(error))
}
}
.resume()
}
}


How do I then get the data from that into a variable? My multi-object one did it along the lines of:

Code Block swift
@State var moons: [SingleObject] = []
.onAppear {
ApiCall().getSingleObject{ (moons) in self.moons = moons}
}


UPDATE: Assuming you are using my code with Result as is...

How do I then get the data from that into a variable? 

Code Block
@State var singleObject: SingleObject?
.onAppear {
ApiCall().getSingleObject{ result in
switch result {
case .success(let singleObject):
self.singleObject = singleObject
case .failure(let error):
print(error)
}
}
}


You say a single object, you usually do not use an Array for a single object.
Thanks, it works!
How to get single object JSON API in SwiftUI
 
 
Q