Object sharing in my iPhone App - iphone

I'm currently developping my first iPhone application and I would like to know what is the best way to share an object which is gonna be used in every controller.
I was thinking of referencing the controller containing the needed data in other controllers and access this data thanks to properties, is that a good idea or is there a better way to do it?
Or can we declare any global variable (not const) accessible anywhere in the application?
Thank you

It's not clear from your question what kind of data you are dealing with, but one approach I have used in iphone applications is a singleton object that contains application state and state management functions.
There is a good discussion of the use of singletons versus app delegates for this type of data found at Cocoa With Love and I agree with what he has to say here.
For instance the application in this case had a user account tied to a web application so on load the application would initialize the singleton object and when the user signed in it would keep a reference to the user object in the singleton so that user info could be referenced for api calls.
This approach has worked fairly well for my purposes you can see how to create a singleton class in Objective-C here, and also in the apple docs here there are several ways to do it which provide the same functional result.
Once you have defined your singleton class you can initialize it in applicationDidFinishLaunching or in the viewDidLoad of your main controller and init the globally accessible data you are needing to manage. I highly recommend you read the Cocoa With Love article I linked above for some consideration of managing this whole process.
Hope that helps.
If you're stuck I can post some example code, but the singleton class examples available are pretty straightforward to work with.

If you really need it to be global, you can put it in the AppDelegate or create a data management object. But I think it's frowned upon to do it like that.

Related

Can I pass parameters to a Singleton class in Swift? And general Singleton use

