Подтвердить что ты не робот

Мониторинг iOS Geofence CLCircularRegion. locationManager: didExitRegion не работает должным образом

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

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

Код, который я использую для отслеживания местоположений, выглядит следующим образом:

self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;

// Set-up a region
CLLocationDegrees latitude = 52.64915;
CLLocationDegrees longitude = -1.1506367;
CLLocationCoordinate2D centerCoordinate = CLLocationCoordinate2DMake(latitude, longitude);

CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:centerCoordinate
                                                                 radius:10 // Metres
                                                             identifier:@"testLocation"];

[self.locationManager startMonitoringForRegion:region];

Я не поставил здесь код для области DidEnter и т.д., как я знаю, это работает, когда я перехожу на 100 м от контролируемого региона.

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

Example Region

Кто-нибудь знает, есть ли ограничение с минимальным радиусом зоны вообще или, возможно, я что-то делаю неправильно.

Спасибо Аарон

4b9b3361

Ответ 1

Я не думаю, что мониторинг области будет хорошо работать для такого небольшого радиуса.

  • Наилучшая точность с чипом GPS и kCLLocationAccuracyBestForNavigation часто составляет всего 10 метров.
  • Apple говорит (в Location and Maps PG), что минимальное расстояние для регионов должно быть 200 м
  • Я слышал, что мониторинг региона использует Wi-Fi, чтобы получить его положение (что имеет смысл для экономии энергии). Точность WiFi больше похожа на 20м-100м. Я не уверен, что использование другого приложения с использованием фонового местоположения (то есть с использованием GPS) повлияет на это. Вероятно, менеджер местоположения будет делиться информацией, чтобы повысить точность.
  • Мониторинг региона может занять 30 секунд, чтобы один раз выстрелить внутри региона, и через пару минут после того, как вы покинули регион (чтобы предотвратить сбои локализации от него).
  • Когда региональный мониторинг был впервые представлен, они заявили, что он будет работать только с 100-метровыми регионами, и что-нибудь меньшее будет набито. Вероятно, это происходит.
  • Существует устаревший метод startMonitoringForRegion:desiredAccuracy:, который позволяет указать расстояние до границы региона, чтобы начать генерировать уведомления. Предположительно эта функция была перенесена в startMonitoringForRegion:, но все еще там. Область 10 м может содержать 10-миллиметровый буфер.
  • Если вы хотите это сделать, укажите большую область вокруг, где вы хотите контролировать, и когда устройство просыпается в этом регионе, начните обновление местоположения фона (GPS) и используйте CLCircularRegion -containsCoordinate: для запуска, когда устройство находится в пределах 10 м вручную. Этот метод официально санкционирован Apple (см. WWDC 2013 Сессия 307).

Из CLCircularRegion docs:

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

Из Location and Maps PG:

События региона могут не произойти сразу после пересечения границы области. Чтобы предотвратить ложные уведомления, iOS не предоставляет уведомлений региона до тех пор, пока не будут выполнены определенные пороговые условия. В частности, местоположение пользователя должно пересекать границу региона, удаляться от границы на минимальное расстояние и оставаться на этом минимальном расстоянии в течение как минимум 20 секунд до того, как будут отправлены уведомления.
Определенные пороговые расстояния определяются аппаратными средствами и технологиями местоположения, которые в настоящее время доступны. Например, если Wi-Fi отключен, мониторинг области значительно менее точен. Однако для целей тестирования вы можете предположить, что минимальное расстояние составляет около 200 метров.

Далее в совок из этот пост Кевина МакМэхона, который попросил инженеров Core Location о мониторинге региона в лаборатории на WWDC 2012. Это информация будет изменена в то же время, но интересна часть о категориях регионов. Здесь отредактировано:

