Delegates in Objective-C (iphone development) best practice - iphone

So new to objective-c and iphone/ipad development. Trying to get my feet wet with a simple app to connect to one of our apis.
Right now I have a view with a user name and password input and button to submit. When it's clicked I grab those and try to authenticate against our server with a simple post call. I have that working using the NSURL stuff. I originally had it working by declaring the delegate methods for NSURLConnection in my view controller. Once I confirmed it was working properly I knew I needed to get that stuff out of there.
So I created a new class ApiLogin which has a method:
(void)authenticateWithUser:(NSString *)username andPassword:(NSString *)password
which does the post and then this object has the delegate methods declared and handles all that stuff. The next problem I ran in to was how to get any info back to the view controller. Since these were asynchronous calls I couldn't just have my method return data. So after some digging I tried out a solution that seemed to make sense. I created a custom delegate for my newly created class
(void)loginDidFinish:(NSString *)login
Which my view controller declares and uses. This worked perfectly.
So my question now is... am I going down a rabbit hole or is this good? I don't want to create a suite of classes or a class with children classes to handle server communication and data handling with a dozen of these delegate functions if that's bad form. Basically I'm asking, am I doing this right? Is there a better way? I feel like I've been given a new tool, and I see every problem as a chance to use that tool to solve it and don't want to make that mistake. Since I'm really new to iphone/ipad development and it's been a long time since I've done any serious C coding I feel a bit lost with some of this stuff.

That seems fine to me. The other solutions that come to mind would be to have your view controller observe a model object using Key-Value Observation and update accordingly, or to use an NSNotification when login is complete.

It's perfectly reasonable for your view controller to be the delegate for items it is controlling. I would only break it out and make it it's own class if you needed to use the same methods in several view controllers, and the delegate methods were very complicated.

You may find this link helpful, since it seems to be talking about a similar situation to yours where the author used delegates:
http://css.dzone.com/articles/do-not-publishcreating-your
Also, this Apple page might be a good read as well if you are curious about different ways in which objects can communicate with each other:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/CommunicatingWithObjects/CommunicateWithObjects.html
The best way to be confident that you are using the right strategy, beyond simply asking other people for confirmation, is to make sure you understand the definition and purpose behind delegation, and then analyze your code from that perspective to see if its a good fit for what you are trying to do. Excerpt from Wikipedia:
In software engineering, the
delegation pattern is a design pattern
in object-oriented programming where
an object, instead of performing one
of its stated tasks, delegates that
task to an associated helper object.
( http://en.wikipedia.org/wiki/Delegation_pattern )
Considering all that, I think you're on the right track with what you're currently doing.

Related

MVC in Cocoa Touch

I'm having troubles understanding if I'm properly implementing the MVC pattern in an iPhone app. In my app I have views, view controllers and models. The view controllers manage the interfaces, navigate to other view controllers, set variables to other view controllers and models, and communicate with the models. But this way, am I correctly following the MVC pattern? Don't I miss a model controller?
Another question: I have a User Model that I need to have access to in almost every models and some controllers. Would it be correct to define it as a variable in the appDelegate? I'm all the time reading that this is a bad practice, but I don't see why in this case.
Global objects
All non trivial code has bugs, and they are harder to track if you use dumb global objects. By "dumb" I mean generic objects from the API that lack a single point of access in case you need to log, validate, key-value observe, and notify, changes. You can wrap the global object in a class to route everything through your own accessors.
Some say using globals at all gets you into a bad habit. Others say it depends on the size of your code because it is a trade between development speed and complexity.
The appdelegate is a Singleton, so this discussion is related: What is so bad about singletons? and Singletons: good design or a crutch?.
MVC
Apple talks about it in Cocoa Core Competencies and Cocoa Fundamentals Guide.
One can merge the MVC roles played by
an object, making an object, for
example, fulfill both the controller
and view roles—in which case, it would
be called a view controller. In the
same way, you can also have
model-controller objects. For some
applications, combining roles like
this is an acceptable design.
Is your design complex enough to need a model controller? Whatever your decission is, suffering the consequences will teach you a lot. :)
A design pattern in which the model (any data in your program), the view (what the user sees), and the controller (a layer that handles all interaction between the view and model) are separated in such a manner that modifying either the view or model component of your program has no effect on one another.
The purpose:
The purpose is that later on you may need to change your programs view, and by programming things in this matter you will not have to modify your programs model. Say for instance Apple comes out with an iPad for which the view is programmed somewhat differently than on the iPhone, but you would like to
Now I received some messages after making the video above, some thanking me for making the concept of MVC sound so simple, and others telling me that I had confused them, and wondering how I could understand any of this stuff.
Well, don’t fret.. I’ve seen arguments all over the place as to what components should be classified in the model, the view, or the controller, and I’ve even seen accomplished "guru authors" mess things up when explaining what goes where, just keep in mind that the key idea here is that you can modify one of these key areas without completely wrecking another key area of your program, and leave the rants to the wannabe coders who like to argue about what exactly what fits what acronym, and MVC is often their target.

