2011-01-15 2 views
3

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

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

Благодаря

ответ

6

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

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

+0

У вас есть ссылки для ссылок на синглтон? спасибо – Matt

+0

Я просто сделал быстрый поиск, но не смог найти, где я это читал. Сожалею! Но совершенно разумно, чтобы он был создан только один раз. – donkim

+1

Я также использую singleton для моего менеджера местоположений, так что доступ к его свойствам и, что более важно, методам доступен во всем и в любое время, но также может отслеживать изменения местоположения (или изменения местоположения * доступности *) и отправлять уведомления слушателям ключевых слов, когда происходит изменение. –

4

Если бы я тебя, я бы сделал это так:

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

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

  3. делегат Set CLLocationManager «s быть CalculatingView, который также можно назвать самостоятельно, если эта точка зрения выделяется и инициализируется CLLocationManager указатель.

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

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

  6. Когда делегируют CLLocationManager «s, который CalculatingView получает сообщения, послать сообщение MapView.

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

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

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

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

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

0

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

Короткий пример кода, чтобы положить на ваш взгляд, где вам нужен CLLocationManager

....imports.... 

@implementation YourViewController 

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

@end 

Hop, который помогает.

0

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

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

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

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

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

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

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

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

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

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

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

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

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

+0

Спасибо за ответ здесь, я вижу ваши точки, но Пользователь не является реальной концепцией в моем приложении, поэтому это представляет собой чисто сфабрикованную сущность. Кроме того, если вы добавите соответствующие тонкости, это может быть просто простой реализацией, с или без уведомлений, спасибо за ваш вклад – Matt

1

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

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

Смежные вопросы