Прекрасная область (0 - 150 м)
 - С полом 100 м этот диапазон категорий составляет 100-150 м.
 - Для регионов этот размер производительности сильно зависит от оборудования, связанного с местоположением
 - Количество времени, которое требуется для определения местоположения ядра и вызова соответствующего метода делегата, составляет примерно 2-3 минуты в среднем после пересечения границы региона.
 - Некоторые разработчики самостоятельно выяснили, что более мелкие регионы будут видеть более быстрые обратные вызовы и будут кластеризовать меньшие регионы для охвата одной большой области для улучшения уведомлений о пересечении регионов.

Ответ 2

Кажется, это ошибка в CLLocationManager. Я провел обширное тестирование с использованием различных конфигураций радиуса области, а locationManager:didExitRegion не срабатывает ожидаемым образом. Это кажется либо довольно неприятной ошибкой, либо мониторинг региона не случается вообще, как предлагает документация. У меня есть тестовая упряжь, доступная всем, кто этого хочет:

http://www.mediafire.com/download/x863zkttltyalk6/LocationTest.zip

Запустите его в симуляторе и запустите тест, выбрав Debug → Location → Freeway Drive в меню iOS simulator. Число, которое вы видите, - это расстояние от центра контролируемого региона. Цвет фона будет зеленым, когда устройство находится в пределах контролируемой области и будет красным, если оно находится за пределами региона. Текст ниже расстояния - это журналы событий.

enter image description here

После запуска приложения вы должны увидеть огонь locationManager:didExitRegion на расстоянии 5319 метров от контролируемого региона. Маршрут будет проходить каждые 37 минут, и вы увидите, что устройство выходит из области всегда на 5319 метров.

Я представил радар с Apple (17064346). Я обновлю этот ответ, когда услышу от них ответ. По крайней мере, тогда у нас будет некоторый вклад от канонического источника.

Вот подробный текст, отправленный Apple:

Используя тестовое приложение на iOS-симуляторе, а также на iPhone 5S, CLLocationManager, похоже, не срабатывает обратные вызовы didExitRegion в ожидаемый путь. Независимо от радиуса круговой области, являющейся контролируемый, обратный вызов не произойдет до порога около 5000 метров.

Шаги по воспроизведению:
1. Запустите приложение в приложении
2. Запустите отслеживание области, выбрав Debug → Location → Freeway Drive в iOS simulator
3. Мониторинг приложения. Большой # указывает расстояние от центра наблюдаемой области.
4. По прошествии примерно 190 секунд и 5300 метров ExExitRegion, наконец, загорится.

Проблема, похоже, не связана с размером региона. В соответствии с Apple docs поддерживаются даже небольшие регионы:

В iOS 6 области с радиусом от 1 до 400 метров работают лучше на iPhone 4S или более поздних устройствах. (В iOS 5 области с радиусом от 1 до 150 метров лучше работают на iPhone 4S и более поздних устройствах.) На этих устройствах приложение может ожидать получить соответствующий регион введенное или выведенное из региона уведомление в течение 3 - 5 минут на средний, если не раньше.

Хотя события региона происходят не мгновенно, они должны происходить довольно быстро. Из Документы Apple:

События региона могут не произойти сразу после того, как граница области скрещены. Чтобы предотвратить ложные уведомления, iOS не предоставляет регион уведомлений до тех пор, пока не будут выполнены определенные пороговые условия. В частности, местоположение пользователей должно пересекать границу области, перемещаться вдали от границы на минимальное расстояние и оставаться на этом минимальное расстояние не менее 20 секунд до того, как уведомления будут сообщается.

Это совсем не то, что я вижу в испытательном ремне. На симуляторе устройство всегда будет находиться на расстоянии более 5000 метров от региона, прежде чем произойдет событие locationManager:didExitRegion.

Ответ 3

Мне нравятся ответы Майкла и Невана. Я хотел бы добавить больше информации из своего личного опыта/мнения в разработке Приложения на основе местоположения на базе iOS с Мониторинг регионов, а также выделить некоторые важные моменты: -

Будьте реалистичны в мониторинге регионов

