Reputation: 556
The compiler said,
Cannot pass function of type '() async -> Void' to parameter expecting synchronous function type
This is the problem code:
DispatchQueue.global().async {
await CreateFolder()
do {
let FilePath = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
let FileName = UUID().uuidString
try! Image.pngData()!.write(to: FilePath.appendingPathComponent("Images").appendingPathComponent("\(FileName).png"))
} catch {
Prompt(error.localizedDescription)
}
}
Upvotes: 0
Views: 185
Reputation: 437392
We can tell that CreateFolder
is not an async
method, and as a result, you should not await
it when calling it from within the GCD dispatch.
But the deeper problem is that you should avoid GCD queues when using async-await. You want to use the Swift concurrency cooperative thread pool. To do that, you would use Task
.
But you do not want Task { ... }
(or Task.init { ... }
). If you want this behavior of running it in the background (like your global queue example), you would create a detached
task:
Task.detached {
CreateFolder() // you may now need the `await`, unless this function is marked as `nonisolated`
...
}
We use Task { ... }
when we want to launch a task on the current actor, but one that honors the Swift concurrency contract to never prevent forward progress. We use Task.detached { ... }
when the code being run is slow and synchronous and does not honor the Swift concurrency contract.
Upvotes: 2
Reputation: 132
Async methods call in a function that does not support concurrency.
You can use Task.init
Task.init {
do {
_ = try await CreateFolder()
let FilePath = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
let FileName = UUID().uuidString
try! Image.pngData()!.write(to: FilePath.appendingPathComponent("Images").appendingPathComponent("\(FileName).png"))
} catch {
Prompt(error.localizedDescription)
}
}
Upvotes: 1
Reputation: 556
Remove await
from DispatchQueue
closure.
Fixed:
DispatchQueue.global().async {
CreateFolder()
do {
let FilePath = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
let FileName = UUID().uuidString
try! Image.pngData()!.write(to: FilePath.appendingPathComponent("Images").appendingPathComponent("\(FileName).png"))
} catch {
Prompt(error.localizedDescription)
}
}
Upvotes: 0