Intereting Posts
Как сохранить только изображение в представлении изображения? Как я могу узнать, какой цикл запуска имеет определенный NSTimer, если он был создан с помощью schedTimerWithTimeInterval? Невозможно присвоить себя как делегата в инициализаторе свойств Как получить XCode для удаления приложения из симулятора при выполнении чистой сборки? Почему я не могу пройти аутентификацию в чате Facebook в приложении iOS? Перемещение UIButton по оси Y при использовании Autolayout Приложение iOS только начинается с огромных задержек после события геопозиции Obj-C, iOS, как мне форматировать UITextField для международной валюты? Пользовательский UIView в UIScrollView drawRect никогда не вызывал Как получить UIManagedDocument для отображения в виде файла, а не папки Skobbler (GPS-навигация) не открывается в указанном месте нет правила для обработки XMPPFramework module.modulemap Как узнать, была ли нажата текущая выбранная вкладка? Как правильно показать TXT или ASCII-файл в UIWebView Нераспределенная собственность освобождается

IOS – Интервал обновления местоположения

Я начинаю разработку IOS, и я очень незнакомый с этим языком.

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

-(void)CurrentLocationIdentifier { locationManager = [CLLocationManager new]; locationManager.delegate = self; locationManager.distanceFilter = kCLDistanceFilterNone; locationManager.desiredAccuracy = kCLLocationAccuracyBest; [locationManager startUpdatingLocation]; } - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { NSLog(@"%@", newLocation); } - (void)applicationDidEnterBackground:(UIApplication *)application { [self CurrentLocationIdentifier]; } 

Оно работает. Поскольку я настроил файл .plist, он зарегистрирован для работы на фоновом режиме, он регистрирует местоположение бесконечно.

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

Я попытался остановить обновление и запланировать запуск с помощью NSTimer в приемнике обновления местоположения:

 - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { NSLog(@"%@", newLocation); [locationManager stopUpdatingLocation]; NSTimer *timer; timer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(CurrentLocationIdentifier) userInfo:nil repeats:NO]; } 

Где CurrentLocationIdentifier – это метод, который снова запрашивает начальное обновление.

Но он работает в первый раз, а затем не запускает запланированную задачу! Что я делаю не так? Должно ли это быть сделано другим способом?

Если вам не нужны подробные обновления местоположения в фоновом режиме, то важная услуга обновления местоположения , вероятно, лучший подход.

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ... // Any other initialisation you already have locationManager = [CLLocationManager new]; locationManager.delegate = self; locationManager.distanceFilter = kCLDistanceFilterNone; locationManager.desiredAccuracy = kCLLocationAccuracyBest; [locationManager startUpdatingLocation]; } - (void)applicationDidEnterBackground:(UIApplication *)application { if ([CLLocationManager significantLocationChangeMonitoringAvailable] { [locationManager stopUpdatingLocation]; [locationManager startMonitoringSignificantLocationChanges]; } else { //Decide what you want do to if it isn't available } } - (void)applicationDidEnterForeground:(UIApplication *)application { [locationManager startUpdatingLocation]; [locationManager stopMonitoringSignificantLocationChanges]; } 

Кстати, метод делегата, который вы используете, locationManager:didUpdateToLocation:fromLocation: устарел, и вы должны использовать locationManager:didUpdateLocations:

ОБНОВЛЕНИЕ Значительное изменение местоположения недоступно на всех устройствах, поэтому я добавил чек в свой код. Вам нужно решить, какой подход взять на устройстве, где он недоступен, – придерживаться стандартных обновлений, возможно, увеличивая distanceFilter

У меня есть проект Github, https://github.com/dsdavids/TTLocationHandler , который вы можете скачать и поиграть. TTLocationHandler – это снижение класса, которое вы можете установить так, как хотите получить результаты, на которые указывали другие. Я сделал это, когда я был в вашей ситуации, пытаясь понять, как использовать службы местоположения в фоновом режиме.

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

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

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

Что касается периодического получения обновлений местоположения (в зависимости от времени, а не расстояния), то лучше всего использовать API многозадачности iOS для выполнения performFetchWithCompletionHandler , что в двух словах позволяет ОС разбудить вас, когда он определит, что у вас есть время для обработки. У вас будет около 30 секунд времени на стене, чтобы справиться с тем, что вы хотите, и снова заснуть.

https://developer.apple.com/library/ios/documentation/uikit/reference/uiapplicationdelegate_protocol/index.html#//apple_ref/occ/intfm/UIApplicationDelegate/application:performFetchWithCompletionHandler :

Чтобы получить эту настройку, необходимо выполнить несколько шагов, но это довольно легко и должно указывать на вас в правильном направлении. Обратите внимание, что это не позволит вам планировать эти события всякий раз, когда вы хотите, вы действительно ограничены ОС и алгоритмом, который он использует, чтобы определить, как часто вам разрешено выполнять фоновые выборки. Если вы занимаете много времени и используете много батареек, вы получите менее частые выборки, и если вы займете слишком много времени и никогда не закончите, вы будете прекращены. Быть «ответственным» в фоновом режиме заканчивается тем, что ОС дает вам больше времени.

По моему опыту, будучи как можно более «ответственным», выполняя обновления местоположения и отправляя запросы на сервер, фоновые снимки происходят прибл. От 15 до 30 минут.

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