iosswiftstaticrealmxcode9.3

iOS swift 4 sets a default boolean to complicated static variables?


Hi I'm working on an app that is connected to a Web API and contains a local Database (Realm). I have a User class which is a Realm Object subclass and keeps the user information such as username, password, accessToken and etc. It has also a static variable and computed property called instance: User? and current: User? Please find details below

class User: Object {

    /// Properties (Database Columns)
    @objc dynamic var username: String = ""
    @objc dynamic var password: String = ""
    @objc dynamic var accessToken: String = ""

    /// Current Logged In User
    static var current: User? {
        if instance == nil {
            let realm = try! Realm()
            instance = realm.objects(self).first
        }

        return instance
    }

    private static var instance: User?
}

As you can see current property returns the first User instance from realm database which is the logged in user information if there is any, otherwise it returns nilwhich means the user hasn't logged in the app.

I have also another class called Configs its name can describe what it does, there's a static boolean variable in it called isLogin. Here is the part of my code which I defined this

static var isLogin: Bool = User.current != nil

as you can see this property refers to User.current property described above and returns the result. I call Configs.isLogin several times in the app whenever I want to check if the user is logged in or not so, I can tell the app to behave properly. But when I call this property, it seems swift dive into the property and calls User.current JUST ONCE in an app session, the next times it just keeps the first result and assign it directly to Configs.isLogin and it will no more check the User.current property and won't runs query to see if there is any result or not, thus when for example the user fills and submits the registration form and gets a token from API and I save the information in Realm, if I call Configs.isLogin it still returns false since the first time in this session that it checked the User.current it was nil, but if I call User.current directly (after the registration) it's not nil anymore and I can access to the logged in user, also if I relaunch the app and start a new app session Configs.isLogin returns true which is correct and shows swift dives into the User.current and checked it and returned the proper result (as I mentioned at first of the article, only the first time it will dive into the class and checks the result).

I debugged my app several times and several parts until I found this problem, How can I make swift to always dive into User.current from Config.isLogin property when I call this config? is there something wrong with my code? and if yes what's the proper way? Thank You


Solution

  • Currently isLogin is a variable initialized at first access. You can move the initialization part into a computed property so it always checks on User.current:

    static var isLogin: Bool { return User.current != nil }
    

    Here you can read up on Computed Properties.