Книга: iOS. Приемы программирования

Обсуждение

Обсуждение

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

Если для работы приложения вам необходима возможность получать информацию об изменении местоположения пользовательского устройства, даже если программа работает в фоновом режиме, то нужно добавить значение location к ключу UIBackgroundModes в основной файл. plist вашего приложения, как показано в подразделе «Решение» данного раздела. В таком случае, даже будучи в фоновом режиме, ваше приложение продолжит получать информацию об изменении местоположения устройства. Протестируем простое приложение, в котором у нас будет только делегат.

В этом приложении я собираюсь сохранить логическое значение в делегате приложения, которое будет называться executingInBackground. Когда приложение переходит в фоновый режим, задам этому делегату значение YES, а когда оно вернется в приоритетный режим — изменю данное значение на NO. Когда будут получены данные об изменении геолокационной информации от Core Location, мы проверим этот флаг. Если флаг установлен в YES, то мы не будем заниматься никакими энергоемкими вычислениями или любыми обновлениями пользовательского интерфейса, поскольку наше приложение сейчас работает в фоновом режиме. Мы, будучи ответственными программистами, не будем нагружать приложение никакими тяжелыми задачами. Но если программа действует в приоритетном режиме, то в нашем распоряжении вся вычислительная мощность устройства, которую мы можем бросить на обработку необходимых функций. Кроме того, попытаемся добиться максимальной точности при определении местоположения, если наша программа работает в приоритетном режиме. Когда же программа уходит в фоновый режим, эту точность можно смело снизить, чтобы уменьшить нагрузку на геолокационные сенсоры. Итак, определим делегат приложения:

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
@interface AppDelegate () <CLLocationManagerDelegate>
@property (nonatomic, strong) UIWindow *window;
@property (nonatomic, strong) CLLocationManager *myLocationManager;
@property (nonatomic, unsafe_unretained, getter=isExecutingInBackground)
BOOL executingInBackground;
@end
@implementation AppDelegate
<# Остаток вашего кода находится здесь #>

Продолжим. Создадим диспетчер местоположения и запустим его сразу после запуска приложения:

— (BOOL) application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
self.myLocationManager = [[CLLocationManager alloc] init];
self.myLocationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.myLocationManager.delegate = self;
[self.myLocationManager startUpdatingLocation];
self.window = [[UIWindow alloc] initWithFrame:
[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}

Как видите, мы указали желаемую точность определения местоположения на довольно высоком уровне. Тем не менее при переходе приложения в фоновый режим лучше снизить эту точность, чтобы снизить нагрузку на iOS:

— (void)applicationDidEnterBackground:(UIApplication *)application{
self.executingInBackground = YES;
/* Снижаем точность определения местоположения и нагрузку
на iOS, пока работаем в фоновом режиме. */
self.myLocationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
}
Когда программа вернется из фонового режима в приоритетный, точность опять можно будет поднять до высокого уровня:
— (void)applicationWillEnterForeground:(UIApplication *)application{
self.executingInBackground = NO;
/* Теперь, когда приложение вернулось в приоритетный режим, повышаем
точность определения местоположения. */
self.myLocationManager.desiredAccuracy = kCLLocationAccuracyBest;
}

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

— (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation{
if ([self isExecutingInBackground]){
/* Работаем в фоновом режиме.
Не выполняем никакой сложной обработки. */
} else {
/* Работаем в приоритетном режиме. Запускаем любые вычисления,
какие требуются */
}
}

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

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

Оглавление книги

Оглавление статьи/книги

Генерация: 0.053. Запросов К БД/Cache: 0 / 0
поделиться
Вверх Вниз