0

我有一个具有 User 对象的 Auth 对象。我存储 Auth 对象是因为它还有其他信息(例如我的访问令牌)。

如果我登录一次,然后退出 - 没有问题。它创建了 auth 对象,然后创建了 user 对象......并且注销会删除 auth 对象(但保留用户对象),这对我来说很好。

但是,当我第二次登录时,它失败了,因为它尝试再次创建用户对象,但主键相同,我收到此错误:

"Can't set primary key property 'id' to existing value '123123123'"

(123123123 是样本 id)

当我将 Auth 对象添加到 Realm 时,它如何更新现有用户(如果存在)而不是尝试创建一个具有相同主键的新用户?

谢谢!

授权对象:

class Auth: Object, Mappable  {
    static var currentAuth: Auth? {
        set {
            let realm = try! Realm()
            try! realm.write {
                if let oldValue = currentAuth {
                    realm.delete(oldValue)
                }
                if let currentAuth = newValue {
                    realm.add(currentAuth)
                }
            }
            NSNotificationCenter.defaultCenter().postNotificationName("didChangeLogin", object: nil)
        }
        get {
            let realm = try! Realm()
            // there should only be 1 or 0
            return realm.objects(Auth).first
        }
    }

    dynamic var accessToken: String?
    dynamic var user: User?

    func mapping(map: Map) {
        accessToken <- map["access_token"]
        user <- map["user"]
    }

    // MARK: - Convenience
    class func logout() {
        currentAuth = nil
    }

    // MARK: - Required
    required init() { super.init() }
    required init?(_ map: Map) { super.init() }
    required init(value: AnyObject, schema: RLMSchema) { super.init(value: value, schema: schema) }
    required init(realm: RLMRealm, schema: RLMObjectSchema) { super.init(realm: realm, schema: schema) }
}

用户对象:

class User: Base {
    dynamic var username: String?
    dynamic var bio: String?

    override func mapping(map: Map) {
        super.mapping(map)
        username <- map["username"]
        bio <- map["bio"]
    }

    // MARK: - Requireds
    required init() { super.init() }
    required init?(_ map: Map) { super.init() }
    required init(value: AnyObject, schema: RLMSchema) { super.init(value: value, schema: schema) }
    required init(realm: RLMRealm, schema: RLMObjectSchema) { super.init(realm: realm, schema: schema) }
}

^ 供参考

4

1 回答 1

1

似乎User的主键是冲突的(也许它是在Base类中定义的?)。

Realm 没有级联删除,因此User即使删除旧对象也会留下Auth对象。

如果您想在具有现有主键的对象时更新,您应该传递true给方法的update参数add(_:, update:)。但是,Auth该类没有主键属性,因此在添加对象时无法传递trueupdate参数。Auth

有两种方法可以解决问题。

1.第一种方法是向Auth类添加主键(也许,accessToken属性是合适的。)。如下所示:

class Auth: Object, Mappable  {
    ...
    override class func primaryKey() -> String? {
        return "accessToken"
    }
    ...
}

然后,您可以传递trueadd(_:, update:).

if let currentAuth = newValue {
    realm.add(currentAuth, update: true)
}

2.

第二种方法是在删除旧User对象时删除旧Auth对象。如下所示:

static var currentAuth: Auth? {
    set {
        let realm = try! Realm()
        try! realm.write {
            if let oldUserValue = currentAuth?.user {
                realm.delete(oldUserValue)
            }
            if let oldValue = currentAuth {
                realm.delete(oldValue)
            }
            if let currentAuth = newValue {
                realm.add(currentAuth)
            }
        }
        ...
于 2016-05-16T05:20:32.080 回答