Is it possible to pass parameters to a Singleton class? If so how?
This is a snippet of one of my Singleton classes:
class NotificationManager: NSObject {
static let sharedManager = NotificationManager()
var tabBarController: UITabBarController!
private override init() {
super.init()
}
In the case of this Singleton, the public property tabBarController must always be set before being used.
I'm wondering if its possible to pass the correct UITabBarcontroller object on start up, as I assume this is when my Singleton class is being instantiated? This would prevent the class from ever being implemented incorrectly. Not that I ever expect this to be a problem as is.
Also, is it perfectly fine to use Singleton classes in this instance? To manage a specific set of operations? In the past I was always passing objects around, especially managedObjectContext, however now I've found Singleton classes to make everything much cleaner, nicer, and safer (as there is only ever one stance) in large apps. I can understand passing objects between classes is fine for smaller apps, but once they can large it can get pretty messy.
In my most recent app I'm also using a shared Singleton class between my iOS and watchOS app that defines a few global variables, such as server endpoints, and environments. This appears to be the best way to go about defining variables that require this access.
I've had friends tell me that Singletons are bad to use, and from what I've Google'd, it really seems like a mixed bag. In my case, they have made my code way easier to manage, and handle.
Thanks.
You can set up a singleton anyway you like. You will just have to change the way it's initialized/organized. There are some examples in this question. For some general critiques of the pattern you can read here
My own opinion is that it's generally good to avoid singletons, but sometimes they are necessary. However I tend to say singletons should only be used when the can be initialized when the app starts (App Delegate), and can/should be used and alive throughout the entire app's lifetime.
I would warn against using singletons having to do with your user interface. It appears you're capture a UITabBarController. I would strongly recommend against this, and instead use delegation or Notifications to respond to events. This is partially because of general design weirdness, but it also complicates app restoration and the memory footprint of your app.

What is the best way to refer to a model API from a view controller?

I really hate singletons and would like to know if there is a better and cleaner way to pass a model reference to a view controller so I could use it's API.
Dont hate singletons, just learn to use them where they are appropriate.
That said, if you don't want to use a singleton you can instantiate your model controller in your app delegate or a 'root' view controller and then pass the reference to all of the view controllers which need it (just like you would pass any other configuration data).
On singletons, they are appropriate when you have some content which should only exist once and it needs to exist for the lifetime of the app. This state would also usually be shared between multiple areas of the app. Singletons obviously aren't the only choice but in an Object Oriented language it makes sense to have an instantiated object to own and manage particular state and knowledge.
People often abuse the app delegate and give it a number of inappropriate responsibilities, using a singleton would provide a better app structure.

How should I use Facebook object across several viewcontrollers

I have been playing with the Facebook iOS API the past days and I got some questions. If I have two distinct view controllers that both need to use the Facebook object how should I share the object? And is it necessary to share it at all? I have been thinking of making a singleton. What I thought of doing was making a class "SocialMedia" that has a class method named "sharedFacebook".
Then I have another class named PREFIXFacebook where I conform to the session protocol and make an object. This class has an attribute named facebook. Then I instantiate this class in the SocialMedia class and send the method "facebook" to it and assign the returned object to the static Facebook variable in SocialMedia. Is that bad design? I have not been doing much singletons before, and I don't even know if it is necessary, but I don't want to duplicate the code.
Another approach would be to do this in the app delegate, but I read a post here on stack overflow and heard in one of the stanford iOS videos that it is bad to do such things with the global. Any thoughts?
As with most things, global variables are not bad in moderation. If you abuse them, you will be running short on Memory, but I think it is justified in this case. A singleton is essentially a global variable and I believe your plan here is a good one. Not only will it help you with Facebook, but it will help with other single-login sites such as Twitter and Google+.
To keep things with a small footprint, you don't want to store a million things in the Singleton class. Try to only store the bare minimum needed to avoid re-authenticating. This probably means only the Facebook object itself, and not an additional wrapper class for it.

How can a Singleton be used to allow communication between various view controllers?

I have been suggested to use the Singleton model at:
http://www.galloway.me.uk/tutorials/singleton-classes/
Some of the questions I have are:
where do I declare the singleton?
Do I release it anywhere or does it terminate with the application?
Any tips in terms of the Singletons in apps?
Thanks
Singleton object can be accessed from any where in your application.
You initialize it at the first time get call (via static method). Then the instance will remain in the memory.
You releases it when the application terminated.
It is just a class having only one object. That's why its called singleton.
We don't release it. It gets when the app terminates.
A Singleton is a construct allowing a class to be instantiated only once.
I am not an expert in iPhone programming, but Singleton doesn't mean the object is accessible from anywhere in your application imho.
You can still manage it's accessiblity through visibility. And you definitely should.
Overuse of the Singleton can lead to tight coupling of your classes to a static instance (your Singleton) and that is usually what you are trying to avoid in object oriented programming.

How do you handle Domain Objects in an iPhone application?

I've got a few apps under my belt now, but I'm still relatively new to this. I'm looking for best practices advice or even a feature of the Cocoa Touch framework that I wasn't aware of, if anybody knows it.
In the 1st app, I created Domain Objects in my Application Delegate, then would pass them off to my ViewControllers as needed. For example, in the App Delegate I'd try to load the user's account from memory, and if it was there I'd create an Account object using initWithCoder. Then, whenever I instantiated a ViewController that needed the Account object, I would pass it to that ViewController which had its own account property.
However I felt like I had too much code in my app, so I decided instead to have my ApplicationDelegate manage my Domain Objects. Whenever a ViewController needed one it would query the ApplicationDelegate like so:
MyAppDelegate* myAppDelegate = [UIApplication sharedApplication].delegate;
ADomainObject* anObject = myAppDelegate.anObject;
Is this insane? Is it a good idea? I totally made it up on my own so I'm wondering if anything better is out there. Since I'm new to iPhone dev, I'm trying to learn the best way to do things...
What you described works; I've used the same strategy when dealing with Core Data on the desktop, where my application has a single managed object context owned by the application controller. Besides singletons as Alex mentioned, one other common strategy is to implement a "data controller" that handles the logic of loading and managing your domain objects. In this case your application controller would still be responsible for initializing and managing the relationships between the data controller and view controllers, but it wouldn't be cluttered with model object specific code.
No, it's not a bad design. You might want to look into using the Singleton pattern as an alternative or, more likely, a complement to the App Delegate idea. You would be able to write things like
[ADomainObject sharedDomainObject]
to get your object. Class methods are also a good way to get domain objects in a single-document application -- as all iPhone applications are single document. If you had, say, a hierarchy of Folder objects, you might have a class method like + (NSArray *)rootFolders or + (NSArray *)allEmptyFolders to get specific groups of objects.
In non-Cocoa application development that I've done, I've found it helpful to use the DI approach, where objects have their dependency objects (in this case, your domain objects) handed to them from outside, rather than reaching out and asking for them explicitly. "Asking for them explicitly" would mean something along the lines of what you are currently doing - accessing them via properties on your application delegate. Is it possible/easy/foolish to create associations between ViewControllers and the domain objects in some fashion, so that the ViewControllers don't have to explicitly ask for them? For example, is there a way to establish these relationships in the nib? I'm asking, not advising, since I'm no expert on Cocoa. (Sorry to piggyback my question on this thread but it's pretty related to the original question.)
I wouldn't have the app delegate involved at all. The View controller instantiates and owns the model object if there's only one controller using that object. Otherwise I use a Class-level method to retreive a static instance of the model, with a +[DatabaseModel sharedDatabaseModel] method.