Swift PlaygroundでConcurrencyを使う by Xcode 13.2.1
Swift 5.5で登場したSwift Concurrency。
async/awaitを使うことで、並列処理を上から下に流れるように記述することができます。
どんな風に使えるかをSwift Playgroundで試そうとしたところ、Swift Playgroundではいろいろ制限があるようなのでまとめました。
検証環境
- Xcode 13.2.1
- Swift 5.5
_Concurrencyをインポートする
Swift Concurrencyの機能をSwift Playgroundで使う場合、まず最初にすることは _Concurrencyというフレームワークをインポートすることです。
明示的にインポートしないでConcurrencyの型を実行すると「スコープにそんな型は見つからない」とエラーになります。
手元ではコンパイルエラーにはならず、実行時にエラーが表示されました。
例えば_ConcurrencyをインポートしないでTaskを実行します。
Task.detached {}
するとデバックエリアにこのようなエラーが出力されます。
error: request-with-async.xcplaygroundpage:57:1: error: cannot find 'Task' in scope
Task.detached {
^~~~
ページの先頭でインポートしておきましょう。
import _Concurrency
Task.detached {}
一部の機能がまだ使えない
残念ながら、import _ConcurrencyをしてもSwift PlaygroundはSwift Concurrencyの一部の機能はまだ使えないようです。
並列実行を可能にするasync letという記法がまだ使えません。
下記のようなコードを実装するとエラーが出力されます。
//// 並列実行
/// 残念ながら、Xcode 13.2.1ではまだPlayground上でasync letは動かない
Task.detached {
    // async letはplaygroundでは動かないそう
    async let appleIcon = request(with: imageURLs[0])
    async let openstack = request(with: imageURLs[1])
    async let tensorflow = request(with: imageURLs[2])
    print(try await appleIcon, try await openstack, try await tensorflow)
}
こんなエラーです。
error: parallel-execution.xcplaygroundpage:80:15: error: expression is 'async' but is not marked with 'await'
    async let appleIcon = request(with: imageURLs[0])
              ^~~~~~~~~
              await 
コンパイルがasync letを知らないみたいです。
仕方がないので、async letはアプリ開発で試しましょう。
まとめ
Xcode 13.2.1ではまだSwift Concurrencyのすべての機能をサポートしているわけではないようです。
ただ、async/awaitの動きを手軽に試せるのはSwift Playgroundの魅力ですね。
参考記事
- Why "error: cannot find 'Task' in scope" in Xcode Playground? - Using Swift - Swift Forums
- ios - Swift 5.5 async let - error: expression is 'async' but is not marked with 'await' - Stack Overflow
宣伝
BOOTHより、「Swift Concurrency入門」発売中です。
Swift Concurrencyを網羅的に学べ、さらに既存アプリへの適応方法も解説しています。
日本語で体系的に学べる解説本は他になかなかありません。
1章、2章が立ち読みできるおためし版もありますので、ぜひチェックしてください!