Мониторинг региона использует глобальную систему позиционирования (GPS), Wi-Fi и другие технологии, чтобы определить, находится ли устройство внутри или за пределами контролируемого региона. Не забывайте, что наша земля составляет 510 квадратных километров, а около 30% - земли (149 миллионов км2). Это огромная территория. Помните недавний MH370 недостающий случай? Наша нынешняя самая передовая технология не могла даже определить предполагаемую область этого недостающего самолета.

Если вы хотите следить за небольшой областью с радиусом 10 метров. Он мог бы работать в очень плотном городе с большим количеством ячеек и Wi-Fi. Но в то же время сигнал может быть заблокирован высотными башнями, что может привести к потере сигнала в течение нескольких секунд/минут, что вызвало задержку доставки уведомления.

Итак, вам действительно нужно рассмотреть приведенную выше информацию, прежде чем решать, насколько большой регион, который вы хотите контролировать. Лично я считаю, что 10-метровый радиус слишком мал.

Будьте реалистичны по количеству контролируемых регионов

Текущая технология Core Location может отслеживать только до максимум 20 регионов в одном приложении. Убедитесь, что контролируемые области не слишком близки друг к другу.

Я лично испытал 3 региона, которые имеют около 100 метров в радиусе, которые находятся примерно в 200 метрах друг от друга. Иногда я могу получать уведомления из всех этих трех регионов, когда я проезжаю через них, но иногда я могу получить уведомление только из первого региона. Что может быть причиной? Я не мог знать. Регионы могут быть слишком близки друг к другу. Или сотовые башни решают, что мое устройство фактически не находится в контролируемой области.

На StackOverFlow был один человек, который хочет контролировать 1800 точек на нашей Земле. Не будьте похожи на него, поскольку он совершенно нереалистичен и, вероятно, не понимает ограничения текущей технологии Core Location. Ссылка: Проверьте, находится ли местоположение пользователя рядом с некоторыми точками

Точная настройка Менеджера местоположений

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

self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.activityType = CLActivityTypeAutomotiveNavigation;

kCLLocationAccuracyBestForNavigation будет потреблять больше заряда аккумулятора с помощью kCLLocationAccuracyBest. Но это будет более точно.

Я обнаружил сбой в мониторинге области в iOS 7, когда одновременно запускаются несколько уведомлений в разных контролируемых регионах. Я нашел решение, чтобы отфильтровать этот глюк. Для получения дополнительной информации посетите: Мониторинг региона Glitch на iOS 7 - Несколько уведомлений в то же время

Не превзойденный амбициозный

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

Я провел некоторое исследование по этому вопросу и выяснил, что некоторые из технологий, которые они используют, недоступны публично. Некоторые из этих компаний в значительной степени финансируются и могут заплатить премию телекоммуникационным компаниям, чтобы получить наилучшую точность местоположения для наилучшего пользовательского опыта. Я не понимаю подробностей о том, как это работает. Я считаю, что большая часть определения местоположения на самом деле находится на конце сервера (back end), а не на мобильном (front end).

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

ПРИМЕЧАНИЕ. Я просто хочу поделиться своими двумя центами. Вышеприведенная информация состоит из моего опыта и личного мнения. Это может быть не на 100% точным, поскольку я все еще изучаю Местоположение ядра и Мониторинг регионов.

Ответ 4

Я согласен с Michael G. Emmons и хочу поделиться своим опытом:

Я проверил свой код с тремя областями, как показано на рисунке ниже:

enter image description here

Объяснение поведения:

  • Мое текущее местоположение - Region-1, и я запускаю мониторинг для вышеуказанного три региона, и позвоните в requestStateForRegion, чтобы определить, есть ли какая-либо область внутри, где я постоянно стоять.
  • Затем я получаю уведомления "Enter" для первых двух областей (регион-1 и область 2), но он должен обнаруживать только область-1.
  • Теперь, когда я вхожу в region-2, я получаю уведомление Enter для региона-3. но я должен получить уведомление для региона-2 здесь.
  • Теперь, когда я снова вхожу в область-1, я получаю событие Exit, запущенное для региона-3, и это продолжается.
  • но я не получаю никаких событий Enter/Exit для первых двух регионов, пока я не перейду как минимум на 7Km-10Km далеко от первых двух регионов.

