Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recurring function in Swift 5.5 using async/await

I want to keep firing a function 5 seconds after it completes.

Previously I would use this at the end of the function:

Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { self.function() }

But I am wanting to use Swift 5.5's async/await.

If I use something like this:

func loadInfo() async {
    async let info = someOtherAsyncFunc()
    self.info = try? await info
    await Task.sleep(5_000_000_000)
    await loadInfo()
}

I get a warning that the Function call causes an infinite recursion and it's not really cancellable.

This compiles fine:

func loadInfo() async {
    Task {
        async let info = someOtherAsyncFunc()
        self.info = try? await info
        await Task.sleep(5_000_000_000)
        if Task.isCancelled {
            print("Cancelled")
        }
        else
        {
            print("Not cancelled")
            await loadInfo()
        }
    }
}

and although it does fire every 5 seconds, it keeps running when my SwiftUI view is dismissed. I start it using:

.onAppear {
    loadInfo()
}

As it's all running on the same Task and not detached should it not all cancel when the view is removed?

What is the modern way to achieve this with async/await?

like image 972
Darren Avatar asked Feb 20 '26 22:02

Darren


1 Answers

The point of async await is to let you write asynchronous code in a synchronous way. So you could remove the recursive function and simply write:

.task {
    repeat {
        // code you want to repeat
        print("Tick")

        try? await Task.sleep(for: .seconds(5)) // exception thrown when cancelled by SwiftUI when this view disappears.
    } while (!Task.isCancelled) // if the view disappears and the above line exceptions early before 5 seconds are up, we can then check this bool to exit the loop.
    print("Cancelled")  
}

I noticed the print tick is always on main thread however if I move it out to its own async nonisolated func then it correctly runs on different threads.

like image 86
malhal Avatar answered Feb 22 '26 11:02

malhal