Alternative to Singleton in Objective-C for better application design

It seems a lot of Objective-C code is using Singleton nowadays.
While a lot of people complaining about Singleton, e.g. Google (Where Have All the Singletons Gone?), their fellow engineers also use it anyway: http://code.google.com/mobile/analytics/docs/iphone/
I know we had some answers in Stack Overflow already but they are not totally specific to Objective-C as a dynamic language: Objective C has categories, while many other languages do not.
So what is your opinion? Do you still use Singleton? If so, how do you make your app more testable?
Updated: I think we need to use codes as example for more concrete discussion, so much discussions on SO are theory based without a single line of code
Let's use the Google Analytics iOS SDK as an example:
// Initialization
[[GANTracker sharedTracker] startTrackerWithAccountID:#"UA-0000000-1"
dispatchPeriod:kGANDispatchPeriodSec
delegate:nil];
// Track page view
[[GANTracker sharedTracker] trackPageview:#"/app_entry_point"
withError:&error];
The beauty of the above code is once you have initialized using the method "startTrackerWithAccountID", you can run method "trackPageview" throughout out your apps without passing through configurations.
If you think Singleton is bad, can you improve the above code?
Much thanked for your input, have a happy Friday.
This post is likely to be downvote-bait, but I don't really understand why singletons get no love. They're perfectly valid, you just have to understand what they're useful for.
In iOS development, you have one and only one instance of the application you currently are. You're only one application, right? You're not two or zero applications, are you? So the framework provides you with a UIApplication singleton through which to get at application-level os and framework features. It models something appropriately to have that be a singleton.
If you've got data fields of which there can and should be only one, and you need to get to them from all over the place in your app, there's totally nothing wrong with modeling that as a singleton too. Creating a singleton as a globals bucket is probably a misuse of the pattern, and I think that's probably what most people object to about them. But if you're modeling something that has "singleness" to it, a singleton might well be the way to go.
Some developers seem to have a fundamental disgust for singletons, but when actually asked why, they mumble something about globals and namespaces and aesthetics. Which I guess I can understand, if you've really resolved once and for all that Singletons are an anti-pattern and to be abhorred in all cases. But you're not thinking anymore, at that point. And the framework design disagrees with you.
I think most developers go through the Singleton phase, where you have everything you need at your fingertips, in a bunch of wonderful Singletons.
Then you discover that unit testing with Singletons can be difficult. You don't actually want to connect to the database, but your Singleton does. Add a layer of redirection and mock it.
Then you discover that unit testing isn't the only time you need different behaviour. You make your Singleton configurable to have different behaviour based on a parameter. You start to wonder if you need to split it into two Singletons. Then your code needs to know which Singleton to use, so you need a Singleton that knows which Singleton to use.
Then some other code starts messing with the values in your Singleton, while you're using it. How dare they! If you wanted just anybody to get at those values from anywhere, you'd make them global...
Once you get to this point, you start wondering if Singletons were the right solution. You start to see the dangers of global data, particularly within an OO design, where you just assume your data won't get poked at by other people.
So you go back and start passing the data along, rather than looking it up (this used to be called good OO design, but now it has a fancy name like "Dependency Injection").
Eventually you learn that Singletons are fine in moderation. You learn to recognize when your Singleton needs to stop being single.
So you get shared objects like UIApplication and NSUserDefaults. Those are good uses of Singletons.
I got burned enough in the Java Singleton craze a decade ago. I don't even consider writing my own Singletons. The only time I've needed anything similar in recent memory is wanting to cache the result of [NSCalendar currentCalendar] (which takes a long time). I created a category on NSCalendar and cached it as a static variable. I felt a bit dirty, but the alternative was painfully slow code.
To summarize and for those who tl;dr:
Singletons are a tool. They're not likely to be the right tool, but you have to discover that for yourself.
Why do you need an answer that is "total Objective C specific"? Singletons aren't totally Obj-C specific either, and you're able to use those. Functions aren't Obj-C-specific, integers aren't Obj-C specific, and yet you're able to use all of those in your Obj-C code.
The obvious replacements for a singleton work in any language.
A singleton is a badly-designed global.
So the simplest replacement is to just make it a regular global, without the silly "one instance only" restriction.
A more thorough solution is, instead of having a globally accessible object at all, pass it as a parameter to the functions that need it.
And finally, you can go for a hybrid solution using a Dependency Injection framework.
The problem with singletons is that they can lead to tight coupling. Let's say you're building an airline booking system: your booking controller might use an
id<FlightsClient>
A common way to obtain it within the controller would be as follows:
_flightsClient = [FlightsClient sharedInstance];
Drawbacks:
It becomes difficult to test a class in isolation.
If you want to change the flight client for another implementation, its necessary to search through the application and swap it out one by one.
If there's a case where the application should use a different implementation (eg OnlineFlightClient, OfflineFlightClient), things get tricky.
A good workaround is to apply the dependency injection design pattern.
Think of dependency injectionas telling an architectural story. When the key actors in your application are pulled up into an assembly, then the application’s configuration is correctly modularized (removing duplication). Having created this script, its now easy to reconfigure or swap one actor for another.”. In this way we need not understand all of a problem at once, its easy to evolve our app’s design as the requirements evolve.
Here's a dependency injection library: https://github.com/typhoon-framework/Typhoon