Ожидаемое поведение:  - Событие Enter/Exit должно срабатывать только тогда, когда я пересекаю границу областей или внутри регионов, а не до 500 метров от региона.

Мое предположение:

  • То, что я заметил после всего эксперимента, когда я звоню "requestStateForRegion" для всех трех регионов,
  • он обнаруживает все области внутри области радиуса 5000 м, вот почему обнаруживает первые две области одновременно (область-1 создает круг радиуса 5000 м, а область-2 входит в свой диапазон, поэтому регион -2 также обнаруживается).
  • и когда пользователь перемещается намного больше, чем 10Km, будут вызываться их события выхода, и когда пользователь вернется в этих регионах, их событие Enter будет запущено. Это тот же случай, который объяснялся выше Aaron Wardle.
  • Регистрируется регион-3, потому что, когда пользователь входит в регион-1, т.е. 8-9 км от региона-3, поэтому для этого выдается событие "Выход", и когда пользователь находится на маршруте для региона-2, здесь, даже когда район-3 находится на расстоянии 5000 метров, он все же обнаруживает область-3 и огонь, Введите событие для региона-3.

Итак, я думаю, что все регионы, расположенные на расстоянии 5000 метров, обнаруживаются, и когда пользователь удаляется на расстоянии 10 км от обнаруженного региона, его событие Exit будет запущено. в противном случае, если пользователь находится внутри диапазона 5 км, он больше никогда не будет называть его "Ввод/Выход".

Пожалуйста, обновите меня, если кто-либо исправил эту проблему, или документы Apple в любом месте по этой проблеме.

Ответ 5

Звуки, как и 1 метр, должны работать (и работать лучше на устройствах iPhone 4S +):

startMonitoringForRegion:

(...)

В iOS 6 области с радиусом от 1 до 400 метров работают лучше на iPhone 4S или более поздних устройствах. (В iOS 5 области с радиусом от 1 до 150 метров работают лучше на устройствах iPhone 4S и более поздних версиях.) На этих устройствах приложение может рассчитывать на получение соответствующего региона, введенного или выведенного из региона, в среднем от 3 до 5 минут, если не раньше.

Ответ 6

Основываясь на ответе @Nevan, в котором указывалось какое-то освещение в WWDC 2013 307 (которое прямо не касалось этого), я придумал разумное решение для получения < 10 м для прибытия в местоположение, хотя я чувствую, что реализация -(void)locationManager:didVisit: может сделать это более консервативным для батареи, но будет обеспечивать менее частые обновления.

Сначала у вас есть области с радиусом 0..150 м и начните мониторинг. На самом деле не имеет значения, поскольку система, похоже, запускает их примерно на 150 ~ 200 м:

_locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self;

CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:CLLocationCoordinate2DMake(location.lat, location.lng) radius:50 identifier:location.name];
[_locationManager startMonitoringForRegion:region];

Затем реализуем

-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
    for (CLCircularRegion *enteredRegion in _locationManager.monitoredRegions.allObjects) {
        if ([enteredRegion.identifier isEqualToString:region.identifier]) {

            self.locationManager.activityType = CLActivityTypeFitness;
            self.locationManager.distanceFilter = 5;
            [self.locationManager startUpdatingLocation];

            break;
        }
    }
}

Система начнет отслеживать и сообщать вашему делегату поток местоположений, даже если ваше приложение приостановлено (необходимо UIBackgroundModes включить элемент массива location).

