Как поставить в очередь операции CKO для разных баз данных CK - PullRequest
0 голосов
/ 04 августа 2020

Я создаю 2 операции, скажем CKModifySubscriptionsOperation. Один для частной, другой для общей базы данных. Я мог бы поставить их в очередь, добавив их в OperationQueue, каждый следующий запускался бы после предыдущего блока завершения. нужно поставить их в очередь. Вот как я добавляю операцию в базу данных. Как поставить их в единую очередь, но при этом оставить go в нужную базу данных каждому?

container.privateCloudDatabase.add(operation)
container.sharedCloudDatabase.add(operation)

// Put subscriptions to correct databases but no queue

1 Ответ

0 голосов
/ 19 августа 2020

Я решил цель, создав управляемую настраиваемую операцию.

Теперь мы можем поставить в очередь c операций облачной базы данных точно так же

let privateSubscriptionOperation = SubscriptionOperation(type: .private)
let sharedSubscriptionOperation = SubscriptionOperation(type: .shared)

operationQueue.addOperation(privateSubscriptionOperation)
operationQueue.addOperation(privateSubscriptionOperation)

Прежде всего, 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)
    }
    
}
...