indigo
indigo

Reputation: 85

Separating delegates from ViewController to own classes

I'm pretty new to iOs development and I've become a bit confused how should I separate my code to avoid a huge ViewController.m-file. Currently my main viewcontroller has quite a many delegates:

@interface ViewController : UIViewController <MKMapViewDelegate, HttpClientDelegate, CLLocationManagerDelegate, NSFetchedResultsControllerDelegate>

I would like to reduce the viewController code and I guess I should create separate classes to handle delegate tasks. The problem is that if I for example create singleton class for CLLocationManager and let it implement delegate methods, how do I then communicate with the view controller?

Let's say that my CLLocationManager receives a location update, how do I tell the viewController to make changes to the UI? Should I use NSNotificationCenter to post a notification and then add observer to the view controller? Or is the best way just to let viewController implement all delegate methods as it is now?

Upvotes: 4

Views: 1865

Answers (2)

Caleb
Caleb

Reputation: 125007

Move some of that functionality into your data model.

It's hard to say how you should manage this given the limited information you've provided, but one has to wonder whether a single view controller should really be managing a map view and keeping track of location and managing a HTTP connection and managing a Core Data fetch. Why not move some of that into your model, where it'll be somewhat easier to divide into modules?

Let's say that my CLLocationManager receives a location update, how do I tell the viewController to make changes to the UI? Should I use NSNotificationCenter to post a notification and then add observer to the view controller?

A notification would be a good solution -- it provides a way for the part of your program that manages location (again, this probably belongs in the model) to communicate the change without having to know anything in particular about the parts of the program that care about changes to location. It also allows one-to-many communication -- if you have another view controller that also cares about location, it can observe the same notification.

Or is the best way just to let viewController implement all delegate methods as it is now?

I try to think about dividing responsibilities appropriately more than limiting the size of the code. If you have a class that does one job but needs a lot of code to do it, that's fine. If you have one class that manages many unrelated things, that's not so good. The trouble is that a lot of jobs seem to fall into the traditional "manages a screenful of content" role of a view controller. Try to separate the task of managing the presentation of the data (which is the view controller's rightful job) from managing the data itself (which is the model's job).

Upvotes: 1

Ryan Huang
Ryan Huang

Reputation: 181

Implement a class responsible for delegate methods:

@interface DelegateManager : NSObject <MKMapViewDelegate, HttpClientDelegate, CLLocationManagerDelegate, NSFetchedResultsControllerDelegate>
-(id)initWithViewController:(ViewController*)vc;
@property (weak) ViewController *delegate;
@end

In your ViewController:

@interface ViewController : UIViewController
-(void)doSomething;
@end

In your ViewController, create an instance of DelegateManager with self as parameter. Set all your delegates' target to your DelegateManager. In the delegate methods of your DelegateManager, call [self.delegate doSomething]; to communicate back to your ViewController.

Upvotes: 0

Related Questions