Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPhone Core Location architecture - How to use it across multiple Controllers

I need a way to get my user current location.

Since a user has friends, and they have location data as well, I though the right way to go is to put a location field in my core data db, both in Friend and User entities.

Now, here's what I thought:

Have some kind of location manager singelton, that whenever I need the accurate location i tell him to start the CLLocationManager updates. (which my manager is responsible for) The manager will save the location in the user.location field in the Db, and controllers interested in the user.location information will register using KVO to that data. It sounds good to me, besides the fact that I have to access this location singelton from every controller that needs accurate locations(in order to tell him to start generating location, I don't want location updates to be on all the time). Plus I try not to pollute my code with bunch of singelton calls.

I though it may be wiser perhaps to have the location manager as a property inside my User class. (obviously if I have a few Users in memory right now, they will all share the same location manager singelton) I will add another method to the user class and call it "StartGettingLocation" , and now whenever some controller need the current accurate location, he can do one of the following:

  1. If in my controller I have a User object (which was passed along by other UIViewController) , i just call his "StartGettingLocation" method and KVO his location field.
  2. If I don't have a User object in my Controller, I get it from my DB and do as the above.

Does this sound right ?

If so, what I'm not sure of, is if it's possible to add a new member of MyLocationManager to my User class (which is a subclass on managedObject) ? What's the right way to accomplish this ?

Thanks

like image 308
Idan Avatar asked Mar 30 '12 15:03

Idan


2 Answers

We implement our CoreLocationManager as a sharedInstance (singleton) pattern. I'm not sure you want your managed object to own the CoreLocation behavior because it really isn't something specific to a User, but rather a device (i.e., iPhone, iPad).

The CoreLocationManager really shouldn't be updating database records either. Its purpose is to send updated locations. Something else needs to listen for these updates, so you could have that something else implement the CLLocationManagerDelegate, which in turn could update the managed object.

Alternatively, you could have your CoreLocationManager be its own delegate and have a @property on CLLocation. You can use KVO to notify observers that a location has changed as you suggested. I guess that all depends on whether or not a location is only relevant to a user or if a location is something that anything can use.

like image 65
Tim Reddy Avatar answered Sep 28 '22 19:09

Tim Reddy


I typically put my location manager as a property of the app delegate, and then it's very easy to access from anywhere in the app as [[[UIApplication sharedApplication] delegate] myLocationManager]. It's also handy to use a #define in your AppDelegate.h file like...

#define commonLocationManager [[[UIApplication sharedApplication] delegate] myLocationManager]

This way, you just include the app delegate header in any class you need to access the locations from with commonLocationManager.someReallyCoolProperty.

EDIT:

Whenever I need my UI to reflect changes in location, or any other state for that matter, I use key-value observing (KVO).

like image 23
Jeff Wolski Avatar answered Sep 28 '22 20:09

Jeff Wolski