I'm creating an iOS that interacts with an API using Alamofire, and requires a Token for most requests. I've built the app using the MVC pattern, and it works great, but I've encountered a problem as I've tried to integrate the API. How should I share/store the token so that it can be accessed from the view controllers/models? I've read up quite a bit and have found negative opinions on using singletons or UserDefaults
, but I've yet to encounter a straightforward answer. I understand this is a pretty broad question that might not have a simple answer, but I am pretty new to this and was wondering if anyone can help point me in the right direction. Thanks!

- 630
- 1
- 6
- 9
-
Does this help? https://stackoverflow.com/questions/16795506/storing-authentication-tokens-on-ios-nsuserdefaults-vs-keychain – Jon Sep 29 '17 at 17:59
-
@Matthew Harries never save token in UserDefaults for security purpose , you can use apple keychain for that. UserDefaults are used to save non-sensitive information. – Tushar Sharma Sep 29 '17 at 17:59
1 Answers
If view controllers need this token, you've broken MVC. There is no reason for a view controller to directly talk to the network. That should be handled in the model layers. A view controller coordinates a view while it's on the screen. It doesn't do anything else.
So you'll store your token in the model. How do the view controllers access the model? That depends on your experience level:
If you're fairly new to Cocoa development, use a shared instance (a "singleton," though really it's not a singleton; it's just a
static let shared
property). This pattern has been used very successfully by Cocoa devs for decades. There's a reason we use it. It just works, and you don't have to fight it. But, it has some problems, which brings me to the next option:If you have enough iOS experience to have actually run into problems with shared instances (usually related to unit testing and occasionally related to code reuse), then you will know enough to have an opinion on all the many other patterns people have been applying (and sometimes inventing) in recent years. But jumping into these more complicated patterns is not, in my opinion, a good approach for new developers. They tend to move you away from how Apple intends us to work (in particular, most of them assume you won't use Storyboards, and Apple pushes Storyboards very hard). There are reasons to go against Apple's guidance, they're not always right, and some of the new patterns are very interesting. But wait until you have some experience before you decide that you know more than Apple about developing Cocoa apps.
If you need to store the token in memory, you're done. If you need to persist it and it's considered sensitive, then the correct place is Keychain. Use a wrapper. The Keychain API is horrible beyond description. Any wrapper will do. KeychainAccess is popular these days, but really, any of them are fine.
The main problem w/ NSUserDefaults is that if someone steals the phone and jailbreaks it, it's easier to read NSUserDefaults than Keychain. As a matter of policy, don't put sensitive information in NSUserDefaults.

- 286,113
- 34
- 456
- 610
-
per your comment "If view controllers need this token, you've broken MVC", can you give an external reference that delves into this further? – ox. May 18 '18 at 16:46
-
3@ox. The best place to start is the View Controller Programming Guide, specifically https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/DesignTips.html#//apple_ref/doc/uid/TP40007457-CH5-SW1. While Apple unfortunately never touches on networking in their guides (it's very frustrating), note the careful separation of UIDocument from the view controller, which is the same kind of separation being discussed here. VCs shouldn't know about files or databases. And they shouldn't know about the network for the same reasons. – Rob Napier May 18 '18 at 17:30
-
1Also worth searching for is the term "massive view controller" which will lead you to many articles on how to reduce the excessive responsibilities that are placed on view controllers. The key point to remember is that VCs are only guaranteed to exist while they are onscreen. If you feel the need to prevent them from deallocating when they go off screen (to deal with a network response for instance), you've done something wrong and will introduce common subtle bugs related to this. – Rob Napier May 18 '18 at 17:32
-
1The point of a ViewController is to manage view lifecycles, and to hand model objects to views. Anything else is going beyond a VC's purpose. (Apple example code and tutorials are often a bad guide to this because cramming everything into the VC makes examples simpler than building a full model. But this is no different than the fact that most example code ignores errors. Neither is acceptable for production code.) – Rob Napier May 18 '18 at 17:34
-
what are your thoughts per this question/answer @rob-napier ? : https://stackoverflow.com/questions/40216992/best-place-to-make-network-calls?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa – ox. May 23 '18 at 20:34
-
1I think Artem gets it right with "In most cases it's not a good idea to send requests from the view controller directly. I would suggest to create a separate networking layer." – Rob Napier May 23 '18 at 21:26