Странное поведение iPhone4S при обнаружении маяка

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

Состояние
1. iPhone4S (с iPhone5 все в порядке)
2. Приложение работает в фоновом режиме
3. После обнаружения другого маяка (другой BeaconRegion отличается от другого).

Кто-нибудь может мне помочь ? Любое предложение будет оценено.

Спасибо за ответ. Вход в зону маяка A (второй) задерживается примерно на 30 секунд с момента входа в зону маяка B (первый), и я ждал около 20 секунд, пока LocalNotification не запустит «Beacon A». (Зона маяка-A и зона маяка-B частично перекрывают друг друга. И я ждал в зоне перекрытия.)

Это кусок кода.

- (void)startBeaconMonitoring
{
    if ([CLLocationManager respondsToSelector:@selector(isMonitoringAvailableForClass:)] && [CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]] && !self.locationManager) {
        self.locationManager = [CLLocationManager new];
        self.locationManager.delegate = self;

        _storeUUID = [[NSUUID alloc] initWithUUIDString:@"MY UUID HERE"];
        CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:_storeUUID major:CENSOR_TYPE_A  identifier:@"MY ID1"];
        region.notifyOnExit  = YES;
        region.notifyOnEntry = YES;

        CLBeaconRegion *region2 = [[CLBeaconRegion alloc] initWithProximityUUID:_storeUUID major:CENSOR_TYPE_B identifier:@"MY ID2"];
        region.notifyOnExit  = YES;
        region.notifyOnEntry = YES;

        [self.locationManager startMonitoringForRegion:region];
        [self.locationManager startMonitoringForRegion:region2];
    }
}

# pragma CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region
{
    [self.locationManager requestStateForRegion:region];
}

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    if ([region isMemberOfClass:[CLBeaconRegion class]] && [CLLocationManager isRangingAvailable]) {
        CLBeaconRegion *beacon = (CLBeaconRegion*)region;
        [self.locationManager startRangingBeaconsInRegion:beacon];
    }
}

- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
    switch (state) {
        case CLRegionStateInside:
            if ([region isMemberOfClass:[CLBeaconRegion class]] && [CLLocationManager isRangingAvailable]) {
                CLBeaconRegion *beacon = (CLBeaconRegion*)region;
                int major = [beacon.major intValue];
                [self.locationManager startRangingBeaconsInRegion:beacon];
            }
            break;
        case CLRegionStateOutside:
        case CLRegionStateUnknown:
        default:
            break;
    }
}

- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
    if ([region isMemberOfClass:[CLBeaconRegion class]] && [CLLocationManager isRangingAvailable]) {
        [self.locationManager stopRangingBeaconsInRegion:(CLBeaconRegion *)region];
    }
}

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
    switch (status) {
        case kCLAuthorizationStatusAuthorized:
            if (_locationDisabled) {
                _locationDisabled = NO;
                self.locationManager = nil;
                [self startBeaconMonitoring];
            }
            break;
        case kCLAuthorizationStatusRestricted:
        case kCLAuthorizationStatusNotDetermined:
            break;
        case kCLAuthorizationStatusDenied:
            _locationDisabled = YES;
            break;
        default:
            break;
    }
}

- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
{
    if (beacons.count > 0 && !_regionExit) {
        for (CLBeacon *beacon in beacons) {
            if ([beacon.proximityUUID.UUIDString isEqualToString:_storeUUID.UUIDString]) {
                NSString *censorType = [NSString stringWithFormat:@"%@", beacon.major];
                if ([censorType intValue] == CENSOR_TYPE_A) {
                    // DO ACTION A
                } else if ([censorType intValue] == CENSOR_TYPE_B) {
                    // DO ACTION B
                }
            }
        }
    }
}

person Tueno    schedule 16.06.2014    source источник
comment
Вы должны опубликовать свой код обнаружения   -  person Pieter    schedule 16.06.2014
comment
Не могли бы вы рассказать нам не только о своем коде, но и о том, сколько времени требуется для обнаружения каждого маяка на iPhone 5 и сколько времени вы ждете на 4s?   -  person davidgyoung    schedule 16.06.2014
comment
Делаете ли вы что-нибудь, чтобы справиться, если вы уже находитесь в этом регионе? Когда вы начинаете ранжировать маяки в didEnterRegion.   -  person Horst    schedule 16.06.2014
comment
да. В didDetermineState, если состояние - CLRegionStateInside, запускает маяк ранжирования (вы можете увидеть это в коде, который я написал выше).   -  person Tueno    schedule 16.06.2014


Ответы (1)


Похоже, что у iPhone4s на iOS 8 есть проблема с обнаружением быстрой смены региона в фоновом режиме. Мой тест показал, что если вы потеряете первую область более чем на 1 минуту и ​​войдете в новую область, то это будет обнаружено немедленно. Но если вы потеряете регион менее чем на 1 минуту, iPhone 4s не распознает его, и вам придется подождать (около 15 минут), чтобы полное сканирование Bluetooth это заметило. Я сделал обходной путь: я начинаю ранжирование после потери первой области на 60 секунд, если я войду в следующий маяк через 60 секунд, ранжирование обнаружит это.

person Kamil    schedule 06.03.2015
comment
Я также зарегистрировал очень странное поведение телефонов iPhone4 в отличие от iPhone5 или 6 stackoverflow.com/questions/27380241/ - person michal.ciurus; 06.03.2015