Call 2o API after finishing 1st one

I have a button that when pressed should call an API which return an ID. Then having this ID, I will call a 2nd API.

Button(action: {
  var id = self.callApi1()
  self.callApi2(id)
}) {
      Text("Start")
}

How can I call the Api2 JUST when the Api1 was finished and returned its value ?
Thank you
Answered by Claude31 in 696736022

I tested the following:

struct ContentView: View {
    
    func callApi1() -> String {
        print("callApi1")
        return "Returned from api1"
    }
    
    func callApi2(_ id: String) {
        print("callApi2 "+id)
    }
    
    var body: some View {
            Button(action: {
              var id = self.callApi1()
              self.callApi2(id)
            }) {
                  Text("Start")
            }

        }
}

.

And get the following, proving that id was passed.

  • callApi1
  • callApi2 Returned from api1

What is it you want to do differently ?

You could use completion handlers:

struct ContentView: View {
    
    typealias API4 = (String) -> Void
    
    func callApi3(completion: API4) {
        print("callApi3")
        let value = "Some value"
        completion(value)
        return
    }
    
    func callApi4(_ value:String) {
        print("callApi4 with ", value)
    }
    
    var body: some View {
            Button(action: {
                self.callApi3(completion: callApi4 )
            }) {
                  Text("Start with completion")
            }

        }
}

To get:

  • callApi3
  • callApi4 with Some value
Accepted Answer

I tested the following:

struct ContentView: View {
    
    func callApi1() -> String {
        print("callApi1")
        return "Returned from api1"
    }
    
    func callApi2(_ id: String) {
        print("callApi2 "+id)
    }
    
    var body: some View {
            Button(action: {
              var id = self.callApi1()
              self.callApi2(id)
            }) {
                  Text("Start")
            }

        }
}

.

And get the following, proving that id was passed.

  • callApi1
  • callApi2 Returned from api1

What is it you want to do differently ?

You could use completion handlers:

struct ContentView: View {
    
    typealias API4 = (String) -> Void
    
    func callApi3(completion: API4) {
        print("callApi3")
        let value = "Some value"
        completion(value)
        return
    }
    
    func callApi4(_ value:String) {
        print("callApi4 with ", value)
    }
    
    var body: some View {
            Button(action: {
                self.callApi3(completion: callApi4 )
            }) {
                  Text("Start with completion")
            }

        }
}

To get:

  • callApi3
  • callApi4 with Some value

I dont want to do differently. But when I do this way, self.callApi2(id) doesnt wait for self.callApi1 to finish. self.callApi2(id) is triggered at the same time and because doesnt have an ID yet, it fails.

 var id = self.callApi1()
  self.callApi2(id)

I dont want to do differently. But when I do this way, self.callApi2(id) doesnt wait for self.callApi1 to finish. self.callApi2(id) is triggered at the same time and because doesnt have an ID yet, it fails.

 var id = self.callApi1()
  self.callApi2(id)

You should have said that callApi1 was an async func. Then, your code will not work. So what do you mean you don't want to do differently something that doesn't work ?

  • did you look at the solution with completion handler ? Does it work ?
  • otherwise, please show the callApi1 real definition. Have you access to its source code ?
  • maybe async / await could be used here (it is done for this) but you must first show code.
Call 2o API after finishing 1st one
 
 
Q