1

I'm working on a feature that involves sending a JSON request and then receiving a JSON response. However, I'm facing an issue while trying to display the received JSON data on a subsequent view, specifically the JSONResponseView.

The problem I'm encountering is that when I navigate to the JSONResponseView, I'm only seeing an empty JSON object displayed there [:]. This is perplexing to me because I can confirm from the console logs that I am indeed receiving a valid JSON response.

To give you a bit more context, I have a process in place where I make the JSON request, receive a JSON response, and then attempt to present the JSONResponseView with the received JSON data. However, even though I'm triggering the JSONResponseView presentation after receiving the response, the view seems to display an empty JSON object.

Is there a possibility of a delay in receiving the JSON response. I've verified that the timing of when I trigger the JSONResponseView and when the response arrives is nearly instantaneous, down to the millisecond level.

Why might I be encountering this behavior? How can I properly pass and display the received JSON data on the JSONResponseView?

var body: some View {
    Form {
        PersonDetailsSection(name: $person1Name, title: "Enter Person 1's Details")
        
        Button {
            if let jsonData = JSONPayloadGenerator.createPayload(person1Name: person1Name) {
                sendRequest(with: jsonData)
            }
        }
    }
    .navigationBarTitle("My App")
    .padding()
    .sheet(isPresented: $showingResponseView) {
        JSONResponseView(jsonResponse: responseJSON)
    .onAppear {
        print("Presenting JSONResponseView")
    }
}

func sendRequest(with jsonData: Data) {
    // Create the URL
    guard let url = URL(string: "http://localhost:7071/api") else {
        print("Invalid URL")
        return
    }
    
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.httpBody = jsonData
    
    // Make the request
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        if let error = error {
            print("Error:", error)
            return
        }
        
        guard let data = data else {
            print("No data received")
            return
        }
        
        // Print the raw JSON data received from the server
        if let jsonString = String(data: data, encoding: .utf8) {
            print("-->Raw JSON Data Received:", jsonString)
        }
        
        do {
            let result = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
            print(" Report:", result ?? "No result")
            
            // Update the responseJSON state with the received JSON data
            responseJSON = result ?? ["Test": "OK"]
            
            // Present the JSONResponseView
            showingResponseView = true
        } catch {
            print("Error parsing JSON:", error)
        }
    }
    
    task.resume()
    
    // Print the JSON payload
    if let jsonString = String(data: jsonData, encoding: .utf8) {
        print("Generated JSON Payload Outgoing:\n", jsonString)
    }
}
}
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Avinash Kumar
  • 298
  • 3
  • 13
  • 1
    Use `sheet(item:)` or change `.sheet(isPresented: $showingResponseView) {` to `.sheet(isPresented: $showingResponseView) { [responseJSON] in` See https://stackoverflow.com/questions/66162219/swiftui-switch-sheet-on-enum-does-not-work – jnpdx Aug 05 '23 at 18:15
  • You do not update your state var in main queue. – Ptit Xav Aug 05 '23 at 20:01
  • Thank you @jnpdx. `.sheet(isPresented: $showingResponseView) { [responseJSON] in JSONResponseView(jsonResponse: responseJSON)` has worked. – Avinash Kumar Aug 06 '23 at 00:20
  • Great -- please consider upvoting the answer I linked to if it was helpful – jnpdx Aug 06 '23 at 00:50
  • @jnpdx Done ~~ Thank you again – Avinash Kumar Aug 06 '23 at 06:54

1 Answers1

0

Thanks to @jnpdx, the code is working now.

I have changed:

.sheet(isPresented: $showingResponseView) {
    if showingResponseView {
        JSONResponseView(jsonResponse: responseJSON)
    }
}

to

.sheet(isPresented: $showingResponseView) { [responseJSON] in
    JSONResponseView(jsonResponse: responseJSON)
}
koen
  • 5,383
  • 7
  • 50
  • 89
Avinash Kumar
  • 298
  • 3
  • 13