Menu & Search

Sharing data between view controllers and other objects in Swift

May 3, 2015
Candy Code - 2

Every iOS developer encounters a situation where some data has to be shared between view controllers, views or other objects. There are a few ways of doing this – some a bit more ugly, some a bit more elegant. However, it’s always best to keep things simple and not to optimise prematurely.

The simplest and fastest way of sharing stuff in your app is by utilising a pattern called Singleton. It might sound scary and some people don’t like to use it, but it gets the job done. If it’s not overly used/abused, you don’t have to feel guilty about using it!


Firstly, we obviously need a singleton class that will hold some values. I named mine SharingManager.

We’re using a static class constant called sharedInstance. That’s a somehow convenient way to name singleton constants. This approach also supports lazy initialisation and is thread safe.

The class has a variable named welcomeMessage that we’ll use to display … a welcome message!

Next, we’ll add a label to our view controller in our storyboard and .swift file. We’ll set it up so it displays the welcomeMessage  variable from our singleton. The label will also be updated before each view display.

End result:

Screenshot

Notice that I’ve also added a button “Change the Message!” that will be linked to the second view controller that’ll help demonstrate data sharing is actually working! We create another view controller named EditingViewController  with a text field and button that will take care of updating the singleton.

I’ve named the method that’s doing all the work updateMessageAndDismiss  and it looks like this:

It basically updates the singleton and dismisses the editing view controller so we can see the updated message. It’s called when the user taps return on the keyboard or presses the update button:

This is how the second view controller looks like (with the text field pre-filled):

Editing View Controller

Now, whenever a user updates the welcome message, it’s gonna get stored in the SharingManager's  sharedInstance  variable and available to use anywhere.

That’s it, you can add more (and different types of) variables to the singleton class and use it anywhere you want! Magic!

App in action (video)

To see the full working project and how view controllers are wired up, click here (GitHub .zip).

STOP LOSING TIME WITH AUTO LAYOUT!

Take part in the 5-day course with actionable tasks that will let you become a master at recognizing and solving the most common mistakes iOS developers do with Auto Layout.

Let Auto Layout become a tool you swing with your utmost confidence!

I won't send you spam, I promise. Unsubscribe at any time. Powered by ConvertKit
Hey there! You're already subscribed to my newsletter and you've hopefully gotten some useful tips and tricks when working with iOS. If you're also working with Auto Layout, make sure to check out my book called Auto Layout Fundamentals and get a 20% off for being my subscriber! https://gum.co/autolayoutfundamentals/youareawesome
Jure Zove

A lot of things but mostly a programmer who really likes fast cars. Check me out on Twitter, if you fancy.

Related article

How to properly do buttons in table view cells using Swift closures

Note: This post is an upgrade of the original post…

A practical MVVM example in Swift – Part 2 (featuring RxSwift)

Welcome to part 2 of the practical MVVM example in…

A practical MVVM example in Swift – Part 1

The good ol’ MVC pattern has been around for a…

  • Chris Brown

    This was just what I was looking for, It works perfect. I just wondered if this same principle could be used to enable a button instead of updating a text field? Any ideas? Thanks

    • Hey Chris! What is the problem you’re trying to solve?
      If I understand correctly, you can replace the welcomeMessage with a Bool, then just set the button’s enabled property accordingly.

      • Chris Brown

        Hi Jure,

        Thanks for replying so quick!

        I have a view controller with a text field, 2 disabled buttons and a login button. The user clicks on the login button and a segue takes them to a login view controller to enter password. Login checks password in a mysql database and this returns a username and several boolean values to the login view controller based on the users preferences. The app then uses your sharing manager code to update the text field with a welcome message before dismissing the login view controller. What i want to do is also enable either of the disabled buttons based on the boolean values from the login.

        Hope thats made sense?! Thanks :-))

        • Ok I think I get it.

          If you add two booleans (like button1Enabled, button2Enabled) in the SharingManager class:

          class SharingManager {
          var welcomeMessage:String = “Default Message”
          var button1Enabled = false
          var button2Enabled = false
          static let sharedInstance = SharingManager()
          }

          Then set those boolean vars in the login view controller (after a successful login). Something like:

          SharingManager.sharedInstance.button1Enabled = true
          SharingManager.sharedInstance.button2Enabled = true

          Then, once the main view controller is shown (in the same place you’re updating your text field), you can just use those vars to enable your buttons.

          For example:
          self.button1.enabled = SharingManager.sharedInstance.button1Enabled
          self.button2.enabled = SharingManager.sharedInstance.button2Enabled

          Is this something you’re looking for?

          • Chris Brown

            That’s perfect! It’s exactly what I wanted – Thank you so much !!!

          • Sure, glad to help! Happy coding! 🙂

  • Chris Brown

    Hi Jure, thanks for replying so quick!

    What I have is a view controller with a text field, 2 disabled buttons and a login button. The user clicks on the login button and a segue takes them to a login view controller to enter password. Login checks password in a mysql database and this returns a username and several boolean values to the login view controller based on the users preferences. The app then uses your sharing manager code to update the text field with a welcome message before dismissing the login view controller. What i want to do is also enable either of the disabled buttons based on the boolean values from the login.

    Hope thats made sense?! Thanks :-))

  • Nir Tzin

    hi,
    i used it and its works great but i have some problem. my dataClass that i created have init() that load data from JSON with almoFire. at first its works great but if i run the init again and update the data the sharedInstance still have the old data and do not update. how can i solve it?

  • Ndu Devi

    i have tested your code in simulator using xcode 7.2 . but getting errors in sharedInstance.welcomeMessage = self.textField.text in this line

    • Thanks for the heads up! What’s the error you’re seeing?

  • Ndu Devi

    value of optional type string not unwrapped did you mean to use ‘!’ or ‘?’?

  • Ndu Devi

    i am getting this error . so i have added ! at the end of the line. but when i click change the message i am getting these errors 2016-05-02 14:49:38.550 Sharing is Caring[4515:204669] -[NSLayoutConstraint setText:]: unrecognized selector sent to instance 0x7fa63ad311a0

    2016-05-02 14:49:38.568 Sharing is Caring[4515:204669] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[NSLayoutConstraint setText:]: unrecognized selector sent to instance 0x7fa63ad311a0’

    • From the error you provided I can assume you’re trying to set text on an NSLayoutConstraint. Are you sure you have everything connected up properly from the storyboard to your view controller file?

      • Ndu Devi

        yes

        • Judging from the error, it looks like a constraint might be linked with a UILabel or UITextField, otherwise I don’t have an idea how you could be calling setText on a constraint.

  • Habeeb

    EXCELLENT – THANKS – WORKS PERFECT

Type your search keyword, and press enter to search