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.
Related
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.
I am playing around with Entity Framework to see how it can be used in a new project I am working on. I put my edmx file in a class library so the Entities (and database access) can be used in multiple places. Currently I have a web project and a console project both referencing the class library.
One of my Entities has a Partial class defined with a static method. The purpose of the method is to accept some parameters and create one or more instances of the specific class. My first version of the method created an ObjectContext instance, created the Entity class (or classes), and returned the Entities to the calling method. The calling method then updated some properties and tried to save the Entities using a new ObjectContext instance. Obviously this did not work because the Entities were bound (correct term ??) to the Context created within the static method.
After some research, I modified the static method to also accept an ObjectContext reference to ensure that all the Entities where created and then later on manipulated and saved using the same Context. This works fine but the design just feels wrong.
Assuming that my one static method may grow into many more, or that my app (especially the web app) would probably benefit from additional layers (DAL or even a Service Layer), does it make sense for all these classes to require an ObjectContext parameter?
I have read on many postings that creating an ObjectContext via a Singleton pattern is a bad idea because "many clients would use the same object". My problem with that is I do not see how that is possible. In a local console app there is only a single user running the app. In a web app there would only be a single user on each request. Where is the user sharing problem? Not a single article/posting mentioned it...but where they referring to a Singleton pattern storing the object instance in the Application context?
I have also seen postings focused on web usage and storing the object instance in the users Session object via the HttpContext object. This makes sense but does not seem to address non-web usage.
I think that whatever solution is appropriate (static methodm, Factory object, etc.) would most likely be implemented in my class library so obviously it needs to support both web and non-web solutions. Maybe check for HttpContext to determine what environment it is running in.
I was hoping http://www.west-wind.com/weblog/posts/2008/Feb/05/Linq-to-SQL-DataContext-Lifetime-Management would be informative but I am having a hard time wrapping my head around the post and the example code seems like overkill for instantiating and sharing a simple object. (Although I am sure I am just not getting it...)
Any thoughts are appreciated.
Thanks.
The issue is not that “many clients would use the same object.” The issue is that the ObjectContext is intended to be a single unit of work. If you use it for many different units of work, you will find that there are a number of problems.
Memory usage will grow and grow.
Your application will become slower as object fixup has to do increasing amounts of work.
Multithreading won't work
The solution is to use the ObjectContext in the manner it is intended, namely, as a single unit of work.
Can anyone explain to me what a singleton object is? In many tutorials I found something like "create a sigleton object". Now I am working in iphone game development using cocos2d. I read "Create a singleton object to keep all the Game Center code in one spot" in raywenderlich multiplayer tutorial, and also he says:
+ (GCHelper *)sharedInstance;
This static method to retrive the singleton instance of this class. But I don't know what a singleton is, or how to use it.
A Singleton object is an object for which there is only a single instance for a given class. The Singleton pattern is used when you want to guarantee that a single instance of a class will be shared across clients in a system.
Check out the C2 wiki page for more information.
Here are some posts with examples of the use of singletons in objective-c:
Using the Singleton Pattern in Objective-C
Singletons: You're doing them wrong
A singleton is an instance of a class that is meant to be the only one of its kind. You usually have a class method that returns a pointer to this single instance or creates it if it didnot exist yet.
Some examples of singletons are:
NSFileManager defaultManager
NSUserDefaults standardUserdefaults
NSCharacterSet whitespaceCharacterset
Singletons are the generally accepted method to hold model data and code in a central place that you can access from everwhere in your other code. All you need to do is to add the header and get the singleton pointer via class method.
See here for a comparison of singleton versus global variables: http://www.cocoanetics.com/2009/05/the-death-of-global-variables/
Singleton object means there is only one object throughout your application. If you used any properties in a singleton class and you access this property using object of this class, which is also called singleton object, you will get the same value in you whole application until you change it manually. This concept is generally used to maintain some fix values that your application required like if your application has login process than may be you required logged in username to be carried in your application for use at any point of application.
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.
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.