Realm add(_,update:true)删除现有关系

时间:2017-08-09 09:30:49

标签: ios swift realm

我遇到一个问题,我在调用add(_, update: true)函数后无法保持现有的关系。

我编写了一个TaskSync类,负责创建/更新Task对象:

class TaskSync: ISync {

    typealias Model = Task

    func sync(model: Task) {

        let realm = try! Realm()

        let inWrite = realm.isInWriteTransaction

        if !inWrite {
            realm.beginWrite()
        }

        let _task = realm.object(ofType: Task.self, forPrimaryKey: model.id)

        // Persist matches as they are not getting fetched with the task
        if let _task = _task {
            print("matches: \(_task.matches.count)")
            model.matches = _task.matches
        }

        realm.add(model, update: true)

        if _task == nil {
            var user = realm.object(ofType: User.self, forPrimaryKey: model.getUser().id)

            if (user == nil) {
                user = model.getUser()

                realm.add(user!, update: true)
            }

            user!.tasks.append(model)
        }

        if !inWrite {
            try! realm.commitWrite()
        }
    }

    func sync(models: List<Task>) {

        let realm = try! Realm()

        try! realm.write {
            models.forEach { task in
                sync(model: task)
            }
        }
    }
}

当要同步模型时,我会检查它是否已存在于Realm中,如果是,我会获取它并尝试包含matches属性,因为该属性不包含在模型中。

在调用realm.add(model, update: true)之前,模型包含matches的列表,但是在执行realm.add之后,matches列表为空。

以下是两种模式:

class Task: Object, ElementPreloadable, ElementImagePreloadable, ItemSectionable {

    dynamic var id: Int = 0
    dynamic var title: String = ""
    dynamic var desc: String = ""
    dynamic var price: Float = 0.0
    dynamic var calculatedPrice: Float = 0.0
    dynamic var location: String = ""
    dynamic var duration: Int = 0
    dynamic var date: String = ""
    dynamic var category: Category?
    dynamic var currency: Currency?
    dynamic var longitude: Double = 0.0
    dynamic var latitude: Double = 0.0
    dynamic var state: Int = 0
    dynamic var userId: Int = 0

    // Existing images
    var imagesExisting = List<URLImage>()
    // New images
    var imagesNew = List<Image>()
    // Images deleted
    var imagesDeleted = List<URLImage>()

    private let users = LinkingObjects(fromType: User.self, property: "tasks")
    var user: User?

    var matches = List<Match>()

    dynamic var notification: Notification?

    override static func ignoredProperties() -> [String] {
        return ["imagesExisting", "imagesNew", "imagesDeleted", "user", "tmpUser"]
    }

    override static func primaryKey() -> String? {
        return "id"
    }

    func getImageMain() -> URLImage? {
        for image in imagesExisting {
            if image.main {
                return image
            }
        }
        return imagesExisting.first
    }

    func getSection() -> Int {
        return state
    }

    func getSectionFieldName() -> String? {
        return "state"
    }

    func getId() -> Int {
        return id
    }

    func getURL() -> URL? {
        if let image = getImageMain() {
            return image.getResizedURL()
        }
        return nil
    }

    func getState() -> TaskOwnState {
        return TaskOwnState(rawValue: state)!
    }

    func getUser() -> User {
        return (user != nil ? user : users.first)!
    }
}

class Match: Object, ElementPreloadable, ElementImagePreloadable, ItemSectionable {

    dynamic var id: Int = 0
    dynamic var state: Int = -1
    dynamic var priorityOwnRaw: Int = 0
    dynamic var priorityOtherRaw: Int = 0
    dynamic var user: User!

    var messages = List<Message>()

    private let tasks = LinkingObjects(fromType: Task.self, property: "matches")
    var task: Task?

    dynamic var notification: Notification?

    override static func primaryKey() -> String? {
        return "id"
    }

    override static func ignoredProperties() -> [String] {
        return ["task"]
    }

    func getId() -> Int {
        return id
    }

    func getSection() -> Int {
        return 0
    }

    func getURL() -> URL? {
        if let image = user.getImageMain() {
            return image.getResizedURL()
        }
        return nil
    }

    func getPriorityOwn() -> PriorityType {
        if priorityOwnRaw == PriorityType.normal.rawValue {
            return PriorityType.normal
        }
        else {
            return PriorityType.favorite
        }
    }

    func getPriorityOther() -> PriorityType {
        if priorityOtherRaw == PriorityType.normal.rawValue {
            return PriorityType.normal
        }
        else {
            return PriorityType.favorite
        }
    }

    func getSectionFieldName() -> String? {
        return nil
    }

    func getTask() -> Task {
        return (task != nil ? task : tasks.first)!
    }
}

我花了好几个小时试图弄清楚为什么在更新任务时我无法保持匹配关系。每一条建议都将受到高度赞赏!

1 个答案:

答案 0 :(得分:1)

在Realm的GitHub问题跟踪器上也提到了{p> This question。对于后代,这是解决方案。

List properties should always be declared as let properties,因为分配它们没有做任何有用的事情。将所有对象从List复制到另一个model.tasks.append(objectsIn: _user.tasks)的正确方法是DateTime