reachability and singleton

How can I make the reachability work as a singleton?
Here is what I want to do ...
I have an application.
When it launches I want to have a singleton and work with the reachability in order to hold the network status.
Then I want from other controllers to access the singleton and check the network status.
For example I want every time user clicks on one tab and the screen is shown to check the internet status and enable or disable a button.
I know the question is very generic but I am so confused.
I am currently using reachability 2.2
Any tips or ideas or even guides will be appreciated.
And a final question....
how 'moral' is the singleton usage? And is it the best practice to be more close to MVC model?
Thanks again
Singletons are fine. Reachability can be a very sensible singleton. You should be aware of the doc "Creating a Singleton Instance" in Apple's Cocoa Fundamentals Guide, but read the text carefully. The code they present is seldom what you need and can cause more problems then it solves. It is only appropriate in cases where it is wrong for there to be multiple copies of the object (wrong because the object manages a unique resource for instance). In those cases, I tend to prefer asserting in -init rather than overloading allocWithZone: because I'd rather force the developer to make the correct call (+sharedInstance) rather than quietly fix it for them, and have them think they've created two instances when there is actually one (at least in cases where the singleton is mutable or holds state).
There is an excellent discussion of good singleton patterns in this question. I favor #Robbie Hanson's answer in my own code because it is cheaply thread-safe.

Where to put common code for iPhone, CLLocationManager

