受WWDC 2015高級NSOPERATIONS會議啟發的Swift框架。以前稱為運營,由@Danthorpe開發,並在我們出色的社區提供了很多幫助下。
| 資源 | 在哪裡找到它 |
|---|---|
| 會話視頻 | developer.apple.com |
| 舊但更完整的參考文檔 | docs.danthorpe.me/operations |
| 更新但尚未完整的參考文檔 | procepure.kit.run/development |
| 編程指南 | operations.readme.io |
ProcedureKit支持所有當前的Apple平台。最低要求是:
ProcedureKit(5.1.0)的當前發布版本支持Swift 4.2+和Xcode 10.1。 development分支是Swift 5和Xcode 10.2兼容。
ProcedureKit是一個“多模塊”框架(不要打擾谷歌搜索,我只是編造了)。我的意思是,Xcode項目具有多個目標/產品,每個目標/產品都會產生快速模塊。這些模塊中的一些是跨平台,其他模塊是專用的,例如ProcedureKitNetwork vs ProcedureKitMobile 。
請參閱《安裝過程指南》。
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中)。
請參閱[[條件|條件]]或條件上的舊編程指南|有關更多信息。
功能代表了應用程序訪問設備或用戶帳戶能力的能力,或者可能是任何類型的門控資源。例如,位置服務,雲套件容器,日曆等或網絡服務。 CapabiltiyProtocol提供了一個統一模型:
GetAuthorizationStatusProcedure檢查當前的授權狀態,AuthorizeCapabilityProcedureAuthorizedFor條件。例如:
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 ( )
}
} ProcedureKit提供以下功能: Capability.CloudKit和Capability.Location 。
在操作(此框架的先前版本)中,存在更多功能(日曆,健康,照片,地址簿等),我們仍在考慮如何在ProcedureKit中提供這些功能。
有關更多信息,請參見[[功能|能力]]或功能的舊編程指南。
Procedure具有通過log屬性暴露的自己的內部記錄功能:
class LogExample : Procedure {
override func execute ( ) {
log . info ( " Hello World! " )
finish ( )
}
}有關記錄和支持第三方日誌框架的更多信息,請參見《編程指南》。
通常,過程需要依賴項才能執行。正如基於異步/事件的應用程序的典型情況一樣,這些依賴性在創建時間可能不知道。取而代之的是,在初始化過程後但在執行該過程之前,必須注入它們。 ProcedureKit通過一組共同工作的協議和類型來支持這一點。我們認為這種模式很棒,因為它鼓勵了小型單一目的程序的組成。這些可以更容易測試,並有可能使更多的重複使用。在整個框架中,您會發現使用和鼓勵的依賴注入。
無論如何,首先,一個值可能已經準備就緒或待處理。例如,當初始化過程時,它可能沒有所有依賴關係,因此它們處於待處理狀態。希望他們在執行時準備就緒。
其次,如果一個過程正在獲取另一個過程要求的依賴關係,則可能會成功,或者可能會失敗。因此,有一個簡單的結果類型可以支持這一點。
第三,有一些協議來定義input和output屬性。
InputProcedure關聯Input類型。 Procedure子類可以符合此範圍以允許依賴注射。請注意,僅支持一個input屬性,因此創建中間結構類型以包含多個依賴性。當然, input屬性是待處理值類型。
OutputProcedure通過其output屬性公開了與Output相關的類型,這是待處理結果類型。
將其整合在一起的是一組API, InputProcedure可以將鏈接依賴在一起。像這樣:
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實例返回速度屬性。
這裡要注意的關鍵是,此閉合可以同步運行。因此,最好不要把任何繁重的東西放在上面。如果您需要進行更複雜的數據映射,請查看TransformProcedure和AsyncTransformProcedure 。
有關更多信息,請參見註射結果的編程指南。