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

Как использовать push-уведомления на основе geo для iOS?

Можно ли использовать оповещения на основе геоданных на iOS, когда приложение убито (не в фоновом режиме)?

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

Однако возможна ли эта "идея"? Может ли GPS запускать и сравнивать координаты, когда приложение будет убито и запущено, и уведомить пользователя, когда он находится на месте? Есть ли у вас учебник/статья/дополнительная информация о предмете, который я мог бы прочитать?

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

4b9b3361

Ответ 1

Для отслеживания местоположения пользователя, когда приложение не работает (т.е. ранее было завершено), существует два варианта:

  • В руководстве по программированию приложений iOS в разделе "Отслеживание местоположения пользователя":

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

    Однако, в соответствии с ссылкой класса CLLocationManager, он не слишком точен, а обновления нечасты:

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

  • Мониторинг регионов работает аналогичным образом - в том числе перезапуск приложения после его завершения - но с большей точностью (в зависимости от доступности Wi-Fi сетей и сотовых вышек ):

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

    Наблюдение за другим регионом заключается в том, что (в соответствии с ссылкой класса CLLocationManager) уведомления о въезде и выезде в регионе могут быть получены только через 3-5 минут после пересечения региона границы.

    В зависимости от реальных требований, региональный мониторинг может использоваться для получения "грубого" местоположения, а затем, когда пользователь находится в определенном регионе, запустите более точную службу GPS на диспетчере местоположений. Когда пользователь покинет интересующую вас область, отключите службу GPS, чтобы сохранить батарею и снова вернуться к службе мониторинга грубого местоположения (например, мониторинг региона). Вот базовая реализация:

    SomeViewController.m

    ...
    @interface SomeViewController () <CLLocationManagerDelegate>
    
    @property (nonatomic, strong) CLLocationManager *locationManager;
    @property (nonatomic, strong) CLRegion *someRegion;
    
    @end
    
    @implementation SomeViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        self.locationManager = [[CLLocationManager alloc] init];
    
        CLLocationDistance radius = 10; // 10 metre sensitivity
        self.someRegion = [[CLRegion alloc] initCircularRegionWithCenter:someCoordinates radius:radius identifier:@"Smithtown Dry Cleaners"];
    
        self.locationManager.delegate = self;
        [self.locationManager startMonitoringForRegion:self.someRegion];
    
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
        self.locationManager.distanceFilter = 10;
        [self.locationManager startUpdatingLocation];
    }
    
    - (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
    {
        [self.locationManager startUpdatingLocation];
    }
    
    - (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
    {
        [self.locationManager stopUpdatingLocation];
    }
    
    // Delegate method from the CLLocationManagerDelegate protocol.
    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
    {
        CLLocation* location = [locations lastObject];
    
        // If the user current location is not within the region anymore, stop updating
        if ([self.someRegion containsCoordinate:location.coordinate] == NO) {
            [self.locationManager stopUpdatingLocation];
        }
    
        NSString *locationData = [NSString stringWithFormat:@"latitude %+.6f, longitude %+.6f\n",
                                  location.coordinate.latitude,
                                  location.coordinate.longitude];
        NSLog(@"%@", locationData);
    
        UILocalNotification *localNotification = [[UILocalNotification alloc] init];
        localNotification.alertBody = locationData;
        localNotification.alertAction = @"Location data received";
        localNotification.hasAction = YES;
        [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
    }
    

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

    MyApp-Info.plist:

    <key>UIBackgroundModes</key>
    <array>
            ...
            <string>location</string>
    </array>
    <key>UIRequiredDeviceCapabilities</key>
    <array>
            ...
            <string>location-services</string>
            <string>gps</string>
    </array>
    

    В приведенном выше коде предполагается использование iOS6 и ARC