Data Accessor object singleton or some other pattern? (Objective C) - ios

It seems to satisfy the three requirements here: On Design Patterns: When to use the Singleton?
I need it to exist only once.
I need to access it from all over the source base.
It handles concurrent access, i.e. Locks for writes, but can handle concurrent reads.
Hi all,
I've been reading a lot of no doubt intelligent educated and wise gems of advice that Singletons are 'Evil' and singletons are anti patterns or just plain bad news.
With the argument that logging makes sense but not much else.
Just interested to know if the case of essentially a persistent data store context makes sense for a singleton, i.e. Reading/Writing from disk to memory and referencing an object graph.
And if not, how do people normally tackle this issue, I don't currently have any problem with it, I know it's created only once, it's fast and the accessor logic is in one place. Meaning it takes me one line of code to do anything data model related.
Which leaves the only argument that it's bad for testing, in that it's a hard coded production implementation to data, but couldn't I just write a method swizzle through a category or in the test code to create the test version of the singleton?
And the final argument from DI testers, is that it is a hard coded implementation, rather than simply an interface to something, which I do get but I don't really have a major drive to use a DI framework given that I can use protocols for implementation, and use separate init methods for setting up an objects state in testing. There's only ever going to be two types of state for the singleton, or realistically one type...production.
Making it (in my opinion) much easier to read and faster to develop.
Change my view SO?

