Intereting Posts
приложение разбилось, когда я нажимаю новый контроллер представления на self.navigation controller UITableView с карточными картами и списком внутри – iOS Swift Преобразование AutoLayout CALayer Сделайте палку UIView в нижней части рамки ViewController в Swift iOS kAudioSessionProperty_AudioRouteИзмените не все обнаруженные устройства Bluetooth iOS: Firebase приглашает по электронной почте не работает Операция iTunes Store завершилась неудачей при загрузке приложения внутри Xcode Описание Слишком длинная длина Приложение ios отклонено, поскольку не разрешено использовать оборудование MFi Параметры камеры iPhone и редактирования фотографий – интеграция в пользовательское приложение Видео iOS 360 с использованием OpenGL ES 2.0 NSBatchUpdateRequest вызывает ошибку в Swift Для IOS, как использовать vImage для преобразования изображения ARGB в серое изображение Пользовательский UISegmentedControl в раскадровке Использование SWRevealViewController, если я прокручиваю всего 10% влево, тогда левое изображение отображает 90%, а переднее изображение отображает 10% Введите цепочку байтов между Objective-C и Swift

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 секунд) и сделать что вам нужно сделать, прежде чем закончить задачу и вернуться спать.