1

I am new to Swift language. I would like to know what is the alternative of wait all tasks to finish before executing the next functions in Swift?

I tried the async/await functions of Swift, but the functions just run in the background instead of waiting until the tasks finish.

Thank you.

func checkData(firstName: String) async {
  Task(priority: .high) {
    await compareFirstName(firstName: firstName)
  }
  
  Task(priority: .low) {
    await uploadFirstName(firstName: firstName)
  }
}

I want the compareFirstName() to finish first, but the uploadFirstName() always finish before the compareFirstName().

Steven-Carrot
  • 2,368
  • 2
  • 12
  • 37
  • Please provide enough code so others can better understand or reproduce the problem. – Community Jun 18 '22 at 21:16
  • 1
    Swift uses a model of [structured concurrency](https://docs.swift.org/swift-book/LanguageGuide/Concurrency.html#ID642) for this. You can either manually create and use `TaskGroup`s, or you can use [`async let`](https://docs.swift.org/swift-book/LanguageGuide/Concurrency.html#ID641) to automatically have them generated for you. – Alexander Jun 18 '22 at 21:19
  • 1
    Try sticking everything in the Task block, async has been deprecated. – cora Jun 19 '22 at 03:21
  • Hi Alexander and Cora, i tried based on your advices, but the second function in my code still execute before the first one. Why? Please check my edited code. – Steven-Carrot Jun 19 '22 at 15:29
  • You could use a serial DispatchQueue – birkoof Jun 20 '22 at 07:21
  • @birkoof - No, you definitely don’t want to unnecessarily introduce a GCD serial queue in the middle of an `async`-`await` codebase. – Rob Jun 22 '22 at 13:19
  • Ive been testing everyone advise, but still it did not work as usual like when i did in kotlin – Steven-Carrot Jun 25 '22 at 22:19

1 Answers1

1

I tried the async/await functions of Swift, but the functions just run in the background instead of waiting until the tasks finish.

Because you wrote your code wrong. Put the awaits into one task:

func checkData(firstName: String) async {
  Task {
    await compareFirstName(firstName: firstName)
    await uploadFirstName(firstName: firstName)
  }
}

Moreover, if checkData is async, you don't need the Task:

func checkData(firstName: String) async {
  await compareFirstName(firstName: firstName)
  await uploadFirstName(firstName: firstName)
}

If it is crucial that they run on different priorities, you can do various things such as nesting tasks.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Good answer! +1. The second is likely the appropriate approach. In this case, the “priorities” were undoubtedly a well-intentioned (but misguided) way of the OP to try to indicate relative priorities of two concurrent tasks. I’d advise against your first approach, as the `async` qualifier is declaring an informal contract, leading the caller to assume that it can `await` the asynchronous task, when, in fact, this first rendition will not. (In fact, if the OP employed this “throw in an unnecessary `Task { ... }`” pattern within `compareFirstName`, then even your second approach won't work!) – Rob Jun 22 '22 at 13:18
  • Ive been testing everyone advise, but still it did not work as usual like when i did in kotlin – Steven-Carrot Jun 25 '22 at 22:19