1

I am creating a login app for iOS and have stumbled upon a design issue. In my app some data (e.g. current user id) has to be shared across view controllers so my initial thought was to hold that data in the AppDelegate and just call it from there whenever it was needed. This would work but it would mean that the AppDelegate would be doing work that it wasn't intended to do and hence it would be bad architecture, so I thought of creating a singleton class to hold all the shared data instead. This seems to be more focused and I have used this strategy in some of my previous apps, but googling the best practices for singleton classes, I found many results against using them, as they:

  1. Hide dependencies
  2. Violate the single responsibility principle
  3. Make unit testing difficult

(taken from the top answer to this question: What is so bad about singletons?)

The alternative to the two other design patterns would then be to pass data back an forth between view controllers, but this again seems inappropriate. Take for example the current user id I would have to pass it from the login view controller to the main view controller (which is the same for all users), then from the main view controller to a more specified view controller which is customized for the user. In this case the main view controller is holding data only for the purpose of passing it to the more specific view controller and to me this also seems to violate the single responsibility principle. Would it be bad design to let the main view controller hold data it doesn't need or is there a better alternative?

Community
  • 1
  • 1
Sebastian
  • 314
  • 1
  • 2
  • 10
  • Many people indeed argue against singletons, majorly because it exposes _global state_ which easily can lead to issues that you didn't expect in your code. I would however say that it depends a little on your level of experience and the size of your app. If you're not too familiar with more advanced design patterns and the app is not intended to be a long-year product, I would say going for singletons is totally fine (also because you need to understand why it might be bad when you want to produce bigger, scalable projects, and that you can do best by experiencing its limitations by yourself). – nburk Jan 24 '15 at 10:54
  • @nburk right now the project is not very big but it could end up being so. Could you give me examples of these more advanced design patterns or maybe some books I should consider reading. I am here to learn :) – Sebastian Jan 24 '15 at 11:10
  • 1
    here's an objc.io article on the topic, I found it very helpful in understanding the perks of singletons misuse http://www.objc.io/issue-13/singletons.html – nburk Jan 24 '15 at 11:13
  • and don't get me wrong, using singletons in this kind of situations isn't the worst choice you could make IMHO (and I know others will disagree on this). only be aware of the issues that might come along with it. I bet that most of the production code you find in the wild use singletons to store user credentials and session data since that's really a convenient and near-by-hand solution. – nburk Jan 24 '15 at 11:16
  • Using a singleton to contain global state info (such as the current user ID) is perfectly valid, though it's really no different from using the AppDelegate (which is specifically there to contain global state info). The hazard with singletons is that users can easily fall into the trap of creating a new singleton (or overloading an existing one) every time there's some need to share data between two classes, even though some even moderately careful design would have allowed the data to be passed as parameters. Once you start down that road complexity grows very rapidly. – Hot Licks Jan 24 '15 at 14:20

1 Answers1

0

There is no "magic" way of storing the model state of your model-view-controller application: you build a class, and you "anchor" it somewhere for easy access.

One common practice is using the app delegate. It is convenient, because it is a system-supplied singleton globally available to your app, but it is logically inferior, because, as you noted, app delegate was not intended for that.

Another common strategy is using a singleton. This is commonplace in app development, and it works fine in practice. You can mitigate the common grievances by limiting the access to your singleton to initializers of your view controller - this addresses the hidden dependencies and the testability issues.

Finally, you can pass the data around, in which case it is the same as "anchoring" it in one of the view controllers. Arguably, this leads to even bigger problems than singletons, because the dependencies become even harder to trace.

I would recommend storing the state in a singleton, and use it in the initialization code of your view controllers. This way the dependency on the singleton remains localized, and you could test your logic with minimal effort.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523