PSOperations 5.0.5

PSOperations 5.0.5

测试已测试
Lang语言 SwiftSwift
许可证 Apache-2.0
发布最后发布2021年1月
SPM支持 SPM

Mark SchultziOS 开发团队维护。



  • Matt McMurry 和 Mark Schultz

PSOperations

codebeat badge Build Status

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.frameworkPSOperationsPassbook.frameworkPSOperationsCalendar.frameworkPSOperationsLocation.framework

入门

不要忘记导入!

import PSOperations

如果您正在使用HealthCapability、PassbookCapability、CalendarCapability、LocationCapability或LocationOperation,您需要分别导入它们

import PSOperationsHealth
import PSOperationsPassbook
import PSOperationsCalendar
import PSOperationsLocation

这些功能需要在一个单独的框架中,否则可能会导致App Store审核拒绝导入HealthKitPassKitEventKitCoreLocation,但实际上并没有使用它们。

创建队列

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将不会执行。

在操作上设置权限

CapabilityTypeCapability 条件使用,允许您轻松查看授权状态并请求在苹果生态系统内某些功能的授权。例如,日历、照片、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 示例代码的差异

  • 当评估条件并失败时,相关操作将取消。操作仍然会按照相同的流程进行,但这一次将被标记为已取消。