Swift 3: Property observer for singleton

邮差的信 提交于 2019-12-04 12:52:58

It's not possible to have a blanket observer for a single Realm Object at the moment, however there's an issue tracking it in the Realm GitHub and I believe it's being prioritized at the moment.

Alcivanio is correct in that you'll need to manually trigger an update event to ensure the changes are persisted to Realm. That being said, because Realm controls the accessors in persisted objects, didSet isn't guaranteed to be called once an object has been saved to Realm. For simplicity reasons, I'd recommend using a closure to update the user object.

Updated Answer: If your singleton is a Realm Object, you can't modify its properties outside of a write transaction. Like I wrote below, the easiest thing to do would be to be to have an update closure that managed the Realm write transaction, and you simply update the properties of your Singleton object inside it.

As you've also seen, you can't use didSet with a property defined with let, so it might be best to drop back to Objective-C conventions and use an internal instance variable.

So all up, maybe consider doing this:

fileprivate var _current: User? = nil

class User: Object {
    dynamic var name:String = ""
    dynamic var email:String = ""
    dynamic var id:String = ""
    dynamic var picURL:String = ""
    dynamic var pic:Data = Data()

    static var current: User
    {
        if _current == nil {
            let realm = try! Realm()

            // Query for an existing user
            _current = realm.objects(User.self).first

            // Create a new user if it didn't exist in Realm
            if _current == nil {
                 _current = User()
                 try! realm.write { realm.add(_current) }
            }
        }
        return _current
    }

    public func update(_ block: (() -> Void)) {
        let realm = try! Realm()
        try! realm.write(block)
    }
}

let user = User.current
user.update {
    user.name = "DCDC"
}

Well, if you just have one user, you should put this observer in each variable, instead of in the let user. And there you can call a method for user update.

dynamic var name: String {
    didSet{
        User.updateOnRealm()//create this method
    }
}

To write the update method, you'll have to write something like this

class func updateOnRealm() {
    //update code here
}
Mladen Bekavac

Based on what you wrote :

What I want to achieve is I want to have only one user object in my app, and anytime any of its properties gets modified, I would like to save it to Realm.

I would suggest this solution:

  1. Create a class User which does not use the Singleton pattern.

  2. Create a class UserManager which does conform to the Singleton pattern

  3. Create custom setter methods for A User. In these setters you can then change the users properties WITH or WITHOUT writing to the database. You can also check the use INPUT (set the name to lowercase etc.).

With this approach you can easily test your User class, extend it, subclass and reuse.

If you need code snippets comment below =).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!