如何通过修改后的内容重新加载CloudKit单元

时间:2018-10-05 16:02:19

标签: swift swift4 cloudkit

我正在使用CloudKit作为数据库创建一个简单的待办事项列表应用程序。目前,我可以添加和删除对象,但是对于编辑对象很不满意。

EditItemController

protocol EditItemControllerDelegate {
func editItemController(_ controller: EditItemController, didFinishEditing item: ItemCK)
}

class EditItemController: UIViewController {

var delegate: EditItemControllerDelegate?
var itemToEdit: ItemCK?

let itemTextField: UITextField = {
    let textField = UITextField()
    textField.placeholder = "Hello"
    return textField
}()

@objc func handleSave() {

        if let item = itemToEdit {
            guard let itemName = self.itemTextField.text else { return }
            item.name = itemName
            delegate?.editItemController(self, didFinishEditing: item)
        }
    }

ItemController

class ItemController: UITableViewController, UITextFieldDelegate, EditItemControllerDelegate {

func editItemController(_ controller: EditItemController, didFinishEditing item: ItemCK) {

    if let index = itemsModel.items.index(of: item) {
        let indexPath = IndexPath(row: index, section: 0)
        if let cell = tableView.cellForRow(at: indexPath) as? ItemCell {
            cell.itemLabel.text = item.name
            print(item.name)
        }
    }
}

因此,当我编辑对象时,表视图单元格将重新加载新的对象数据。但是当我向后滑动时,它又回到了原始对象。它似乎没有存储到数据库中。我该如何编辑对象,存储对象,然后将其显示在表格视图单元格中?

What app currently look like

CloudKit代码

class ItemCK: NSObject {
static let recordType = "Item"
static let keys = (name: "title")

var record: CKRecord
init(record: CKRecord) {
    self.record = record
}

override init() {
    record = CKRecord(recordType: ItemCK.recordType)
}

var name: String {
    get {
        return record.value(forKey: ItemCK.keys.name) as! String
    }
    set {
        record.setValue(newValue, forKey: ItemCK.keys.name)
    }
  }
}


class ItemModel {
private let database = CKContainer.default().privateCloudDatabase

var items = [ItemCK]() {
    didSet {
        self.notificationQueue.addOperation {
            self.onChange?()
        }
    }
}

var onChange: (() -> Void)?
var onError : ((Error) -> Void)?
var notificationQueue = OperationQueue.main

var records = [CKRecord]()
var insertedObjects = [ItemCK]()
var editedObjects = ItemCK()
//to keep track of deleted objects
var deletedCKObjectIds = Set<CKRecord.ID>()

init() {
}

func addCategory(name: String) {
    print("Adding item")
    let item = ItemCK()
    item.name = name
    database.save(item.record) { (_, error) in
        guard error == nil else {
            self.handle(error: error!)
            return
        }
    }

    insertedObjects.append(item)
    updateItem()
}

func editItem() {
    let privateDatabase = database
    var predicate= NSPredicate   
}

func delete(at index: Int) {
    print("Deleting item")
    let recordId = self.items[index].record.recordID
    database.delete(withRecordID: recordId) { (_, error) in
        guard error == nil else {
            self.handle(error: error!)
            return
        }
    }

    deletedCKObjectIds.insert(recordId)
    updateItem()
}

@objc func refresh() {
    print("refreshing")
    let query = CKQuery(recordType: ItemCK.recordType, predicate: NSPredicate(value: true))
    database.perform(query, inZoneWith: nil) { (records, error) in
        guard let records = records, error == nil else {
            self.handle(error: error!)
            return
        }
        self.records = records
        self.updateItem()
    }
}

private func updateItem() {

    print("Updating item")
    var knownIds = Set(records.map {$0.recordID})

    self.insertedObjects.removeAll { (item) -> Bool in
        knownIds.contains(item.record.recordID)
    }

    knownIds.formUnion(insertedObjects.map {$0.record.recordID})

    self.deletedCKObjectIds.formIntersection(knownIds)
    var items = records.map { (record) in ItemCK(record: record) }

    items.append(contentsOf: insertedObjects)
    items.removeAll { (items) -> Bool in
        deletedCKObjectIds.contains(items.record.recordID)
    }

    self.items = items

}
}

很抱歉,源代码较长。 CloudKit如此令人困惑,IDK共享或不共享哪些重要信息

1 个答案:

答案 0 :(得分:0)

database.save在updateItem()函数中。

使用新的RecordID保存记录时,它将插入记录。

保存具有与现有记录匹配的RecordID的记录时,它将覆盖该记录(取决于您的冲突解决方案设置)。