Overview 概要
Note 注意
This sample code project is associated with WWDC21 session 10194: Swift Concurrency: Update a Sample App. この見本コードプロジェクトは、WWDC21 セッション 10194: Swift Concurrency: Update a Sample Appと関連します。
Swift concurrency provides a standard set of language tools and techniques for concurrent programming. However, you may already have an existing project built with concurrency that uses other frameworks and techniques. You don’t have to convert all of your code all at once; instead, you can use specific refactoring techniques to convert your code one piece at time. Swift並行性は、標準的な一揃いの言語ツールと技法を並行性プログラミングのために提供します。しかしながら、あなたは既に、他のフレームワークと技法を使う並行性でビルドされた既存のプロジェクトを持っているかもしれません。あなたは、あなたのコードの全てを一斉に変換する必要はありません;あなたは特定のリファクタリング技法を使ってあなたのコードを一度に一断片ずつ変換できます。
This sample provides two separate versions of the Coffee Tracker app: この見本は、2つの別のバージョンのCoffee Trackerアプリを提供します:
The original version uses completion handlers to query the HealthKit SDK and to respond to
CLKComplication
calls, and dispatch queues to isolate concurrent access to memory. For more information on the original version, see Creating and Updating a Complication’s Timeline. オリジナルバージョンは、完了ハンドラを、HealthKit SDKへの問い合わせのためそしてData Source CLKComplication
呼出しへの応答のために、そしてディスパッチキューを、メモリへの並行アクセスを隔離するために使います。オリジナルバージョンに関するさらなる情報として、Creating and Updating a Complication’s Timelineを見てください。Data Source The updated version uses Swift’s concurrency features to provide clearer code with better error checking at compile time. It replaces the completion handlers with
async
functions, and uses actors to guarantee safe access to data. 更新されたバージョンは、Swiftの並行性機能を使って、明快なコードをより良いコンパイル時でのエラーチェックとともに提供します。それは、完了ハンドラをasync
関数で置き換えます、そしてアクターを使ってデータへの安全なアクセスを保証します。
Watch the session to see the process step by step, and then compare the two projects to see the differences. この過程を段階的に理解するためにセッションを視聴してください、そしてそれから2つのプロジェクトを比べてその違いを見てください。
Configure the Sample Code Project 見本コードプロジェクトを構成設定する
To add the complication to an active watch face, start by building and running the sample code project in the simulator, and follow these steps: コンプリケーションをアクティブなウォッチフェイスに加えるには、見本コードプロジェクトをシミュレータにおいてビルドおよび実行することによって始めます、そしてこれらの段階に従ってください:
Click the Digital Crown to exit the app and return to the watch face. Digital Crownをクリックして、アプリを出て、ウォッチフェイスに戻ってください。
Using the trackpad, firmly press the watch face to put the face in edit mode, then tap Customize. トラックパッドを使って、しっかりウォッチフェイスを押して、フェイスを編集モードに入れて、それからCustomizeをタップしてください。
Swipe left until the configuration screen highlights the complications. Select the complication to modify. 構成画面がコンプリケーションをハイライト表示するまで、左にスワイプしてください。修正するためにコンプリケーションを選択します。
Scroll to the Coffee Tracker complication, and then click the Digital Crown again to save your changes. Coffee Trackerコンプリケーションまでスクロールしてください、そしてそれからDigital Crownを再びクリックしてあなたの変更を保存してください。
Tap the Coffee Tracker complication to go back to the app. Coffee Trackerコンプリケーションをタップしてアプリに戻ってください。
For more information on setting up watch faces, see Change the watch face on your Apple Watch. ウォッチフェイスを設定することに関するさらなる情報として、Change the watch face on your Apple Watchを見てください。
After configuring and running the Coffee Tracker app, you can test the background updates. Make sure the Coffee Tracker complication appears on the active watch face. Then build and run the app in Simulator, and follow these steps: Coffee Trackerアプリを構成設定および実行した後、あなたはバックグラウンド更新をテストできます。Coffee Trackerコンプリケーションがアクティブなウォッチフェイス上に現れることを確かめてください。それからアプリをシミュレータ上でビルドおよび実行してください、そしてこれらの手順に従ってください:
Add one or more drinks using the app’s main view. 1つ以上の飲み物を、アプリのメインビューを使って加えてください。
Click the Digital Crown to send the app to the background. Digital Crownをクリックして、アプリをバックグラウンドに送ってください。
Open Settings, and scroll down to Health > Health Data > Nutrition > Caffeine to see all of the drinks you added to the app. Settingsを開いて、そして Health > Health Data > Nutrition > Caffeine へと下にスクロールして、あなたがアプリに加えた飲み物の全てを見てください。
Click Delete Caffeine Data to clear all of the caffeine samples from HealthKit. Delete Caffeine Data をクリックして、カフェイン見本の全てを HealthKit から消去してください。
Navigate back to the watch face. ウォッチフェイスに戻ってください。
Coffee Tracker updates the complication within 15 minutes; however, the update may be delayed based on the system’s current state. Coffee Tracker は、コンプリケーションを 15 分以内に更新します;しかしながら、更新はシステムの現在の状態に依存して遅れるかもしれません。
Convert Completion Handlers to Use Asynchronous Methods 完了ハンドラを変換して非同期メソッドを使うようにする
The Health
type contains several calls to the HealthKit SDK. In SDKs that support Swift concurrency, frameworks add async
-await
versions of most functions that previously took completion handlers. You can remove completion handlers by updating these calls to use the async
-await
versions. You suspend the store
operation by adding the await
keyword. Execution resumes after the await
completes. An async
function can also be a throwing function, which you call by prepending try await
to the function call. Wrap the call in a do-catch
statement instead of using an Error?
type as a parameter to the completion handler.
Health
型は、HealthKit SDKへのいくつかの呼び出しを含みます。Swift並行性をサポートするSDKにおいて、フレームワークそれらは以前は完了ハンドラをとっていた大部分の関数のasync
-await
バージョンを加えます。あなたは完了ハンドラそれらを取り除くことがそれらの呼び出しをasync
-await
版を使うよう更新することで可能です。あなたはstore
操作を、await
キーワードの追加によって一時停止します。遂行は、await
が完了した後に再開します。async
関数はまた、あるスロー関数であることが可能です、それはあなたがtry await
をその関数呼び出しの前に付けることによって呼び出すものです。呼び出しをdo-catch
文の中に包んでください、Error?
型をパラメータとして完了ハンドラに使う代わりに。
In some cases an SDK call requires using a completion handler. For example, a call to init(type:
takes a completion handler, but the call that needs to await
is the call to execute(_:)
.
いくつかの場合においてSDKは完了ハンドラを使うことを要求します。例えば、init(type:
への呼び出しは完了ハンドラをとります、しかしawait
する必要がある呼び出しは、execute(_:)
への呼び出しです。
To await
the results of a completion handler in these cases, add a continuation
:
それらの場合に完了ハンドラの結果をawait
するには、continuation
を加えてください:
To protect the stored properties on the controller when accessed asynchronously, change Health
from a class
type to an actor
:
格納プロパティをコントローラ上で非同期にアクセスされた時に保護するには、Health
をclass
型からactor
へと変えてください:
Calls to async
functions from synchronous functions are made by creating new asynchronous tasks, which can use await
to wait for completion:
async
関数への非同期関数からの呼び出しは、新しい非同期タスクを作成することによって作られます、それらは await
を使うことで完了に対して待機できます:
Put the Coffee Data Class on the Main Actor Coffee Data Classをメインアクター上に置く
The Coffee
class implements Observable
and has an @Published
property to feed the SwiftUI views. To ensure that all updates to this property are made on the main thread, place the type on the main actor:
Coffee
クラスは、Observable
を実装して、そしてSwiftUIビューに供給する@Published
プロパティを持ちます。このプロパティへの全ての更新がメインスレッド上でなされることを確実にするために、その型をメインアクター上に置いてください:
Two methods that perform synchronous IO — the load
and save
methods — are factored out into a separate Coffee
actor, which performs these activities away from the main thread. The model type on the main actor must use await
to call methods on the Coffee
actor, which allows other work to run on the main thread during the synchronous IO operations.
同期的なIOを実行する2つのメソッド — load
とsave
メソッド — それらは、ある隔てられたCoffee
アクターへと抽出されます、それはこれらの活動をメインスレッドから離して実行します。メインアクター上のmodel型は、await
を使ってメソッドそれらをCoffee
アクター上で呼び出さなければなりません、それは他の作業が同期IO操作の間にメインスレッド上で動作するのを可能にします。
The two types communicate by passing an array of Drink
values, which is a value type because Drink
is a structure. Loading returns an array of drinks, and saving takes an array of drinks as an argument.
2つの型は、Drink
値それらからなるある配列を渡すことによって通信します、それは値型です、なぜならDrink
が構造体であるからです。ロードでは、ドリンクそれらからなるある配列を返します、そしてセーブ(保存)ではドリンクそれらからなるある配列を引数としてとります。
To perform all methods asynchronously, replace the current
property’s did
operation with private(set)
and add a new async
method named drinks
. Move the code from the setter into the new method. Call the drinks
after any code that sets the current
property, using an await
call.
全てのメソッドを非同期に実行するには、current
プロパティのもつdid
演算をprivate(set)
で置き換えます、そして新しいasync
メソッドをdrinks
という名前で加えてください。コードをそのセッターから新しいメソッドに移動してください。drinks
を、current
プロパティを設定するあらゆるコードの後に呼び出してください、await
呼出を使って。
Update the drinks
method to call the Coffee
actor using an await
call. The Coffee
actor saves the data on a background thread.
drinks
メソッドを更新して、Coffee
アクターをawait
呼出を使って呼び出すようにください。Coffee
アクターは、データをあるバックグラウンドスレッド上で保存します。
Calls to the Coffee
object from SwiftUI views don’t require any use of await
as these views are also on the main actor due to their use of @Environment
.
Coffee
オブジェクトへのSwiftUIビューそれらからの呼び出しは、await
のどのような利用も必要としません、それらのビューがまたメインアクター上で@Environment
のそれらの使用によってするのと同じく。
Replace Delegates and Completion Handlers with Async Methods 委任と完了ハンドラをasyncメソッドで置き換える
Several methods on the CLKComplication
protocol used to configure the app’s timeline take completion handlers, which you can replace with their async
equivalents:
アプリのもつタイムラインを構成設定するために使われるCLKComplication
プロトコル上のいくつかのメソッドは、完了ハンドラをとります、それはあなたがそれらのasync
相当物と置き換え可能です: