PSOperations
PSOperations 是一个框架,利用了 NSOperation 和 NSOperationQueue 的强大功能。它使您能够轻松地在项目的各个部分中使用操作。
这是基于 WWDC 2015 上 高级 NSOperations 会话中提供的示例代码。
支持
- Swift 5.x
- iOS 8.0
- tvOS 9.0
- watchOS (未定义部署目标)
- macOS 10.11
- 扩展友好
- 测试仅在 iOS 9(最新版)和 tvOS 9(最新版)上运行
Swift 3+
由于 Swift 3 从几个 Foundation 类型中删除了 NS
前缀,我们添加了一些类型别名以方便使用。我们也探讨了重命名少数冲突的类,但遇到了 radar://28917706,其中框架如果没有包含给出的类型,将回退到 Foundation 类型,例如 UIKit.Data
是有效的,实际上是 Foundation.Data
。如果我们把 Operation
重命名为 PSOperation
,那么使用 PSOperations.Operation
的用例将最终使用 Foundation.Operation
,并可能导致您的代码崩溃。
以下是这些类型别名
public typealias PSOperation = Operation
public typealias PSOperationQueue = OperationQueue
public typealias PSOperationQueueDelegate = OperationQueueDelegate
public typealias PSBlockOperation = BlockOperation
安装
PSOperations支持多种方法在项目中安装库。
Swift包管理器
自Swift 3.0起,Swift包管理器 (SPM) 是Swift自带的依赖管理工具。Xcode 11原生支持SPM,允许在Xcode内部添加应用依赖。
PSOperations可以通过Xcode 11及以上版本或者通过在包管理文件中加入以下依赖项来添加:
.package(url: "https://github.com/pluralsight/PSOperations.git", from: "5.0.2"),
CocoaPods
CocoaPods 是Objective-C的依赖管理器,可以自动化并简化将如PSOperations这样的第三方库集成到项目中的过程。
您可以使用以下命令来安装:
$ gem install cocoapods
要使用CocoaPods将PSOperations集成到Xcode项目中,请在您的Podfile中指定它。
如果您想要包含所有子子规范(健康和Passbook功能)
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
target 'TargetName' do
pod 'PSOperations', '~> 4.0'
end
请运行以下命令
$ pod install
其他配置
基本功能,不包括功能
pod 'PSOperations/Core', '~> 4.0'
基本功能,仅包括Passbook功能
pod 'PSOperations/Passbook', '~> 4.0'
基本功能,仅包括健康功能
pod 'PSOperations/Health', '~> 4.0'
基本功能,仅包括日历功能
pod 'PSOperations/Calendar', '~> 4.0'
基本功能,仅包括位置功能和操作
pod 'PSOperations/Location', '~> 4.0'
Carthage
Carthage 是一个分布式的依赖管理器,它会为您构建依赖并提供二进制框架。
您可以使用以下命令通过 Homebrew 安装Carthage:
$ brew update
$ brew install carthage
要使用Carthage将PSOperations集成到Xcode项目中,请在您的Cartfile中指定它。
github "pluralsight/PSOperations"
运行 carthage
构建框架,并将构建好的 PSOperations.framework
拖入您的Xcode项目。可选地,您可以添加 PSOperationsHealth.framework
、PSOperationsPassbook.framework
、PSOperationsCalendar.framework
和 PSOperationsLocation.framework
。
入门
不要忘记导入!
import PSOperations
如果您正在使用HealthCapability、PassbookCapability、CalendarCapability、LocationCapability或LocationOperation,您需要分别导入它们
import PSOperationsHealth
import PSOperationsPassbook
import PSOperationsCalendar
import PSOperationsLocation
这些功能需要在一个单独的框架中,否则可能会导致App Store审核拒绝导入HealthKit
、PassKit
、EventKit
或CoreLocation
,但实际上并没有使用它们。
创建队列
OperationQueue是核心,它是NSOperationQueue的一个子类
let operationQueue = OperationQueue()
创建一个操作
Operation
是一个NSOperation的子类。与NSOperation
相似,它本身并没有做什么。但PSOperations提供了一些有用的子类,例如
BlockOperation
GroupOperation
URLSessionTaskOperation
LocationOperation
DelayOperation
以下是一个快速示例
let blockOperation = BlockOperation {
print("perform operation")
}
operationQueue.addOperation(blockOperation)
观察一个操作
可以通过OperationObserver
协议来观察Operation
实例的开始、取消、完成和产生新的操作。
PSOperations提供了一些实现了该协议的类型
BlockObserver
TimeoutObserver
以下是一个快速示例
let blockOperation = BlockOperation {
print("perform operation")
}
let finishObserver = BlockObserver { operation, error in
print("operation finished! \(error)")
}
blockOperation.addObserver(finishObserver)
operationQueue.addOperation(blockOperation)
对操作设置条件
可以通过OperationCondition
协议为Operation
实例设置执行所需的条件。
PSOperations提供了一些实现了该协议的类型
SilentCondition
NegatedCondition
NoCancelledDependencies
MutuallyExclusive
ReachabilityCondition
Capability
以下是一个快速示例
let blockOperation = BlockOperation {
print("perform operation")
}
let dependentOperation = BlockOperation {
print("working away")
}
dependentOperation.addCondition(NoCancelledDependencies())
dependentOperation.addDependency(blockOperation)
operationQueue.addOperation(blockOperation)
operationQueue.addOperation(dependentOperation)
如果blockOperation
被取消,则dependentOperation
将不会执行。
在操作上设置权限
CapabilityType
由 Capability
条件使用,允许您轻松查看授权状态并请求在苹果生态系统内某些功能的授权。例如,日历、照片、iCloud、位置和推送通知。
以下是一个快速示例
let blockOperation = BlockOperation {
print("perform operation")
}
let calendarCapability = Capability(Photos())
blockOperation.addCondition(calendarCapability)
operationQueue.addOperation(blockOperation)
此操作需要访问“照片”,如果需要则会请求访问。
自定义流程
上面的示例提供了简单的作业,但 PSOperations 可以参与您应用的许多部分。这是一个利用 PSOperations 力量的自定义 UIStoryboardSegue
。转换直到完成操作才会保留。这是一个通用的 OperationSegue
,可以运行任何给定的操作。这可以用于确保用户在继续转换之前进行身份验证的身份验证操作。如果需要,身份验证操作甚至可以显示身份验证界面。
class OperationSegue: UIStoryboardSegue {
var operation: Operation?
var segueCompletion: ((success: Bool) -> Void)?
override func perform() {
if let operation = operation {
let opQ = OperationQueue()
var retainedSelf: OperationSegue? = self
let completionObserver = BlockObserver {
op, errors in
dispatch_async_on_main {
defer {
retainedSelf = nil
}
let success = errors.count == 0 && !op.cancelled
if let completion = retainedSelf?.segueCompletion {
completion(success: success)
}
if success {
retainedSelf?.finish()
}
}
}
operation.addObserver(completionObserver)
opQ.addOperation(operation)
} else {
finish()
}
}
func finish() {
super.perform()
}
}
贡献
请尽管提交拉取请求,因为我们始终在寻找社区改进。
WWDC 差异
与 WWDC 示例代码的第一个版本的不同之处
- 取消操作不起作用。
- 取消函数稍微友好一些。
- 否定条件不会否定。
- 单元测试!
与 WWDC 示例代码的第二个版本的不同之处
- 在 iOS 8.4 中,有时取消不会正确工作。在取消期间不会调用完成 override。我们修复了这将在 iOS 8.4 和 iOS 9.0 中正常工作。
- 取消函数稍微友好一些。
- 单元测试!
一个值得注意的 WWDC 示例代码的差异
- 当评估条件并失败时,相关操作将取消。操作仍然会按照相同的流程进行,但这一次将被标记为已取消。