Search code examples
iosswiftxcodeswiftuialamofire

How to read the data with button press in SwiftUI view where, data called from function


I am trying to learn network request using Alamofire in SwiftUI. I am trying to fetch data from a URL and display it on my simulator screen. I have used a button on tap of which , the fetched data will get displayed. The problem is on tap of the button nothing is getting printed.

I tried using debugPrint() and print() turn by turn, but nothing is getting printed , neither on simulator screen nor in console. How do i achieve the same, here is what i tried -->

import SwiftUI
import Alamofire

struct ContentView: View {
    
    @State var tapped : Bool = false
    
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundStyle(.tint)
            Text("Hello, world!")
            Button(action: read, label: {
                Text("Let's Begin!")
            })
            .padding()
        }
        
    }
}

func read() {
    print ("%%%%%%%%%%%%%%%")
    AF.request("https://httpbin.org/get").response { response in
            debugPrint("Response : \(response)")
    }
}

#Preview {
    ContentView()
}

Solution

  • Usually you would bounce it over to a task, like this:

    struct ContentView: View {
        
        @State var isReading : Bool = false
        @State var result = ""
    
        var body: some View {
            VStack {
                Image(systemName: "globe")
                    .imageScale(.large)
                    .foregroundStyle(.tint)
                Text("Hello, world!")
                Button(action: {
                    isReading.toggle()
                }, label: {
                    Text(isReading ? "Cancel" : "Let's Begin!")
                })
                .padding()
                .task(id: isReading) {
                    if !isReading { return }
                    do {
                        result = await read()
                    }
                    catch {
                        // use error
                    }
                    isReading = false
                }
            }
        }
    }
    
    func read() async throws -> String {
        print ("%%%%%%%%%%%%%%%")
    
        let response = try await withCheckedThrowingContinuation { continuation in
                AF.request("https://httpbin.org/get")
                .responseData { response in
                    switch(response.result) {
                    case let .success(data):
                        continuation.resume(returning: data)
                    case let .failure(error):
                        continuation.resume(throwing: error)
                    }
                }
            }
        let result = // process response into your result
        return result
    }