151

I have a global variable that needs to be shared among my ViewControllers.

In Objective-C, I can define a static variable, but I can't find a way to define a global variable in Swift.

Do you know of a way to do it?

martinez314
  • 12,162
  • 5
  • 36
  • 63
czzhengkw
  • 1,521
  • 2
  • 10
  • 5
  • one answer over here http://stackoverflow.com/questions/24868120/how-to-create-global-variable-in-swift – Steve Rosenberg Oct 04 '14 at 17:36
  • Possible duplicate of [How to create global variable in Swift?](https://stackoverflow.com/questions/24868120/how-to-create-global-variable-in-swift) – Kode Jan 24 '18 at 03:59
  • you can define variable or struct in outside of the class then you are able to access that variable in overall application. – Chandni May 04 '18 at 10:08

4 Answers4

247

From the official Swift programming guide:

Global variables are variables that are defined outside of any function, method, closure, or type context. Global constants and variables are always computed lazily.

You can define it in any file and can access it in current module anywhere. So you can define it somewhere in the file outside of any scope. There is no need for static and all global variables are computed lazily.

 var yourVariable = "someString"

You can access this from anywhere in the current module.

However you should avoid this as Global variables are not good for application state and mainly reason of bugs.

As shown in this answer, in Swift you can encapsulate them in struct and can access anywhere. You can define static variables or constant in Swift also. Encapsulate in struct

struct MyVariables {
    static var yourVariable = "someString"
}

You can use this variable in any class or anywhere

let string = MyVariables.yourVariable
println("Global variable:\(string)")

//Changing value of it
MyVariables.yourVariable = "anotherString"
Bobbbay
  • 322
  • 6
  • 18
codester
  • 36,891
  • 10
  • 74
  • 72
  • 4
    *Your* struct is called `MyVariables`, so `MyViewState` looks like a copy/paste error from http://stackoverflow.com/a/24868789/1187415 :) – Martin R Oct 04 '14 at 18:48
  • Thanks Martin R. yes i have copied the code from it – codester Oct 04 '14 at 18:49
  • 11
    If you copy code from another answer then you should state that explicitly (with a link to the original answer). Compare http://stackoverflow.com/help/referencing. – Martin R Oct 04 '14 at 18:52
  • 2
    Got it, Thanks! But is there any different between global variable and encapsulate in struct? – czzhengkw Oct 05 '14 at 01:25
  • @郑克文 As such there is no difference but while encapsulating variable in `struct` you can control the visibility of all variables by `struct` and also you can bind them to different logical units by enclosing in different strut if appropriate.Like Audio Constant of application and general constant. – codester Oct 05 '14 at 06:24
  • @codester I don't know if you can judge on that, but isn't it even better to define global variables in the `AppDelegate` and later call them by `(UIApplication.sharedApplication().delegate as AppDelegate).myVariable`? How would that be different (except for the syntax of course) from your solution? Thanks for a reply – borchero Mar 03 '15 at 16:28
  • @OliverBorchert Yes this can be done but whole point here is of best practices. First it is really really bad to use global variable unless you really need it. Second there is difference if you organize your code in meaningful way instead of polluting app delegate. – codester Mar 03 '15 at 17:10
  • 5
    Won't "MyVariables" be considered as global? How does it make a difference if we declare it as global struct or variable? – Satyam Jun 13 '15 at 05:55
  • It looks like a global static variable that is encapsulate in a struct is not viewable in the debug area :( – Regis St-Gelais Jun 25 '15 at 18:53
  • You can inspect a global variable in lldb. Although using such variables may make your code less modular, it does work well in certain conditions, and it's not heresy to use it when it works best for your circumstances. – jbaraga Apr 02 '16 at 04:43
  • Having issues with changing objects defined in this way. For example: `let tcView = someView(); prjConstants.tcView = tcView`. For some reason, when tcView is used elsewhere, it's finding the old reference. – Levi Roberts Apr 21 '16 at 02:08
  • There are no problems if I store an array of objects by this way? – JCarlosR Apr 16 '17 at 20:24
  • And if is empty, we have to declare as "var string:String" – J A S K I E R Jul 17 '18 at 17:10
16

Global variables that are defined outside of any method or closure can be scope restricted by using the private keyword.

import UIKit

// MARK: Local Constants

private let changeSegueId = "MasterToChange"
private let bookSegueId   = "MasterToBook"
Dan Coughlin
  • 1,104
  • 10
  • 14
7

if you want to use it in all of your classes you can use:

public var yourVariable = "something"

if you want to use just in one class you can use :

var yourVariable = "something"
-3

If you don't actually want a global variable, but instead want to save values that persist even when the app closes you can do this:

If you don't actually want to pass data between view controllers but rather simply want to store a global variable you can do this:

This gives a great explanation for how to do this in Swift 5: https://www.hackingwithswift.com/example-code/system/how-to-save-user-settings-using-userdefaults

Summary:

To set a value:

let defaults = UserDefaults.standard
defaults.set("value", forKey: "key")

To get a String value:

let key = defaults.object(forKey: "StringKey") as? [String] ?? [String]()

To get integer value:

let key = defaults.integer(forKey: "IntegerKey")
Jeffrey Kozik
  • 201
  • 4
  • 8
  • Off-topic, this is not what OP is asking about. – Eric Aya Dec 01 '21 at 16:11
  • 2
    Also, a friendly tip: it would be *very wrong* to use UserDefaults to save a value only because you need that value in another view controller. There are proper ways to pass the value without having to write it to local storage. – Eric Aya Dec 01 '21 at 16:13
  • When I was searching about how to save data that persists even when the app is closed and that is accessible from all view controllers, this SO question came up on most search engines I used. So, I figured my answer would be useful to someone else who was in the same situation as me. – Jeffrey Kozik Dec 01 '21 at 16:14
  • @EricAya I agree that it would be wrong to write to local storage if you simply want to pass data between view controllers. However some people looking up how to do this might not actually want to pass data between view controllers, they may want data that is more persistent such as an id for a user logged into their app. That's why I posted this answer. – Jeffrey Kozik Dec 01 '21 at 16:16
  • It may be helpful to people who are trying to solve a similar problem as was the case for me, but I get your point – Jeffrey Kozik Dec 01 '21 at 16:32