Запустите CKQueryOperation с результатами предыдущего CKQueryOperation
У меня есть приложение со списком покупок. Я могу хранить цены на продукт и поставщика в своем приложении, модель
Product
Vendor
Price
Один товар может иметь несколько цен от разных поставщиков.
Я храню информацию о ценах со ссылками на продукт и поставщика (CKRecord.Reference).
Теперь я использую следующее, чтобы получить все цены, связанные с продуктом:
public func fetchDataByProduct(product: Product, completionHandler: @escaping (Bool) -> Void){
self.pricesBuffer = []
let cloudContainer = CKContainer.init(identifier: "iCloud.XYZ")
let publicDatabase = cloudContainer.publicCloudDatabase
let reference = CKRecord.Reference(recordID: product.recordID, action: .deleteSelf)
let predicate = NSPredicate(format: "priceToProduct == %@", reference)
let query = CKQuery(recordType: "Price", predicate: predicate)
let operation = CKQueryOperation(query: query)
operation.recordFetchedBlock = { record in
let price = Price()
price.recordID = record.recordID
price.grossPrice = record.object(forKey: "grossPrice") as? Double
let dummy = record.object(forKey: "priceToVendor") as! CKRecord.Reference
price.vendorRecordID = dummy.recordID
self.pricesBuffer.append(price)
}
operation.queryCompletionBlock = { [unowned self] (cursor, error) in
self.pricesBuffer.forEach({price in
price.retrieveVendor()
})
DispatchQueue.main.async {
if error == nil {
self.prices = self.pricesBuffer
completionHandler(true)
} else {
}
}
}
publicDatabase.add(operation)
}
Моя проблема в том, что теперь я не могу получить имя поставщика, которое является частью объекта Vendor (Vendor.name).
Я попытался перебрать priceBuffer и запустить этот по цене, но проблема, похоже, в том, что CloudKit сначала выполняет первоначальный запрос на fetchDataByProduct(), а затем затем извлекает данные поставщика, но уже слишком поздно, потому что обновленные данные не получают нажал на мой просмотр (SwiftUI).
publicDatabase.fetch(withRecordID: self.vendorRecordID, completionHandler: {[unowned self] record, error in
if let record = record {
print(record)
self.vendor.recordID = record.recordID
self.vendor.name = record["name"] as! String
print(self.vendor.name)
}
})
Есть идеи, как это решить? Я считаю, что мне нужно добавить в смесь второй CKQueryOperation и использовать.addDependency(), но я не могу понять, как это должно выглядеть в конце.
1 ответ
Допустим, вы используете операцию для получения цен, как указано выше.
let predicate = NSPredicate(format: "priceToProduct == %@", reference)
let query = CKQuery(recordType: "Price", predicate: predicate)
let pricesOperation = CKQueryOperation(query: query)
pricesOperation.database = publicDatabase // not required if you don't use OperationQueue
Затем вы можете построить операцию для выборки поставщиков, я создам простую операцию для демонстрационных целей.
let vendorQuery = CKQuery(recordType: "Vendor", predicate: predicate)
let vendorsOperation = CKQueryOperation(query: vendorQuery)
vendorsOperation.database = publicDatabase // not required if you don't use OperationQueue
Затем вы можете установить зависимость, сначала получить цены, чем продавцы.
vendorsOperation.addDependency(pricesOperation)
И, наконец, отправьте эти операции в OperationQueue
let operationQueue = OperationQueue()
operationQueue.addOperations([pricesOperation, vendorsOperation], waitUntilFinished: false)
Изменить: если вы не хотите использовать OperationQueue
, просто отправьте эти операции в базу данных, но сначала установите зависимость, прежде чем отправлять операции для выполнения.
vendorsOperation.addDependency(pricesOperation)
publicDatabase.add(pricesOperation)
publicDatabase.add(vendorsOperation)