WWDC 2015 Advanced Nsoperationsセッションに触発された迅速なフレームワーク。以前はオペレーションとして知られていましたが、@danthorpeによって開発され、素晴らしいコミュニティから多くの助けがありました。
| リソース | それを見つける場所 |
|---|---|
| セッションビデオ | developer.apple.com |
| 古いが、より完全な参照ドキュメント | docs.danthorpe.me/operations |
| 更新されたがまだ完全ではないリファレンスドキュメント | procedure.kit.run/development |
| プログラミングガイド | Operations.readme.io |
ProcretureKitは、現在のすべてのAppleプラットフォームをサポートしています。最小要件は次のとおりです。
PrestureKit(5.1.0)の現在のリリースバージョンは、Swift 4.2+およびXcode 10.1をサポートしています。 developmentブランチはSwift 5とXcode 10.2互換です。
proctionurekitは「マルチモジュール」フレームワークです(グーグルでグーグルではないでください。つまり、Xcodeプロジェクトには複数のターゲット/製品があり、それぞれにSwiftモジュールが生成されているということです。これらProcedureKitMobileモジュールの一部はクロスプラットフォームでありProcedureKitNetworkその他は専用です。
インストール手順ガイドを参照してください。
ProcedureはFoundation.Operationサブクラスです。これは、サブクラス化する必要がある抽象クラスです。
import ProcedureKit
class MyFirstProcedure : Procedure {
override func execute ( ) {
print ( " Hello World " )
finish ( )
}
}
let queue = ProcedureQueue ( )
let myProcedure = MyFirstProcedure ( )
queue . add ( procedure : myProcedure )ここでの重要なポイントは次のとおりです。
Procedureexecuteオーバーライドしますが、 super.execute()を呼び出しないでくださいfinish()を呼び出します。これは非同期に行うことができます。ProcedureQueueのインスタンスに手順を追加します。 オブザーバーは、 Procedureサブクラスに接続されています。ライフサイクルイベントが発生したときにコールバックを受け取ります。ライフサイクルイベントは次のとおりです。添付、実行、実行、実行、キャンセル、新しい操作を追加し、新しい操作を追加し、終了し、終了しました。
これらのメソッドはプロトコルによって定義されるため、複数のイベントに適合するようにカスタムクラスを書き込むことができます。ただし、オブザーバーをより自然に追加するためのブロックベースの方法が存在します。たとえば、手順が終了したときに観察するには:
myProcedure . addDidFinishBlockObserver { procedure , errors in
procedure . log . info ( message : " Yay! Finished! " )
}このフレームワークは、 BackgroundObserver 、 TimeoutObserver 、 NetworkObserverも提供します。
詳細については、[[オブザーバー|オブザーバー]]のwikiを参照してください。
条件はProcedureサブクラスに添付されています。手順を実行する前に、そのすべての条件を非同期に評価します。条件が失敗した場合、実行する代わりにエラーで終了します。例えば:
myProcedure . add ( condition : BlockCondition {
// procedure will execute if true
// procedure will be ignored if false
// procedure will fail if error is thrown
return trueOrFalse // or throw AnError()
}条件は相互に排他的です。これは、同じ除外が実行されている他の操作を妨げるロックが保持されていることに似ています。
このフレームワークは、次の条件を提供します: AuthorizedFor 、 BlockCondition 、 MutuallyExclusive拡張、 NegatedCondition 、 NoFailedDependenciesCondition 、 SilentCondition 、 UserConfirmationCondition ( procedurekitmobile )。
[[条件|条件]]のwikiまたは条件に関する古いプログラミングガイドを参照してください|詳細については。
機能は、デバイスまたはユーザーアカウントの能力、または潜在的にあらゆる種類のゲートリソースにアクセスするアプリケーションの機能を表します。たとえば、ロケーションサービス、クラウドキットコンテナ、カレンダーなど、またはWebサービス。 CapabiltiyProtocol 、次のような統一モデルを提供します。
GetAuthorizationStatusProcedureを使用して、現在の承認ステータスを確認します。AuthorizeCapabilityProcedureを使用して、アクセスを明示的にリクエストしますAuthorizedFor呼ばれる条件として。例えば:
import ProcedureKit
import ProcedureKitLocation
class DoSomethingWithLocation : Procedure {
override init ( ) {
super . init ( )
name = " Location Operation "
add ( condition : AuthorizedFor ( Capability . Location ( . whenInUse ) ) )
}
override func execute ( ) {
// do something with Location Services here
finish ( )
}
} proctionureKitは、次の機能を提供します: Capability.CloudKitとCapability.Location 。
操作(このフレームワークの以前のバージョン)では、より多くの機能が存在し(カレンダー、健康、写真、アドレス帳など)、これらをPrestionureKitで提供する方法を検討しています。
詳細については、[[機能] |機能]の[[機能|機能]]または古いプログラミングガイドを参照してください。
Procedure 、 logプロパティを介して公開されている独自の内部ロギング機能があります。
class LogExample : Procedure {
override func execute ( ) {
log . info ( " Hello World! " )
finish ( )
}
}ログの詳細については、サードパーティのログフレームワークのサポートについては、プログラミングガイドを参照してください。
多くの場合、手順は実行するために依存関係が必要になります。非同期/イベントベースのアプリケーションで典型的なように、これらの依存関係は作成時にはわからないかもしれません。代わりに、手順が初期化された後、それが実行される前に注入する必要があります。 ProcedureKitは、これを共同で動作させる一連のプロトコルとタイプを介してサポートします。このパターンは、小さな単一目的の手順の構成を促進するため、素晴らしいと思います。これらはテストが簡単で、より大きな再利用を可能にする可能性があります。このフレームワーク全体で使用され、奨励されている依存関係の注入が見つかります。
とにかく、まず、値が準備ができているか保留中です。たとえば、手順が初期化されている場合、すべての依存関係がない場合があるため、保留中の状態にあります。うまくいけば、彼らがそれが実行されるまでに準備ができていることを願っています。
第二に、別の手順で必要な依存関係を手順を取得している場合、成功するか、エラーが発生しても失敗する可能性があります。したがって、これをサポートする単純な結果タイプがあります。
第三に、 inputプロパティとoutputプロパティを定義するプロトコルがあります。
InputProcedure 、 Inputタイプを関連付けます。 Procedureサブクラスは、これに適合して、依存性噴射を可能にします。したがって、1つのinputプロパティのみがサポートされていることに注意してください。したがって、複数の依存関係を含む中間構造タイプを作成することに注意してください。もちろん、 inputプロパティは保留中の値タイプです。
OutputProcedure 、 outputプロパティを介してOutput関連タイプを公開します。これは保留中の結果タイプです。
それをすべてまとめることは、依存関係を一緒にチェーンすることを可能にするInputProcedure上のAPIのセットです。このような:
import ProcedureKitLocation
// This class is part of the framework, it
// conforms to OutputProcedure
let getLocation = UserLocationProcedure ( )
// Lets assume we've written this, it
// conforms to InputProcedure
let processLocation = ProcessUserLocation ( )
// This line sets up dependency & injection
// it automatically handles errors and cancellation
processLocation . injectResult ( from : getLocation )
// Still need to add both procedures to the queue
queue . add ( procedures : getLocation , processLocation )上記では、 Input型がOutputタイプ、この場合はCLLocation一致すると想定されています。ただし、クロージャーを使用して、出力タイプを必要な入力タイプにマッサージすることもできます。たとえば、:
import ProcedureKitLocation
// This class is part of the framework, it
// conforms to OutputProcedure
let getLocation = UserLocationProcedure ( )
// Lets assume we've written this, it
// conforms to InputProcedure, and
// requires a CLLocationSpeed value
let processSpeed = ProcessUserSpeed ( )
// This line sets up dependency & injection
// it automatically handles errors and cancellation
// and the closure extracts the speed value
processLocation . injectResult ( from : getLocation ) { $0 . speed }
// Still need to add both procedures to the queue
queue . add ( procedures : getLocation , processLocation )さて、何が起こったのですか? injectResult APIには、後続の閉鎖を受け入れるバリアントがあります。閉鎖は出力値を受信し、入力値を返す必要があります(またはエラーを投げる)。したがって、 { $0.speed }ユーザーのCLLocationインスタンスからSpeedプロパティを返します。
ここで注意すべき重要なことは、この閉鎖が同期して実行されることです。ですから、何も面白くないものを入れないことが最善です。より複雑なデータマッピングを実行する必要がある場合は、 TransformProcedureとAsyncTransformProcedureをチェックしてください。
詳細については、結果を注入するプログラミングガイドを参照してください。