如何为不同的 CKDatabase 排队 CKOperations
How to queue CKOperations for different CKDatabase
我创建了 2 个操作,比如说 CKModifySubscriptionsOperation。一个用于私有,另一个用于共享数据库。我可以通过添加到 OperationQueue 来对它们进行排队,每个下一个都将在上一个完成块之后开始。
let operationQueue = OperationQueue()
operationQueue.maxConcurrentOperationCount = 1
// ...
operationQueue.addOperation(operation)
// Queued great but all subscriptions are created in private database
但我需要从不同的数据库中执行一些操作(获取、修改等),但仍需要将它们排队。这是我向数据库添加操作的方法。如何将它们放入单个队列,但仍然让它们分别进入所需的数据库?
container.privateCloudDatabase.add(operation)
container.sharedCloudDatabase.add(operation)
// Put subscriptions to correct databases but no queue
我已经通过创建受控自定义操作解决了目标。
现在我们可以像那样对云数据库特定操作进行排队
let privateSubscriptionOperation = SubscriptionOperation(type: .private)
let sharedSubscriptionOperation = SubscriptionOperation(type: .shared)
operationQueue.addOperation(privateSubscriptionOperation)
operationQueue.addOperation(sharedSubscriptionOperation)
首先,家长class
class CKDatabaseControlledOperation: Operation {
let databaseType: DatabaseType
let database: CKDatabase
private var _finished = false
private var _executing = false
init(type: DatabaseType) {
databaseType = type
switch type {
case .private:
database = CKContainer.default().privateCloudDatabase
case .shared:
database = CKContainer.default().sharedCloudDatabase
}
}
override var isExecuting: Bool {
get {
return !_executing
}
set {
willChangeValue(forKey: "isExecuting") // This must match the overriden variable
_executing = newValue
didChangeValue(forKey: "isExecuting") // This must match the overriden variable
}
}
override var isFinished: Bool {
get {
return _finished
}
set {
willChangeValue(forKey: "isFinished") // This must match the overriden variable
_finished = newValue
didChangeValue(forKey: "isFinished") // This must match the overriden variable
}
}
func stopOperation() {
isFinished = true
isExecuting = false
}
func startOperation() {
isFinished = false
isExecuting = true
}
enum DatabaseType: String {
case `private` = "private-changes"
case shared = "shared-changes"
}
}
然后我们可以创建任何数据库操作(在此示例中为订阅,但可以使用任何)
class SubscriptionOperation: CKDatabaseControlledOperation {
override func main() {
startOperation() //Operation starts
let subscription = CKDatabaseSubscription(subscriptionID: databaseType.rawValue)
//...set any needed stuff like NotificationInfo
let operation = CKModifySubscriptionsOperation(subscriptionsToSave: [subscription], subscriptionIDsToDelete: [])
operation.modifySubscriptionsCompletionBlock = { [unowned self] subscriptions, subscriptionIDs, error in
//Handle errors
self.stopOperation() //Operation ends
}
database.add(operation)
}
}
我创建了 2 个操作,比如说 CKModifySubscriptionsOperation。一个用于私有,另一个用于共享数据库。我可以通过添加到 OperationQueue 来对它们进行排队,每个下一个都将在上一个完成块之后开始。
let operationQueue = OperationQueue()
operationQueue.maxConcurrentOperationCount = 1
// ...
operationQueue.addOperation(operation)
// Queued great but all subscriptions are created in private database
但我需要从不同的数据库中执行一些操作(获取、修改等),但仍需要将它们排队。这是我向数据库添加操作的方法。如何将它们放入单个队列,但仍然让它们分别进入所需的数据库?
container.privateCloudDatabase.add(operation)
container.sharedCloudDatabase.add(operation)
// Put subscriptions to correct databases but no queue
我已经通过创建受控自定义操作解决了目标。
现在我们可以像那样对云数据库特定操作进行排队
let privateSubscriptionOperation = SubscriptionOperation(type: .private)
let sharedSubscriptionOperation = SubscriptionOperation(type: .shared)
operationQueue.addOperation(privateSubscriptionOperation)
operationQueue.addOperation(sharedSubscriptionOperation)
首先,家长class
class CKDatabaseControlledOperation: Operation {
let databaseType: DatabaseType
let database: CKDatabase
private var _finished = false
private var _executing = false
init(type: DatabaseType) {
databaseType = type
switch type {
case .private:
database = CKContainer.default().privateCloudDatabase
case .shared:
database = CKContainer.default().sharedCloudDatabase
}
}
override var isExecuting: Bool {
get {
return !_executing
}
set {
willChangeValue(forKey: "isExecuting") // This must match the overriden variable
_executing = newValue
didChangeValue(forKey: "isExecuting") // This must match the overriden variable
}
}
override var isFinished: Bool {
get {
return _finished
}
set {
willChangeValue(forKey: "isFinished") // This must match the overriden variable
_finished = newValue
didChangeValue(forKey: "isFinished") // This must match the overriden variable
}
}
func stopOperation() {
isFinished = true
isExecuting = false
}
func startOperation() {
isFinished = false
isExecuting = true
}
enum DatabaseType: String {
case `private` = "private-changes"
case shared = "shared-changes"
}
}
然后我们可以创建任何数据库操作(在此示例中为订阅,但可以使用任何)
class SubscriptionOperation: CKDatabaseControlledOperation {
override func main() {
startOperation() //Operation starts
let subscription = CKDatabaseSubscription(subscriptionID: databaseType.rawValue)
//...set any needed stuff like NotificationInfo
let operation = CKModifySubscriptionsOperation(subscriptionsToSave: [subscription], subscriptionIDsToDelete: [])
operation.modifySubscriptionsCompletionBlock = { [unowned self] subscriptions, subscriptionIDs, error in
//Handle errors
self.stopOperation() //Operation ends
}
database.add(operation)
}
}