Чтобы проверить, находится ли одно из этих мест в центре одного из регионов, выполните:

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
    CLLocation *firstLocation = [locations firstObject];
    CGFloat const DESIRED_RADIUS = 10.0;

    CLCircularRegion *circularRegion = [[CLCircularRegion alloc] initWithCenter:firstLocation.coordinate radius:DESIRED_RADIUS identifier:@"radiusCheck"];

    for (CLCircularRegion *enteredRegion in _locationManager.monitoredRegions.allObjects) {
        if ([circularRegion containsCoordinate:enteredRegion.center]) {
            [_locationManager stopUpdatingLocation];
            NSLog(@"You are within %@ of %@, @(DESIRED_RADIUS), enteredRegion.identifier);            
            break;
        } else if ([enteredRegion containsCoordinate:circularRegion.center]) {
            NSLog(@"You are within the region, but not yet %@m from %@", @(DESIRED_RADIUS), enteredRegion.identifier);
        }
    }
}

Вы также захотите реализовать:

-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
    [_locationManager stopUpdatingLocation];
}

Ответ 7

Это больше похоже на важный комментарий. Из Мониторинг регионов и iBeacon

Тестирование поддержки мониторинга регионов iOS Apps

При тестировании кода мониторинга вашего региона в iOS Simulator или на устройства, осознайте, что события в регионе могут не произойти сразу после граница области пересекается. Чтобы предотвратить ложные уведомления, iOS не доставляет уведомления по регионам до определенного порога условия выполнены. В частности, местоположение пользователей должно пересекать границы области, отойти от границы на минимальное расстояние, и остаются на этом минимальном расстоянии не менее 20 секунд до уведомления сообщаются.

Определенные пороговые расстояния определяются аппаратными средствами и которые сейчас доступны. Например, если Wi-Fi отключен, мониторинг региона значительно меньше точный. Однако для целей тестирования вы можете предположить, что минимальное расстояние составляет около 200 метров.

Ответ 8

В последние несколько дней мы тестировали функцию геообработки на моем устройстве iOS 8.1 (iPhone 5S) для разработки приложения iv. Приложение регистрирует несколько регионов для службы iOS gefence. Логика приложения требует, чтобы каждый радиус геозонности составлял от 40 до 80 метров.
Я вижу до сих пор, что в районах с большим количеством ячеек и горячих точек Wifi обнаружение геозонности достаточно хорошо для входа в регионы. То есть, в нижних районах города, в бизнес-зонах и т.д. Обнаружение геозонности работает нормально.

К сожалению, обратное происходит в областях с несколькими башнями сотовой связи и Wi-Fi-сетями. Мой район, например, составляет около 1000 метров ширины и 500 высоты (1KM x 0,5KM), и в нем нет ячеек. Есть несколько сотовых вышек, которые по периметру окружают окрестности. К сожалению, по периметру окрестности служба геологического обнаружения ничего не обнаруживает.

Излишне говорить, что я тестирую Wifi на устройстве.

Когда я тестирую свое приложение на Android: сервис geofencing на Android 4.3, 4.4 и 5.1 работает намного лучше, чем на iOS. Служба геодезирования Android не обнаруживает 100% региональных переходов, однако обнаруживает 50% -90% переходов региона.

Я заключаю следующее: если бы было больше ячеек для мобильных телефонов и горячих точек Wifi, и если бы Apple улучшила сервис geofence, то обнаружение на устройствах iOS было бы так же хорошо, как в Android.

Ответ 9

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

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

Внутри торгового центра или спортивного стадиона он может сделать 10 метров - сотовые башни часто очень близки друг к другу. В региональной области может произойти сбой менее чем на 100 км.

Если вам нужны небольшие области, вам нужно использовать bluetooth вместо ячеек (iBeacons). Если в целевой зоне есть устройство с низкой энергией bluetooth, вы можете установить диапазон очень короткий (сантиметры) или достаточно большой (до 30 метров или около того). Обратите внимание, что все зависит от качества оборудования iBeacon, некоторые из них лучше других.

К сожалению, bluetooth (версия 4.0 или новее) и ячеистые сетевые башни - единственный способ отслеживать местоположения без значительного разряда батареи. Сохранение GPS-функции для проверки на 10-метровой границе приведет к полной разрядке батареи до полной плоской за 2 часа даже при выключенном экране.