如何在RealmSwift中为对象生成id?

时间:2016-05-14 14:54:55

标签: swift realm

我正在使用RealmSwift。为对象生成id的最佳/规范方法是什么?

以下是我提出的建议:

class MyObject: Object {
    dynamic var id = ""
    dynamic var createdAt = NSDate()

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

    func save() {
        let realm = try! Realm()

        if(self.id == "") {
            while(true) {
                let newId = NSUUID().UUIDString
                let saying = realm.objectForPrimaryKey(MyObject.self, key: newId)
                if(saying == nil) {
                    self.id = newId
                    break
                }
            }
        }

        try! realm.write {
            realm.add(self)
        }
    }
}

我想要一个将对象持久保存到Realm的函数,并根据id覆盖或创建一个新函数。这似乎工作正常,但我不确定是否有内置的东西来做到这一点。或者有更好的方法吗?

感谢。

2 个答案:

答案 0 :(得分:6)

我知道这已经有几个月了,但这就是我实现自动递增主键的方式。

此代码未经测试,但您会得到一般的想法

constructor (props) {
        super(props)

        this._handleNavigate = this._handleNavigate.bind(this)
        this. _renderScene = this. _renderScene.bind(this);
    }

创建唯一字符串ID(IE:UUID)的过程非常相似:

class MyObject: Object {
    /**
    Primary Key

    Since you can't change the primary key after the object is saved,
    we'll use 0 to signify an unsaved object. When we set the primary key,
    we'll never use 0.
    */
    dynamic var id: Int = 0

    /**
    Some persisted value
    */
    dynamic var someString: String?

    var nextID: Int {
        do {
            let realm = try Realm()

            /// I would use .max() but Realm only supports String and signed Int for primary keys
            /// so using overflow protection, the `next` primary key would be Int.min if the
            /// current value is Int.max
            var id = realm.objects(MyObject.self).sorted("id", ascending: true).last?.id ?? 0

            /// add 1 to id until we find one that's not in use... skip 0
            repeat {
                id = Int.addWithOverflow(id, 1).0 /// Add with overflow in case we hit Int.max
            } while id == 0 || realm.objectForPrimaryKey(MyObject.self, key: id) != nil

            return id
        } catch let error as NSError {
            /// Oops
            fatal(error: error.localizedDescription)
        }
    }

    convenience init(someString: String?) {
        self.init()

        id = nextID
        self.someString = someString
        save()
    }

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

    func save() {
        /// Gotta check this in case the object was created without using the convenience init
        if id == 0 { id = nextID }

        do {
            let realm = try Realm()
            try realm.write {
                /// Add... or update if already exists
                realm.add(self, update: true)
            }
        } catch let error as NSError {
            fatalError(error.localizedDescription)
        }
    }
}

答案 1 :(得分:1)

Realm(Swift)目前不支持自动递增主键。您可以像上面一样设置主要,但对于自动递增和唯一键,您可以使用几条路线:

  1. UUID(就像你上面的那样)
  2. 查询max" id"您的对象的(主键)并将要插入的对象设置为id + 1.类似于......

    let id = realm.objects(MyObject).max("id") + 1

  3. 创建自己的哈希签名(一个可能的示例:SHA256(纪元时间戳+ SHA256(object.values))