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.

kmiklas
  • 13,085
  • 22
  • 67
  • 103
  • does this need to be specific for every view? Also do you need to persist this across multiple application runs? – Gabriele Petronella Jul 21 '14 at 14:55
  • Only needed for one view: a detail view of a Master-Detail controller. No, it does not need to persist across multiple application runs. – kmiklas Jul 21 '14 at 14:58

2 Answers2

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.

koen
  • 5,383
  • 7
  • 50
  • 89
Keenle
  • 12,010
  • 3
  • 37
  • 46
  • 1
    Where shall we put the struct? I got an error of "Use of unresolved identifier 'MyViewState' " – tong Nov 14 '14 at 16:09
  • @tong in a new .swift file. – Reza_Rg Dec 29 '14 at 12:21
  • 1
    FWIW, using `NSUserDefaults` is tantamount to using singleton (in fact, in many ways, worse). – Rob Jan 10 '15 at 19:42
  • I have a lot of variables that can be user configured, basically skinning, in many VCs. how would atomically update all of them? – μολὼν.λαβέ Dec 23 '15 at 06:59
  • Ok I'm confused. How does a singleton differ from user defaults? And @Rob why are user defaults worse? Isn't that exactly what the user defaults are for? – Jeff Jan 22 '18 at 16:34
  • @Jeff - 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. – Rob Jan 22 '18 at 18:08
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
            }
        }
    }
}
Gabriele Petronella
  • 106,943
  • 21
  • 217
  • 235
  • 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. – kmiklas Jul 21 '14 at 15:47
  • When you say 'the master controller' do you mean a new swift file called master controller or the app delegate file? – Darrow Hartman Sep 02 '19 at 20:12