How to create global variable in Swift?
Asked Answered
G

2

10

I am trying to set a global variable. In my case, just a boolean flag that indicates if a view is being presented for the first time:

var initialLoadFlag: Bool = true

After the view is presented, I want to set this flag to false:

var initialLoadFlag: Bool = false

And then check for it thenceforth:

if initialLoadFlag {
   showWelcomeMessage() 
}

So, I would like to create initialLoadFlag as a global variable. Where and how? I've tried:

  • In the viewDidLoad area of my view controller
  • In the application() method in my AppDelegate.swift file
  • In the AppDelegate class

No luck. I'm getting a Use of unresolved identifier 'initialLoadFlag' error message

(Note: I realize that in this question I betray my ignorance of how scope is handled in Swift. Please forgive me... I'm on a deadline, and still new to the language.)

Thanks for your help.

Gefen answered 21/7, 2014 at 14:49 Comment(2)
does this need to be specific for every view? Also do you need to persist this across multiple application runs?Bub
Only needed for one view: a detail view of a Master-Detail controller. No, it does not need to persist across multiple application runs.Gefen
B
3

You could store a flag in the master controller and set it to true when you perform the segue to the details controller. E.g.

class MasterViewController: UIViewController {

    var firstTimePresenting = true

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "showDetail" {
            if firstTimePresenting {
                println("First time!")
                firstTimePresenting = false
            }
        }
    }
}
Bub answered 21/7, 2014 at 15:5 Comment(2)
This was very helpful. I actually ended up setting the variable as part of the didSet routine in the detail view controller: self.firstload = false. tyvm.Gefen
When you say 'the master controller' do you mean a new swift file called master controller or the app delegate file?Biafra
P
25

You can define a struct with static field:

struct MyViewState {
    static var initialLoadFlag = false
}

Usage:

// set
MyViewState.initialLoadFlag = true

// get
let state = MyViewState.initialLoadFlag
println("My view state:\(state)")

Remarks: Such hacks as singletons and global vars are usually needed in case of bad design. Maybe you can store your state in NSUserDefaults? Or store it in some session object that can be injected in any ViewController that needs to be aware about context.

Predisposition answered 21/7, 2014 at 15:22 Comment(6)
Where shall we put the struct? I got an error of "Use of unresolved identifier 'MyViewState' "Busoni
@Busoni in a new .swift file.Chipman
FWIW, using NSUserDefaults is tantamount to using singleton (in fact, in many ways, worse).Eastbourne
I have a lot of variables that can be user configured, basically skinning, in many VCs. how would atomically update all of them?Infeudation
Ok I'm confused. How does a singleton differ from user defaults? And @Eastbourne why are user defaults worse? Isn't that exactly what the user defaults are for?Systematic
@Systematic - I'm not advocating singletons over user defaults. They're both inappropriate for state variables. My point is merely that user defaults "are referred to as defaults because they’re commonly used to determine an app’s default state at startup or the way it acts by default." To use it for random state variables is contrary to the intent of this store. One can use it to hold whatever you want, but the question is whether one should. But singletons and defaults suffer from similar problems; dependencies obscured and debugging/testing is harder. Dependency injection is more robust.Eastbourne
B
3

You could store a flag in the master controller and set it to true when you perform the segue to the details controller. E.g.

class MasterViewController: UIViewController {

    var firstTimePresenting = true

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "showDetail" {
            if firstTimePresenting {
                println("First time!")
                firstTimePresenting = false
            }
        }
    }
}
Bub answered 21/7, 2014 at 15:5 Comment(2)
This was very helpful. I actually ended up setting the variable as part of the didSet routine in the detail view controller: self.firstload = false. tyvm.Gefen
When you say 'the master controller' do you mean a new swift file called master controller or the app delegate file?Biafra

© 2022 - 2024 — McMap. All rights reserved.