Использование нового CLVisit в CoreLocation

#swift #core-location #ios8

#swift #расположение ядра #ios8

Вопрос:

Я не нашел ничего, что говорило бы о CLVisit, поэтому я пытаюсь самостоятельно изучить технологию.

Кто-нибудь знает, почему это не работает? Все ключи .plist установлены и работают.

 class ViewController: UIViewController,CLLocationManagerDelegate {

var manager:CLLocationManager!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    manager = CLLocationManager()
    manager.delegate = self
    manager.desiredAccuracy = kCLLocationAccuracyBest
    manager.requestAlwaysAuthorization()
    manager.startMonitoringVisits()


}


func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {

}
func locationManager(manager: CLLocationManager!,
    didVisit visit: CLVisit!)
{
    println("visit: (visit.coordinate.latitude),(visit.coordinate.longitude)")
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


}
  

Ответ №1:

Ваш код выглядит правильно. Я также обнаружил, что CLVisit работает не так, как я это понимал. Это сложно отлаживать, потому что вам нужно фактически покинуть свое рабочее пространство, чтобы протестировать его. 🙂

Эвристика, которую CLVisit использует для определения «посещения», не документирована, но, согласно видеоролику WWDC, вам нужно остаться на неопределенное время, прежде чем CLVisit решит, что вы посещаете, а не просто проходите мимо. У меня был очень ограниченный успех в получении обратного вызова делегата. Однажды посещение ArrivalDate было запущено примерно через две минуты в местоположении, другое — примерно через десять минут, но в большинстве случаев посещение никогда не срабатывает.

NSLog не работает для отслеживания CLVisits, если вы отсутствуете, поэтому я настроил простой объект Core Data и регистрирую все посещения:

     Visits *thisVisit = [NSEntityDescription insertNewObjectForEntityForName:@"Visits" inManagedObjectContext:[self managedObjectContext]];
    thisVisit.arrivalDate = visit.arrivalDate;
    thisVisit.departureDate = visit.departureDate;
    thisVisit.latitude = [NSNumber numberWithDouble:visit.coordinate.latitude];
    thisVisit.longitude = [NSNumber numberWithDouble:visit.coordinate.longitude];
    [self saveContext];
  

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

РЕДАКТИРОВАТЬ: вот полный пример. Установите и используйте его в течение нескольких дней, и вы увидите проблемы с этим новым API. Я надеюсь, что это будет работать лучше в более поздних бета-версиях. Для меня это все еще довольно непоследовательно — иногда два прибытия подряд, иногда два вылета подряд, длительные задержки перед запуском visit…

https://github.com/steveschauer/TestCLVisit

Комментарии:

1. Итак, CLVisit довольно глючный, и нам следует дождаться третьей бета-версии… Я оставался в двух местах более 1 часа, и ничего не было отмечено (я использовал NSUserDefaults для хранения посещений.

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

Ответ №2:

Я предполагаю, что вы пытаетесь получить эти вызовы делегатов, пока приложение работает в фоновом режиме; однако вы создаете экземпляр CLLocationManager в контроллере представления, который не будет создан (afaik).

Это работает для меня (я использую iOS 8, бета-версию 2, на iPad mini 2-го поколения): установите NSLocationAlwaysUsageDescription ключ, включите фоновый режим «Обновления местоположения» в разделе «Возможности» и включите следующее в AppDelegate :

 let locationManager = CLLocationManager()

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
    locationManager.delegate = self
    locationManager.requestAlwaysAuthorization()
    locationManager.startMonitoringVisits()

    return true
}

func locationManager(manager: CLLocationManager!, didVisit visit: CLVisit!) {
    println("Visit: (visit)")
    // I find that sending this to a UILocalNotification is handy for debugging
}
  

Обновление: я выдвинул пример приложения, которое работает для https://github.com/mloughran/CLVisit-POC .

Комментарии:

1. Сработало для меня на устройстве. Я не знаю, как можно было бы протестировать это в симуляторе tbh.

2. хорошо, не могу заставить CLLocationManager работать для меня на устройстве бета-версии 2. Перепробовал все предложения. Считайте, что вам повезло 😉

3. Я добавил демонстрационное приложение — может быть, посмотрите, работает ли это для вас?

4. Было бы неплохо, если бы Apple предоставила нам способ имитации CLVisits, чтобы мы могли протестировать это, не разъезжая по городу. У кого-нибудь есть идеи по имитации этих посещений?

5. Я думал об использовании файла GPX.. но не знаю, как аппаратное обеспечение выберет посещение. Какое-либо определенное количество времени требуется для того, чтобы посещение было квалифицировано как CLVisit? @mloughran пожалуйста, пролейте немного света на это. Когда вы тестировали проект github, на сколько времени вы останавливались в определенном месте? Также это работает, когда приложение убито??

Ответ №3:

Я начинаю думать, что в этом API есть серверный компонент. Мое тестовое приложение настроено в AppDelegate, и без изменений кода оно начало периодически отключать посещения только в течение последних нескольких дней. Но он пропускает некоторые и, кажется, создает другие.

Вот последние два посещения, записанные моим приложением. Эти точки по существу одинаковы (примерно в 30 футах друг от друга). Я думаю, что первое прибытие является точным, а отправление — нет. Прибытие второго визита абсолютно не произошло. В течение этого времени мое тестовое устройство не выходило из дома.

широта: xx.11852879438132 долгота: -xxx.7792256808099 Дата прибытия: 2014-06-25 12:19 ВЕЧЕРА Дата отправления: 2014-06-25 4:44 вечера

широта: xx.1185726857039 долгота: -xxx.7793685278068 Дата прибытия: 2014-06-26 5:59 Дата отправления: отдаленное будущее

Раньше я вынимал его и примерно несколько раз, и только изредка заходил на огонь.