Search code examples
iosswiftrealm

How can I read the value of a Realm variable in an iOS project?


I have just started coding. I am making an iOS app with Swift that needs to be able to store two variables even when the app is exited. For this, I am using Realm. I am able to write those two variables, but when I try to read them, I cannot build my project.

I have tried many tutorats, but failed each time I tried to apply them to my problem.

Here is my Realm class:

class Info: Object {
    dynamic var name  = ""
    dynamic var gender  = ""
}

How can I read the value of these two variables in my ViewController?

When I try to read the variable, I have an error on the line

guard let info = realm.objects(Info.self).first else {return}

of my ViewController:

import UIKit
import RealmSwift

class SettingsViewController: UIViewController {

    let realm = try! Realm()
    guard let info = realm.objects(Info.self).first else {return}
    let name = info.name
    let gender = info.gender

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

Solution

  • You can access Realm variables like this:

    let realm = try! Realm()
    guard let info = realm.objects(Info.self).first else {return}
    let name = info.name
    let gender = info.gender
    

    However, if you don't plan on storing more complex data on storage, I would suggest you just use UserDefaults, for such a simple task it is easier to use.

    You should also change the « » to proper " signs if you want to store String literals.

    For the edited part of your question: guard let info = realm.objects(Info.self).first else {return} has to happen inside your viewDidLoad function. You cannot access realm, which is an instance property of your class, before your class is actually initialised, hence the error you get. If you need info to be an instance property, initialise it as an optional and access it inside viewDidLoad.

    First option - if you only need access to info inside viewDidLoad:

    class SettingsViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            let realm = try! Realm()
            guard let info = realm.objects(Info.self).first else {return}
            let name = info.name
            let gender = info.gender
        }
    
    }
    

    Second option - if you need to access info everywhere in your class instance:

    class SettingsViewController: UIViewController {
    
        let realm = try! Realm()
        var info: Info?    
    
        override func viewDidLoad() {
            super.viewDidLoad()
            info = realm.objects(Info.self).first else {return}
            let name = info.name
            let gender = info.gender
        }
    
    }
    

    If this is your initial view controller, declaring realm as an instance property might prove to be problematic, since your class might be instantiated before your application(didFinishLaunchingWithOptions) function finished execution and hence your realm schema won't be set up properly by the time you try to access it in SettingsViewController. If this is the case, just move the line let realm = try! Realm() inside viewDidLoad.