swiftxcode12wwdcswift5

error: Couldn't lookup symbols: nominal type descriptor for Swift.Task.Handle trying async/await with Xcode 12.5 beta / Swift 5.5


I'm trying to figure out how to use async/await in a Playground using Xcode 12.0 beta / Swift 5.5, but am getting an error every time.

Here's my entire playground code, which is probably wrong:

import Cocoa
import Foundation

if #available(macOS 12.0, *) {
    
    class Foo {
        func reversed(_ s: String) async -> String {
            Thread.sleep(forTimeInterval: 10)
            return String(s.reversed())
        }
    }
    
    detach {
        let foo = Foo()
        let result = await foo.reversed("Chowhound")
        print("Result is \(result)")
    }
}

I'm getting this error:

error: Couldn't lookup symbols: nominal type descriptor for Swift.Task.Handle

Any solution would be great!


Solution

  • I figured it out!

    So the deal is that anything that calls async must also be async itself. So if you are doing await anything in your function, that function itself must also be async.

    So that would mean that everything everywhere must end up async, right?

    Nope. The solution is wrapping the calling function in async { }, which I learned by watching this very helpful WWDC video

    So the good code ends up being this:

    import Cocoa
    import Foundation
    
    if #available(macOS 12.0, *) {
        
        class Foo {
            func reversed(_ s: String) async -> String {
                Thread.sleep(forTimeInterval: 2)
                return String(s.reversed())
            }
        }
        
        let foo = Foo()
        async {
            let result = await foo.reversed("Chowhound")
            print("Result is \(result)")
        }
        // The above runs asynchronously, and probably won't run before this:
        print("The async block above probably runs after me.")
    }
    

    The async wrap schedules the block within to run asynchronously, soon - a little bit like when you do DispatchQueue.main.async{}. So in the corrected code above, the print statement at the bottom will likely run prior to async block above it.