лучший способ использовать CoreLocation для нескольких представлений - PullRequest
3 голосов
/ 16 января 2011

У меня есть два представления в моем приложении, одно - это общий вид, в котором CoreLocation отрабатывает вычисление местоположения пользователя, пока пользователь выполняет другие действия в представлении. Пользователь получает доступ ко второму виду, когда он касается кнопки, позволяющей ему более точно определить свое местоположение с помощью mapview и MapKit. Мне бы хотелось, чтобы представление map в этом представлении показывало местоположение, которое CoreLocation уже определило в первом представлении, и продолжало отображение этого местоположения на основе обновлений из CoreLocation в другом представлении.

Является ли лучший способ здесь создать синглтон, который инкапсулирует содержимое CoreLocation и имеет на него ссылку в представлении с картой, или использовать уведомления? или использовать другую лучшую практику для моего сценария?

Спасибо

Ответы [ 5 ]

6 голосов
/ 16 января 2011

У меня есть пара приложений, которые используют CoreLocation в нескольких местах. Из того, что я прочитал, вы определенно хотите, чтобы был только один экземпляр CLLocationManager Он отлично работал как синглтон для меня.

Надеюсь, это поможет!

4 голосов
/ 16 января 2011

На вашем месте я бы сделал это так:

  1. Решите, какой вид будет загружен всегда.Я предполагаю, что вы хотите, чтобы CalculatingView загружался все время, а MapView будет загружаться / выгружаться в зависимости от действия пользователя.

  2. Allocateи инициализировать указатель на CLLocationManager внутри CalculatingView .Это обеспечит свойство местоположения, а также вызовет сообщения делегата.Поскольку CalculatingView загружается и сохраняется, этот указатель также всегда работает.

  3. Установите для CLLocationManager делегат равным CalculatingView, который также можно назвать self , если это представление выделило и инициализировало указатель CLLocationManager .

  4. Реализация методов делегата CLLocationManager , в CalculatingView

  5. Если вы хотите, вы можете иметь MapView для выделения и инициализации в CalculatingView .Но в других местах это нормально, если вы можете отправить сообщение на MapView .Убедитесь, что они действительны, проверив, не является ли он nil или responsedsToSelector .

  6. Когда CLLocationManager 's делегат, который CalculatingView принимает сообщения, отправляет сообщение на MapView .

  7. Это похоже на ретрансляцию сообщений, но сообщения, которые MapView должен отвечать, чтобы не быть теми же сообщениями, отправленными на CalculatingView , как вызовы методов делегата из CLLocationManager

  8. Проверяя, действительно ли MapView , то есть, если он загружен для отображения, вы можете решить отправлять сообщения на MapView или нет

Суть состоит в том, чтобы решить, какое представление загружается последовательно, использовать методы делегата для отправки (или ретрансляции) сообщений на другие указатели (в данном случае указатель MapView ).

Синглтон хорош,но если вы не собираетесь использовать CLLocationManager изнесколько мест, например более 3 ~ 4 мест, это не так уж и нужно, я думаю

Надеюсь, я вас не запуталИсходя из того, что вы опубликовали, кажется, что этот способ может быть простым решением для вашей цели.Если я не уловил ваше истинное намерение, пожалуйста, дайте мне знать.

1 голос
/ 01 сентября 2011

Я не уверен, что это лучший способ, но я настраивал свой основной контроллер (тот, который загружается первым) как делегат менеджера местоположения. Когда местоположение обновляется, оно запускает уведомление с новым местоположением в качестве объекта уведомления. Любые прослушивающие контроллеры могут затем использовать эти данные так, как им нужно.

Кроме того, приложение Apple LocateMe трижды создает экземпляр менеджера местоположений. Таким образом, в их примере наличие нескольких LocationManager'ов может не быть проблемой.

0 голосов
/ 16 января 2011

Возможно, вам следует рассмотреть MVC-ориентированный подход. Из вашего описания вам не хватает представления слоя модели вашего пользователя. Первым шагом будет определение простого класса User с базовым свойством CLLocation.

@interface User {}
@property (nonatomic, retain) CLLocation *location;
@end

@implementation User
@synthesize location;
- (void)dealloc {
  self.location = nil;
  [super dealloc];
}
@end

Тот же экземпляр User будет передан вашему контроллеру представления. Может быть создан в приложении делегатом.

Далее создайте объект служб определения местоположения для вашего приложения. Он запустит CLLocationManager и предоставит местоположение вашему пользователю. Возможно, вам придется установить точность GPS, игнорировать ненужные кадры и реализовать базовую логику LBS.

На данный момент у вас есть полнофункциональное приложение без какого-либо пользовательского интерфейса. Это хороший дизайн с точки зрения возможности повторного использования и тестирования.

Теперь поместите ваш интерфейс поверх этого. Дайте вашему корневому контроллеру указатель на экземпляр User в вашем делегате приложения. Ваш контроллер представления передает этот указатель контроллерам модального / навигационного представления, которые он создает.

Этот контроллер начинает наблюдать изменения местоположения пользователя в их viewDidLoad и реагирует соответствующим образом.

- (void)viewDidLoad {
   [self observeValueForKeyPath:@"location" ofObject:self.user change:0 context:NULL];
}

Ваш контроллер представления также будет регистрироваться для уведомления, генерируемого объектами служб определения местоположения, для отображения предупреждения пользователю.

На основании других ответов:

  • Нет реального наказания за создание нескольких экземпляров CLLocationManager в вашем коде. Единственным побочным эффектом является то, что API-интерфейс является асинхронным, поэтому вам нужно подождать, чтобы получить правильное местоположение в вашем контроллере представления. Вы можете попытаться получить текущее местоположение из диспетчера местоположений на вашем viewDidLoad с помощью API locationManager.location.
  • не делитесь информацией от вашего делегата приложения. Это предотвращает повторное использование кода. Что если вы повторно используете свои представления, а у делегата приложения нет менеджера местоположений?

если вам нужно больше кода, пожалуйста, спросите.

0 голосов
/ 16 января 2011

Из того, что я прочитал, лучше всего добавить CLLocationManager к вашему App Delegate, поскольку вы можете получить к нему доступ из любого представления.

Краткий пример кода для представления в вашем месте, где вам нужен CLLocationManager

....imports....

@implementation YourViewController

- (void)viewDidLoad {
   self.myLocationManager = [[UIApplication sharedApplication] delegate].yourLocationManagerVarName;
}

@end

Хмель, который помогает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...