3

So I am making an HTTP request and I get a response that looks like this:

{
  "code": 200,
  "status": "success",
  "patients": {
    "bogdanp": {
      "_id": "5e77c7bbc7cbd30024f3eadb",
      "name": "Bogdan Patient",
      "phone": "0732958473"
    },
    "robertp": {
      "_id": "5e77c982a2736a0024e895fa",
      "name": "Robert Patient",
      "phone": "0739284756"
    }
  }
}

How to get "bogdanp" as a string, and how do I access the object properties? For example, how to access "name" or "phone" etc.?

Here is my HTTP code:

func getPatients(link: String, username: String)
{
    var code = 0 // this is the variable that stores the error code from the response, it is initially set to 0
    let parameters: [String : Any] = ["username": username]
    let url = URL(string: link)!
    let session = URLSession.shared
    var request = URLRequest(url: url)

    request.httpMethod = "POST"
    do {
        request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
    } catch _ {
        }

        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("application/json", forHTTPHeaderField: "Accept")

        let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
            guard error == nil else {
                return
            }
            guard let data = data else {
                return
            }
            do {
                if let jsonResponse = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
                        // Here I want to access the json response
                    }
            } catch _ {
            }
        })
    task.resume()
}
1
  • 3
    please remove the json image and paste it in as code text. Commented Mar 25, 2020 at 21:39

1 Answer 1

3

The best way to make a call request with SwiftUI is to use Combine.

You will first have to create a Model of your JSON object that you want to get back:

import Foundation

//MARK: - Your object to retrieve from JSON
struct Doctor: Codable, Identifiable {
  let id = UUID()
  let patients: [Patients]
}

struct Patients: Codable {
  let id: String
  let name: String
  let phone: String
}

You then create a class that will handle your JSON requests using Combine (I added a plus for you to handle any response error):

import Foundation
import Combine

class Network {

  // Handle your request errors
  enum Error: LocalizedError {
    case invalidResponse
    case addressUnreachable(URL)

    var errorDescription: String? {
      switch self {
      case .invalidResponse:
        return "The server responded with garbage."
      case .addressUnreachable(let url):
        return "\(url.absoluteString) is unreachable."
      }
    }
  }

  // Add your url
  let urlRequest = URL(string: "your url")!

  // Networking on concurrent queue
  let networkQueue = DispatchQueue(label: "Networking",
                                   qos: .default,
                                   attributes: .concurrent)

  // Combine network call (This replace your previous code)
  func downloadPatients() -> AnyPublisher<Doctor, Error> {
    URLSession.shared
      .dataTaskPublisher(for: urlRequest)
      .receive(on: networkQueue)
      .map(\.data)
      .decode(type: Doctor.self, decoder: JSONDecoder())
      .mapError { (error) -> Network.Error in
        switch error {
        case is URLError:
          return Error.addressUnreachable(self.urlRequest)
        default:
          return Error.invalidResponse
        }
    }
    .eraseToAnyPublisher()
  }
}

And now, in your SwiftUI file, where you need this values, you just need to call the downloadPatients() function and use the return data as you wish:

import SwiftUI

let networkRequest = Network()

//MARK: - Call this function where you want to make your call
func loadPatients() {
  _ = networkRequest.downloadPatients()
    .sink(
      receiveCompletion: {
        print("Received Completion: \($0)") },
      receiveValue: { doctor in
        // doctor is your response and [0].name is your first patient name
        print(doctor.patients[0].name) }
  )
}
Sign up to request clarification or add additional context in comments.

3 Comments

hello @Roland i use your answer but have a query
What kind of query do you have? Bearer? Content-Type? Authentification? Can you post a question on StackOverflow with your URLRequest specificity and add the link on the conversation?
hey thanks @Roland for reply i post my question here can you plz help stackoverflow.com/questions/66043573/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.