If I have a tab bar app, and plan on using Core Location in different tabs, is there a good common place to put the code used to alloc/init the CLLocationManager, and get the updates once startUpdatingLocation is called? Or if it's going to be used in two different tabs, do I then just put it in the code for each tab? Just wondering what best practices are since I am new to programming. Thanks.
I don't agree with John, the AppDelegate is the "easy" way to do it, but not always the better.
I would do this with a singleton. You can look at Matt Gallagher's article on Singletons, AppDelegates and top-level data for reference.
if you notice you're duplicating what you've written, or faced with writing code which exists, consider creating an interface (object, set functions, etc.) to handle these tasks.
see DRY (do not repeat yourself). there will be a lot of duplicate functionality by the time you've written a few apps. it's best to write it once, and to write that correctly.
here are some high level guidelines:
don't put app-specific features in a common interface (instead, use a subclass shared by the 2 projects)
always keep your bases free of hacks (unless you're dealing with an issue in the system libraries). if clients (e.g., subclasses, callers) need a particular workaround or require a specific check, then it is better to make them handle it.
use assertions to ensure they use the interface as intended, check every argument, precondition/postcondition, the state of your object, etc..
keep your objects/interfaces very small and maintainable, with a clear purpose of their intended use. naturally, this will result in a higher number of objects.
avoid the urge to use singletons and static data; there's almost always a better way even if it's as simple as forcing clients to create an instance of your class.
create libraries with these interfaces, and divide them logically.
now that that's covered…
i'd begin by using (potentially multiple) instances of the objects you'll need. there is nothing in the documentation that states "you should not create multiple instances of the object".
if this is somehow inadequate in profiling, then consider using a shared object which relays messages to the objects (in your app) which need updates.
rationale: chances are, apple's already optimized the implementation, so you don't have to.
finally, i broke these guidelines in an app which required a ton of location requests, and displayed a ton of location information. the app used some static data behind an interface which stored the location manager and the location (among other things). so i ended up using static data with private (hidden) static data to reduce the memory and cpu demands in this case.
The App Delegate is a good, central place for such data. You can always get to the app delegate with [[UIApplication sharedApplication] delegate]

iOS Application partitioning / MVC

I've been playing around with iOS development and I'm getting to the stage where I want to create something beyond a simple app. However, I'm not confident that I understand how to partition an application correctly.
For the purposes of simplicity, imagine a (very) simple audio player application. Let's say there are two view controllers, accessible via a UITabBarController which is instantiated the main AppDelegate class.
Each of these view controllers has the following responsibility:
PlayerViewController - A sound player which plays the “current” audio sample when the user presses a button.
SelectorViewController - A sample selector, that uses a UIPickerView to display the available audio samples so that the user can select which sample they want to play.
So far, so good. However, what I don't quite understand is where I should store the data on the available samples, so that both of the views can find out information on the available samples, trigger a sample to play, etc.
As both view controllers need to access this “model level” information, would creating an “audio manager” singleton class be a sensible approach, or is there (much, much more likely I'm guessing) a better means of solving this problem that I'm overlooking.
Any pointers would be much appreciated.
I've used this pattern (Singleton data manager) several times in serious apps. It's quite straightforward, easy to understand, easy to use, although this pattern is despised by OOP purists.
If nobody tells you it's wrong to use a singleton, go ahead, just be sure to check Apple's documentation on the recommended implementation (there is a bunch of methods to overload).
Oh and BTW, Apple uses it a lot in the iOS SDK, so it's a common practice (see class methods beginning with 'shared').
UPDATE:
Another possibility is reusing an already existing singleton, the Application delegate for instance. It might feel cleaner, or not, it's more a matter of taste. It has the advantage of giving a clear "entry point" where you allocate/create/init your data manager.
If the source of your data is in a remote server and it comes to your app as an XML file, you can also get it whenever you want with a kind of source downloader class.
That way you don't have to care about keeping things in memory when they are not necessary. Just get it from the remote source, parse it and then release it.
Another way of achieving this more careful use of memory is to get your data from a sqlite database using Core Data. But some people thinks it is too much complicated for a simple app and prefer running queries by hand.