Home > database >  how can i merge these SwiftUI async tasks in one task to get a correct result from function when cha
how can i merge these SwiftUI async tasks in one task to get a correct result from function when cha

Time:06-15

I want to update and use container members in picker , textfield and get price function.

struct PropertyContainer: Equatable {
    static func == (lhs: PropertyContainer, rhs: PropertyContainer) -> Bool {
        return lhs.fromQty == rhs.fromQty && lhs.fromCurrency == rhs.fromCurrency && lhs.toCurrency == rhs.toCurrency && lhs.toQty == rhs.toQty
    }
    @State var toQty: Double = 1.0
    @State var toCurrency: String = "ETH"
    @State var fromQty: Double = 1.0
    @State var fromCurrency: String = "BTC"
}

struct ContentView: View {
@State private var propertyContainer = PropertyContainer()

using memebers of container in text field and picker so I need updates for getprice func.

.task(id: propertyContainer) {
            do {
                price = try await listMaker.getPrice(fromCurrency: propertyContainer.fromCurrency, fromQty: propertyContainer.fromQty, toCurrency: propertyContainer.toCurrency, toQty: propertyContainer.toQty, type: "Fixed")
                print(propertyContainer.fromCurrency)
            } catch {
                print("Error")
            }
        }

CodePudding user response:

As all of your function calls are the same you could do it with a bit of refactoring:

  1. Create a struct that contains all the properties you want to react to (Note: as you did not provide the properties e.g. toQty... this will be a general example):

    struct PropertyContainer: Equatable{ //important to conform to Equatable
        var property1: Bool = true
        var property2: Bool = true
        // and so on....
    }
    
  2. Create a @State var that holds your properties in your View:

    @State private var propertyContainer = PropertyContainer()
    
  3. Create your task as follows:

    .task(id: propertyContainer) {
     do {
     price =
         try await listMaker.getPrice(fromCurrency: fromCurrency, fromQty: fromQty, toCurrency: toCurrency, toQty: toQty, type: "Fixed")
       } catch {
       print("Error")
       }
    }
    

Now access (read and write) your properties only through the container propertyContainer e.g.:

Button {
    propertyContainer.property1.toggle()
} label: {
    Text("label")
}

When you change a property in your container the whole struct changes and your task gets executed.

Edit:

Example for Picker:

Picker("", selection: $propertyContainer.selected) {//beware the $ for the binding
    ForEach(selectable) { selection in
        Text(selection)
    }
}
  • Related