Yup, for some singletons are Evil. For the new developers who has little MRC knowledge and more ARC it sounds scary because they need to mess with memory,volatile,synchronize etc.
However it is not against to use them, they indeed has their own purpose to use with some are below.
when sharing large data models like arrays and dictionaries etc between multiple screens (VC's) we can't prefer storing them in UserDefaults (because userdefaults is permanent storage and storing such large entries make app start lazily) instead singletons are best since they stay only current app context and restarting app creates new one.
when we need a stable db connection to be accessible allover the app without messing up with connecting and closing in every business classes we can go for it.
when we wanted an ability to app for theming itself dynamically we would need to create a singleton class which holds all the color,image instances etc. and use that instance in application VC/Views etc so no code duplication and re-processing theme occurs in all places.
You dont have to change your view but tweak it a bit to get some positive intention towards singletons.
Hoping this clears it out, thanks

Related

Best Practise for storing data in an iOS app?

I've looked through a lot of answers on stack overflow but haven't found anything that answers this question.
I have an app where you download data in a downloadVC (there are many other VC's). I want to be able to access the currentUser and the downloaded data in the downloadVC whenever I go to the downloadVC without re-downloading the data.
The options I've looked at so far are:
Making a singleton with data that I could access at all points of the app (feels like the easiest way but people have warned me singletons aren't good).
Making a class var of download VC. (This is the solution I understand the least, what is the scope of a class var? Is it just the same as making a singleton?)
Passing it around (This wouldn't work for me as the app is too big to have it passed between every VC)
Saving it to user defaults, (how quick is accessing something user defaults?)
Please tell me if this questions doesn't fit the stack overflow rules?
Singletons are usually implemented using a static variable, so your first and second options are quite similar.
There is a "singletons are evil" sect that's very vocal in the development community lately.
Personally, I think they have their place and can sometimes clean up your design. I recently worked on a project that had been designed by a member of the "Singletons are evil" cult who then went to absurd lengths to pass a data manager object around to every other object in the project, resulting in a lot of overhead and more than a few bugs when the object got dropped.
There is no one answer. You need to weigh the pros and cons of different approaches for your app.
I would caution against over-using UserDefaults though. That's intended for saving small bits of data like user preference settings, not big data objects.
Basically, adding any networking logic inside the view controller is a first big mistake that you could make. So move that to another class that is responsible only for sending network requests and handling the responses.
Then, when you have the data downloaded, you'll probably need something to manage the cache - no matter whether it is a set of big files or a couple of small strings, the logic would be the same - to have all this cache controlled by one object. This cache manager could save the objects to local files, use CoreData or simply keep those objects in memory - this is for you to decide, depending on what kind of app are you creating.
Now, the cache manager could basically be your endpoint for view controllers, since it will either download the data and return it to view controller after the request's success, or return it immediately. The view controllers don't really have to know about any networking at all.
But, how the view controllers will find out about the cache manager?
You could either pass around the reference to it, but you've already said that this is impossible in your app. So basically another solution would be to use the hated singleton pattern. I too personally think this is a bad pattern, however you cannot create any app without it, since you always must have at least one singleton, which is AppDelegate.
Anyway, a good idea might be to create a singleton class (or maybe even use the AppDelegate for that purpose), that would be responsible for handling the dependencies between the classes responsible for networking, the cache manager, and any other classes that you might need to perform some logic behind your app. This is actually a pattern called Dependency Injection Container. It would allow you to easily access your model classes through this container, without neither having a ton of singletons that will eventually make you confused, nor creating some ridiculous logic of passing around the model objects.
The simple answer is, yes, you use a singleton.
That's exactly correct.
Note that whether you use
SQLite.swift,
core data,
realm.io,
write to a text file,
a baas such as Firebase or Back4app (aka Parse),
or literally just "keep it in an array" ("in memory"),
Yes, the answer to your question is you'll have singleton which is where you "keep - access" that stuff. Exactly correct.
That seems to be what you are asking here.
Given that ...
... if you are then additionally asking "what's the easiest / best / most modern way ("in my data singleton") to store data locally in my app", the real-world answer in 2017 is
realm.io
Previously you used Apple's core data. Which is (a) spectacular (b) extremely difficult. Importantly though: realm.io and SQLite are identically available on both Android and iOS; in very many cases, on real world projects today, this eliminates Core Data from consideration.
However. All of this is somewhat moot. Don't forget ...
We now live in a "baas world"
You can't eg. "get a job programming iOS or Android" any more. You get a job because of how good you are / your specific expertise areas in either Firebase, Parse, PubNub, Cloudbase, or whatever. For better or worse, being able to move buttons and tables around in Xcode, Studio, is not really a thing anymore. (There are a minuscule number of hyper-specialities, like GPU programming, dynamic mesh, or the like, that are exceptions to this.) Similarly, say you're a hobbyist making your own app or startup: again in that case, it's just entirely and totally about what backend you work with. (And that applies equally to games or business/social apps.) There are simply no "local, static" apps any more. (Again, applies equally to games or business/social apps.)
(Note indeed that realm.io, which is "the" simple, obvious way to keep data on apps these days - indeed, those guys have/are moving to becoming, indeed, a OCC cloud baas-paas-whatever service themselves. We'll probably all just use realm.io instead of Firebase in a year.)
So in a sense the answer to your question is something like Firebase or back4app. But: then within your app, you centralize that to a singleton, indeed (the first part of your question).
But note....................
it is extremely unlikely, at the beginner level, that any of this will be relevant: Just keep the data in an array! That's all there is to it. OK, once in a billion years when a user happens to literally restart the device or your app, the app will reload data. So what?
Note that a common name for your "get data here" Singleton is
Local
So,
import Foundation
often .. import SQLite, Realm, Firebase or whatever
public let local = Local.shared
open class Local {
static let shared = Local()
fileprivate init() {
print("'Local' singleton running AOK")
}
// could be this simple..
var clients:[String:[Blah]] = [:]
var stock:[String:String] = [:]
func loadStockInfoFromWWW() { ... }
func calculateQuantityInfoOrWhatever() { ... }
// or it could be more like this..
func reloadClientsFromParse() { ... }
func sendNewDataToFirebaseParse() { ... }
.... etc
you then just access it from anywhere in your app like
local.updateFromWeb()
height = local.stock["ladders"][idNumber].size.h
and so on.
That's all there is to it.
(A word on singleton code style.)
It depends on file complexity & size. If you don't need to parse the contents, or they're simple to parse, but it's large in size then I'd recommend using the Documents folder and retrieving it from there, if it's small or involves complex processing then a singleton acting as a manager would be my approach as it feels appropriate.

Debating the use of dependency injection in iOS app

I'm working on an iOS app where we need different binaries for each customer based on their needs. A customer may want to change all the colors, icons and texts. We can do that through white labeling process. The problem here, though, is when they ask for different behavior, for instance, removing login screen and making it optional to login.
I thought we can use dependency injections and use different handlers for each customer if needed. For instance, we can have LoginHandler1 and LoginHandler2, both implementing ILoginHandler and inherit from UIViewController.
However, use of dependency injection is costly, it slows down the app because resolving is expensive comparing to normal instantiation.
The other way is to define all these behaviors in the app and enable/disable them in a plist file. like "is login optional? yes/no"
Any suggestions?
Thanks
You should create the entire object graph up-front, in the composition root. Object creation, and constructor injection, should not take much time at all as long as your constructors are not doing any actual work.
That being said, there are times when creating the entire object graph at the start of the application may take longer than is acceptable. In those cases, you can use lazy-loading to defer the costly initialization until later - while still creating the objects in the composition root.
Mark Seemann describes this approach in more detail here: Compose object graphs with confidence.
I thought we can use dependency injections and use different handlers for each customer if needed.
You thought right. Flexibility is one of the main reasons people use DI.
However, use of dependency injection is costly, it slows down the app because resolving is expensive comparing to normal instantiation.
It really doesn't cost that much at all. Have you tried it yourself? Unless the object in question (i.e. the object being injected) is very expensive to instantiate, you have no real reason to stay away from DI and Inversion Of Control. Also, as #Lilshieste noted above, creating the object graph up front (see AppDelegate) will probably make this even less a problem.
A good way of doing that is described here:
http://cocoapatterns.com/passing-data-between-view-controllers/ and here http://cocoapatterns.com/ios-view-controller-transitions-mediator-pattern/
The other way is to define all these behaviors in the app and enable/disable them in a plist file. like "is login optional? yes/no"
While less "elegant", this solution is a pretty useful one, especially if the project is not really big in terms of number of classes and VCs. It is also the easiest one to implement if the app code is already laid out and introducing major design changes would ask for lots of refactoring.
Always take action based on the task at hand, there is rarely if ever a single solution to a software design problem.

Is using a singleton as a data manager class bad?

I commonly create apps that require storage of data, and this data is used across the entire program. It's not much, though, so I usually use NSUserDefaults to load/save this data. However, the saving/loading code, along with packing/unpacking the data, takes up space, and I thought moving this code to reusable methods inside a global singleton would be a good idea. It seems to have worked well.
Even so, I've read a lot lately on the evils of singletons and global objects, and I've started to have second thoughts. People often say that the use of singletons is almost always an indications of poor design. For the most part, I'd disagree (I think simple uses like this are a good design pattern), but I'm certainly no expert on the matter.
So, is using singletons even in a simple way like this bad? If so, what's the better alternative?
I definitely don't agree that singletons are evil. They are sometimes overused perhaps but on some occasions are just perfect for the job. In some applications it makes sense to have some kind of general data manager. The singleton pattern is used extensively in the SDK itself (app delegates, shared managers, default centers and so on). Most often these are not "pure" singletons, as in you can access a shared instance but can also create new instances if necessary.
The question you need to ask yourself is whether it would be useful to have access to a single instance of a data manager from anywhere at anytime, if it isn't then a singleton is probably not needed. If you are going to be using singletons in multi-threaded environments however, you do need to worry about race conditions (can one thread modify a resource while another is accessing it), the documentation has good explanations on how best to achieve this in Cocoa.
Let me try to explain with an example - Am using some code from a game I wrote. Let's say you have a GameMap class and a Tile class. The GameMap represents a 2 dimension grid of Tile objects.
GameMap *gameMap = [[GameMap alloc] init];
NSArray *theTiles = gameMap.tiles;
The instance of the GameMap owns the grid of tiles, and creates the tiles when the game map is created. No singleton needed.
You may say "but I only have one GameMap at a time, what's the big deal?". What about loading saved games, or loading new levels? Well that becomes as easy as:
// In whatever class object owns the game map
self.gameMap = [[GameMap alloc] initWithSaveData:saveData];
In conclusion, create an instance of a class that has code to manage other instances of things. Keep as little global as possible and your code will be more scalable and maintainable.

Why does Apple documentation that getting ManagedObjectContext from UIApplicationDelegate is bad?

Just curious why ManagedObjectContexts should be passed to UIViewControllers when they are created, rather than just grabbing them from a UIApplicationDelegate?
The docs say that this makes your applications more rigid, but I am failing to see the nuances of when to use which pattern.
Thanks!
Imagine that I ask you to do some task, like painting a room. If I just tell you "go paint a room," you'll need to ask me a lot of questions, like:
Which room?
Where's the paint?
Where are the brushes?
Should I use a dropcloth?
In short, you won't be able to complete the task without help from me. If you have to depend on me every time, you won't be a very flexible painter. One way to deal with that problem is for me to give you all the stuff you need at the outset. Instead of "go paint a room," I'll say "please paint room number 348 using this bucket of paint and this brush, and don't bother with a dropcloth." Now, you've got everything you need, and you can get right to work with no further help from me. You're a much more flexible worker because you no longer depend on me.
The same thing applies to view controllers (and objects generally); it's better to give them everything they need than to have them depend on a particular object like the app delegate. It's true not just for managed object contexts, but for any information they need to do their job.
This is mainly because you want to use dependency injection with your UIViewControllers instead of just grabbing everything from UIApplication, this keeps your delegate clean instead of full of reference hacks.
This is also to keep with the MVC pattern:
Model
View Controller (Only for view logic)
Controller (For coordinating between the view and the model)
I tend not to agree with this pattern.
First of all I try to treat Core Data as an implementation detail, and as any implementation detail it should be hidden behind a good facade. The facade is the interfaces I expose for my model objects. For example if I have two model objects; Cource and Student, any cource can have a number of students. I do not want to let the controller take upon the duty to setup predicates and sort descriptors, and jump through all Core Data hoops just to get a list of students for a particular class. There is a perfectly valid way to expose this in the model:
#interface Cource (StudentAccess)
-(NSArray*)studentsStortedByName;
#end
Then implement the ugly stuff once and for all in the Model class. Hiding all the complex details of Core Data, and no need to pass around managed object contexts. But how would I find the sources, it has to start somewhere right? Yes, it does but you need not expose it to the controller. Adding methods such as these are perfectly reasonable as well:
#interface Cource (CourceAccess)
+(Cource*)caurceByID:(NSString*)courceID;
+(NSArray*)allCources;
+(NSArray*)courcesHeldByTeacher:(Teacher*)teacher;
#end
This also helps in minimizing dependencies between controllers. And reducing he dependencies between the model and controller. Assuming I have a CourceViewController and a StudenViewController is I did not hide the Core Data details behind a facade and wanted to pass around the managed object context as well, then I would end up with a designated initializer like this:
-(id)initWithManagedObjectContext:(NSManagedObjectContext*)moc
student:(Student*)student;
Whereas with good a good facade I end up with this:
-(id)initWithStudent:(Student*)student;
Minimizing dependencies behind facades, in favor of dependency injection also makes it much easier to change the internal implementations. Passing around the managed object context encourages each controller to implement their own logic for basic stuff. Take for example studentsSortedByName method. At first it might be sorter by last/first name, if later changed to last/first name sort you would have to go to each and every controller that has sorted students and make the change. Where a good facade method requires you to change in one method, and all controller automagically get the update for free.
The Apple Docs try to foster the most widely applicable and sustainable design patterns.
Dependency injection is preferred because it allows for the most flexible, expandable, reusable and maintainable design.
As apps grow in complexity, using a quasi-singleton like parking the context in the app delegate breaks down. In more complex apps, you may have multiple context tied to multiple stores. You might want the same view-controller/view pair to display data from different context at different times or you may end up with multiple context on different threads/operations. You can't pile all those context up in the app delegate.
If you have a simple app with a single context then using the quasi-singleton with the app delegate can work well. I've used it on several smaller apps in the past without immediate issue but I did hit scalability problems on a couple of apps when the apps grew overtime.
Which pattern to use depends on your shipping constraints and you best guesses about of the evolution app over its entire lifecycle. If its a small one shot app, then the app delegate quasi-singleton will work fine. If the app is more complex, might grow more complex or might spawn other related apps that will reuse existing components, then dependency injection is the way to go.

I'm using Dependency Injection: which types should I bind as singletons?

There are a lot of questions out there about whether singletons are "bad," and what patterns to use instead. They're generally focused on the singleton design pattern, which involves retrieving the singleton instance from a static method on the class. This is not one of those questions.
Ever since I really "discovered" dependency injection several months back, I've been driving its adoption in our team, removing static and singleton patterns from our code over time, and using constructor-based injection wherever possible. We've adopted conventions so that we don't have to keep adding explicit bindings to our DI modules. We even use the DI framework to provide logger instances, so that we can automatically tell each logger which class it's in without additional code. Now that I have a single place where I can control how various types are bound, it's really easy to determine what the life cycle of a particular category of classes (utility classes, repositories, etc.) should be.
My initial thinking was that there would probably be some advantage to binding classes as singletons if I expected them to be used fairly often. It just means there's a lot less newing going on, especially when the object you're creating ends up having a big dependency tree. Pretty much the only non-static fields on any of these classes are those values getting injected into the constructor, so there's relatively little memory overhead to keeping an instance around when it's not being used.
Then I read "Singleton I love you, but you're bringing me down" on www.codingwithoutcomments.com, and it made me wonder whether I had the right idea. After all, Ninject compiles object-creation functions by default, so there's very little reflection overhead involved in creating additional instances of these objects. Because we're keeping business logic out of the constructor, creating new instances is a really lightweight operation. And the objects don't have a bunch of non-static fields, so there isn't a lot of memory overhead involved in creating new instances, either.
So at this point, I'm beginning to think that it probably won't matter much either way. Are there additional considerations I haven't taken into account? Has anyone actually experienced a significant improvement in performance by changing the life cycles of certain types of objects? Is following the DI pattern the only real important thing, or are there other reasons that using a single instance of an object can be inherently "bad?"
I am using singleton instances to cache expensive to create objects (like nhibernate session factory) or for objects I want to share across the application.
If in uncertainty I would rather have the object be recreated every time it is used and mark it as singleton or "per thread"/"per request"/"per whatever" only if you really need to.
Scattering singletons all over the place to potentially save some newing up is premature optimization and can lead to really nasty bugs because you can't be sure if the object is new or shared across multiple objects/instances.
Even if the object has no state at the moment and seems save to share, someone can refactor later and add state to it which then may be unintentionally shared between different objects/instances.
I am not sure if memory management is the big issue unless you are creating A LOT of objects. I found using singleton from my IoC container helpful when dealing with something like caching, where creating the caching object and making a connection to the caching servers is expensive during creation so we create the caching object once and reuse it.
A single instance can be harmful however cause it can create a bottleneck in performance as you have a single instance serving multiple requests in the case of services.
It shouldn't matter much for memory usage, but you'll get increased modularity, easier testability with mock objects, and the aesthetic ugliness of having to write out dependencies explicity will encourage programmers to make each class more orthogonal and independent. It's easier to gloss over dependencies when your class is calling globals, which a singleton basically is, and it can make your life harder later.
As noted in Gary's answer, the whole point of DI is testability (you can easily mock out all references to a class since they are all listed in the constructor), not runtime performance.
You want to do TDD (test-drive development), right?

Resources