3

This is more of a design best practice question:

When you are designing the structure of lets say a location based app. The location Manager is obviously an important instance and should be given easy access for other objects.

Should you have it as a property of appDelegate? or a singleton on its own?

Under what scenario would you prefer one over the other?

I understand both would work, but I want to make sure I'm doing things the right way, not just hacking everything together.

Your inputs are much appreciated!

Jacky Wang
  • 618
  • 7
  • 27
  • I like if my appdelegate class contains little code, so I prefer creating location manager like singleton – gaRik Apr 18 '15 at 09:23

5 Answers5

2

Neither.

Pass in a location manger object via a custom init method or property where ever you need it.

This will conform with the SOLID principals S, O & D (single responsible, open-close, dependency inversion).

Also testing with mocks will be possible more easily.

vikingosegundo
  • 52,040
  • 14
  • 137
  • 178
  • 1
    I don't see how it's neither! Having it as a singleton object with all location manager responsibility and use observer pattern or delegation doesn't violate neither Open-Close nor dependency inversion principles ! – Radwa Ebrahim Apr 18 '15 at 16:23
  • 1
    Sure it does violet open-close, as if you want to use a subclass instead you have to alter the class that uses the singelon. And it obviously violates dependency inversion, as this states that dependencies must be handled from outside a class. – vikingosegundo Apr 18 '15 at 19:11
  • For open-close yes you are right in general sense, and I know that singleton in general has its problems and people don't prefer it. But regarding the case at hand, I saw many tutorials use it this way as best practices ,because why would you subclass location manager? its responsibility should be just getting/observing location updates. Anything further than that should be done outside it. – Radwa Ebrahim Apr 19 '15 at 08:18
  • Many tutorials are inheritable broken, as they are focusing on the details they want to teach. Best examples are nearly all apple codes as they all conflicts with Single responsible principle: View controller implements just EVERYTHING. Apple is aware of this, see wwdc video "advances in collection views" or similar. – vikingosegundo Apr 19 '15 at 13:42
  • [«Advanced User Interfaces with Collection Views»](https://developer.apple.com/videos/wwdc/2014/#232). This video reveals that most of apple's tutorials are architectural broken. Though it does not name singletons and their treatments it proves that you should not take everything found in tutorials as "best practice" — what ever this buzz word means for you. – vikingosegundo Apr 19 '15 at 14:19
2

The worst choice IMO is to store things in the app delegate. See What describes the Application Delegate best? How does it fit into the whole concept? for much more on that. In short, the app delegate is the Application Delegate. It is not "the Application Dumping Ground for Globalish Things."

Singletons are a long-established approach in ObjC, via the shared... pattern. After decades of popularity, and extensive use within the core Cocoa frameworks (NSUserDefaults, NSNotificationCenter, NSApplication, NSFontManager, NSWorkspace, UIDevice, etc. etc. etc.), they have in recent years fallen into some disregard in favor of other techniques, particularly "dependency injection," which is just to say "assigning to a property."

After years of using singletons in ObjC, I am coming around to the DI way of thinking. The improvements in testability and the improved clarity of dependencies are quite nice. That said, sometimes DI can lead to awkward transitions, particularly when dealing with storyboards.

So, I would say:

  • When practical, just construct objects and assign them to properties on the objets that need them.
  • If you have a lot to pass around, consider collecting them into a single "configuration" object and pass that around (but this hurts modularity somewhat).
  • If DI creates chaos (particularly if it leads to a lot of passing objects to things just so they can pass the object on to something else), or if it forces a lot of storyboard segue code that you could otherwise avoid, singletons are a well-established and well-respected pattern in Cocoa and are not wrong. They are a Cocoa Core Competency.
  • If you ever find yourself calling (MyAppDelegate *)[[UIApplication sharedApplication] delegate], then you're doing something wrong.
Community
  • 1
  • 1
Rob Napier
  • 286,113
  • 34
  • 456
  • 610
1

Make another singleton for location management. Single responsibility is a first principle of SOLID.

Vlad
  • 7,199
  • 2
  • 25
  • 32
  • And violate O & D of SOLID – vikingosegundo Apr 18 '15 at 15:38
  • Can you explain what do you mean? I really think that he should not do this with AppDelegate because it has another role. Single responsibility principle just described my thoughts. – Vlad Apr 18 '15 at 15:51
  • See my answer. Neither. – vikingosegundo Apr 18 '15 at 15:53
  • 1
    I think a singleton for location management does not violate O and D principles. It doesn't modify CLLocationManager, just provides a simple access to its properties and implements some useful functional. It doesn't inverse dependencies because this singleton doesn't depend on any other modules of the app. His functions are simple: configure one instance of CLLocationManager (i don't know why I will need another one), take care about authorization status and give an access to current location instance. Please tell me why this solution is bad? I really want to know. – Vlad Apr 18 '15 at 16:25
  • 3
    The singleton itself does not violate any SOLID principles, accessing it from inside a class does. A Breyer example is using nsuserdedaults: when i need it in a class, I will pass it in, even though I probably will always use the standarddefaults. But this gives me the choice to pass in a mocked version for testing. – vikingosegundo Apr 18 '15 at 19:08
0

Think about do you really need it in AppDelegate ?

For Location Manager for example, no you don't. You better keep the location manager with all its related methods in a separate class to keep the singularity principle as @vladimir said, and to be able to reuse it later.

AppDelegate is responsible for handling what happens when the app launch and/or going to the background, initializing core data, registering to push notification and other 3rd party libraries like parse,...

Adding other things to appDelegate will make it grow larger by time and it would be very hard to maintain.

When to add things that don't belong to AppDelegate to it? I think when the app is small, you know it won't scale up, and you are required to favor time over clean code.

Check the AppDelegate responsibilities , and this answer by Matt

Community
  • 1
  • 1
Radwa Ebrahim
  • 337
  • 2
  • 8
  • Yes I totally get what you are saying. But what about other scenarios? I see many people like to add all their ViewControllers and managers in appDelegate. Is that necessary? – Jacky Wang Apr 18 '15 at 15:31
  • That's according to what they are adding. If you have an example for that we can discuss it. But in general, it's more easy to add everything in app delegate and I saw some beginners tutorial do that, but it's wrong and it will hurt your sanity when you maintain the app later. So again my key for that is, is it belong to app delegate responsibilities ? If so add it, else never... I'll add links to the answer check them – Radwa Ebrahim Apr 19 '15 at 08:46
0

You can create multiple instances of CLLocationManager and use them wherever you need them.

If you create one instance and try to share it then you'll have trouble trying to forward the delegate methods around or try to re-implement them as notifications leading to a big mess.

malhal
  • 26,330
  • 7
  • 115
  • 133