Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How can I use the return from my function as an argument for another function in onAppear

I am trying to use the result of the following function:

class GetRefresh: ObservableObject {
   let user = Auth.auth()
   var ref = Database.database().reference()
   @Published var refreshToken = ""
   func getRefresh() {
       ref.child("\(user.currentUser!.uid)").child("refreshUrl").getData { error, snapshot in
        guard error == nil else {
            print(error!.localizedDescription)
            return
        }
        let refreshUrl = snapshot.value as? String ?? "Unknown"
        let url = URL(string: refreshUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!)
        var request = URLRequest(url: url!)
        request.httpMethod = "POST"
        URLSession.shared.dataTask(with:request) { (data, response, error) in
          if error != nil {
            print(error)
          } else {
            do {
              let parsedData = try JSONSerialization.jsonObject(with: data!) as! [String:Any]
              let token = parsedData["access_token"] as? String
              self.refreshToken = token!
            } catch let error as NSError {
              print(error)
            }
          }
        }.resume()
    }
  }
}

To pass as an argument to a Async service that is called in the onAppear of my view:

struct DevicesTab: View {
   @StateObject var callDevices = CallDevices()
   @StateObject var getRfrsh = GetRefresh()
   var ref: DatabaseReference!
   var body: some View {
       VStack(spacing: 0) {
           greeting.edgesIgnoringSafeArea(.top)
           messages
           Spacer()
       }
      .onAppear {
          getRfrsh.getRefresh()
          callDevices.getDevices(refreshToken: getRfrsh.refreshToken) //this fails
          }
      }
   }

The callDevices.getDevices is using the argument as a Header for its URLRequest.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

If i hardcode the token in onAppear like:

.onAppear {
   getRfrsh.getRefresh()
   callDevices.getDevices(refreshToken: "HardcodedToken") //this works
  }

It works fine, albeit with a bit of a delay before the data is loaded but it works…
I am sure the function is returning correctly as I was able to print it in GetRefresh.

>Solution :

Well the reason for your code failing is you are not waiting for the network call to be completted before you call the next method.

Solution:

You could rework the code to be async. Or you could observe the changes of your @Publishedvar and call getDevices.

.onChange(of: getRfrsh.refreshToken) { newValue in
            callDevices.getDevices(refreshToken: newValue)
        }
.onAppear {
// to avoid repeatitive refreshing
      if getRfrsh.refreshToken == ""{
         getRfrsh.getRefresh()}
      }

But be aware. This will call getDevicesevery time the value changes.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading