'Swift Playground with async/await "cannot find 'async' in scope"

I'm trying to run this async function on Xcode Playground:

import Foundation
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

enum NetworkingError: Error {
    case invalidServerResponse
    case invalidCharacterSet
}

func getJson() async throws -> String {
        let url = URL(string:"https://jsonplaceholder.typicode.com/todos/1")!
        let (data, response) = try await URLSession.shared.data(from: url)
        
        guard let httpResponse = response as? HTTPURLResponse,
              httpResponse.statusCode == 200 else {
                  throw NetworkingError.invalidServerResponse
              }
        
        guard let result = String(data: data, encoding: .utf8) else {
            throw NetworkingError.invalidCharacterSet
        }
        
        return result
}
    
let result = try! await getJson()
print(result)

and I'm receiving this error message:

error: ForecastPlayground.playground:27:25: error: 'async' call in a function that does not support concurrency
let result = try! await getJson()
                        ^

So I tried to create am async block in my func call:

async{
    let result = try! await getJson()
    print(result)
}

And then I received this error message:

Playground execution failed:

error: ForecastPlayground.playground:27:1: error: cannot find 'async' in scope
async{
^~~~~

I tried to annotated my function with the new @MainActor attribute and it doesn't work.

What I'm doing wrong?



Solution 1:[1]

Add an import to _Concurrency (underscore because this is supposed to be included by default) or a library that makes use of the library, such as UIKit or SwiftUI. It appears that Swift Playgrounds don't have access to all concurrency features at the moment though, such as async let.

In summary

import _Concurrency

Solution 2:[2]

For Xcode 13, to use async and await in a Playground, just import Foundation and wrap the code in a detached task.

import Foundation

Task.detached {
    func borat() async -> String {
        await Task.sleep(1_000_000_000)
        return "great success"
    }

    await print(borat())
}

And this is because there are only 3 places your code can call asynchronous functions: (1) in the body of an asynchronous function or property; (2) in the static main() method of a class, structure, or enumeration that’s marked with @main; (3) in a detached child task.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 fake girlfriends