iBeacon: didRangeBeacons перестает вызываться, необходимо перезагрузить устройство, чтобы оно снова заработало

Я использую пользовательский делегат BeaconManager, чтобы диапазон радиомаяка не определялся жизненным циклом контроллера представления. Все работает отлично, но время от времени (1-2 дня) диапазоны маяков перестают работать, и didRangeBeacons никогда не будут вызываться. Единственный способ исправить это - сбросить свой iPhone, после того, как я это сделаю, он отлично работает. Ниже приведен код, который я использую. Основной поток состоит в том, что когда мой ViewController вызывает ViewDidLoad, он отправляет уведомление обратно в AppDelegate, чтобы сказать ему, что нужно начинать ранжирование для маяков, я никогда не советую ему останавливаться, потому что я хочу, чтобы он продолжал варьироваться для маяков, независимо от того, куда пользователь перемещается чтобы в приложении. Мне интересно, является ли мой код причиной этого или это просто ошибка с Bluetooth. Спасибо за вашу помощь!

BeaconManager.m

#import "BeaconManager.h"
#import "AppDelegate.h"

@interface BeaconManager()<CLLocationManagerDelegate>

@property (nonatomic, strong) CLLocationManager *locationManager;
@property (nonatomic, strong) CLBeaconRegion *beaconRegion;

@end

@implementation BeaconManager

+ (id)sharedManager
{
    static BeaconManager *sharedBeaconManager = nil;
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        sharedBeaconManager = [[self alloc] init];
    });
    return sharedBeaconManager;
}

- (id)init
{
    self = [super init];
    if(self)
    {
        self.locationManager = [[CLLocationManager alloc] init];
        self.locationManager.delegate = self;
    }
    return self;
}

- (void)startBeaconMonitoring:(NSString*)forUUID
{
    NSUUID * uuid = [[NSUUID alloc] initWithUUIDString:forUUID];

    self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:@"com.beacons.publicRegion"];
    [self.locationManager startMonitoringForRegion:self.beaconRegion];
    [self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
}

- (void)stopBeaconMonitoring
{
    //Stop the region monitoring
    if(self.locationManager != nil && self.beaconRegion != nil) {
        [self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];
    }
}

#pragma mark - CLLocationManagerDelegate

- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
{
    self.beacons = beacons;
    if(self.delegate != nil) {
        [self.delegate beaconManager:self didRangeBeacons:self.beacons];
    }
}

@end

ViewController.m

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] postNotificationName:@"startRanging" object:nil userInfo:nil];
}

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(startRangingForZombies) name:@"startRanging" object: nil];

    return YES;
}

- (void)startRanging
{
    //Start the beacon region monitoring when the controller loads
    BeaconManager *beaconManager = [BeaconManager sharedManager];
    beaconManager.delegate = self;
    [beaconManager startBeaconMonitoring:@"1234-54324-34242-34242-43243"];
}

5 ответов

Решение

Мы получили много сообщений в Radius Networks о том, что телефоны перестают обнаруживать iBeacon и требуют перезагрузки или выключения и повторного включения Bluetooth для разрешения ситуации. Люди сообщили об этом на iPhone 4S, iPhone 5s, iPhone 5c и iPad.

У меня нет никаких веских доказательств того, что это что-то сломалось по сравнению с iOS 7.1, но частота отчетов значительно возросла с момента его выпуска. Таким образом, косвенные доказательства довольно убедительны.

Когда этот телефон переходит в это состояние, он все еще может сканировать устройства Bluetooth и может передавать как iBeacon. Поэтому это не аппаратная проблема с Bluetooth. Основываясь на имеющихся данных, это, скорее всего, недавно появившаяся ошибка в CoreLocation.

На самом деле это известная ошибка в iOS 7.1. Это чисто программная проблема со стеком Bluetooth для последней версии iOS. Обнаружение устройств Bluetooth иногда просто перестает работать - к сожалению, это относится ко всем iOS 7.1-совместимым устройствам. Об этой ошибке уже сообщалось в Apple, но до тех пор, пока они не выпустят исправление, лучшим решением будет просто перезагрузить устройство.

Если перезагрузка не помогает, в SmartRobotic есть полезное руководство по ее решению: http://www.smartbotics.com/#!4-Tips-to-Fix-Bluetooth-Problems-After-iOS-71-Upgrade / c118r / 031A86F6-C8E8-4768-B4FD-E6F83D9E4317

Если после обновления до iOS 7.1 возникают проблемы с подключением Bluetooth, попробуйте эти 4 совета.

  1. Завершение работы и перезагрузка - некоторые люди сообщают, что это все, что было необходимо для исправления их устройства после обновления iOS 7.1.
  2. Выключите Bluetooth и снова включите его. Проведите пальцем вверх, чтобы получить доступ к Центру управления, и нажмите значок Bluetooth, подождите не менее 30 секунд, а затем снова включите его. Это может часто восстанавливать устройство, которое испытывает проблемы с подключением.
  3. Убить (принудительно выйти) вызывающее беспокойство приложение. Начните с двойного щелчка Домой, чтобы запустить интерфейс многозадачных карт. Нажмите и удерживайте карту для приложения, затем подбросьте ее вверх и прочь. Это заставит приложение выйти и будет полностью перезагружено при следующем открытии приложения.
  4. Очистите и сбросьте параметры подключения устройства Bluetooth. Перейдите в "Настройки"> "Bluetooth" и коснитесь значка (i) соответствующего устройства. Нажмите на Забыть это устройство. Теперь вы сможете повторно добавить и повторно подключить оборудование Bluetooth к вашему устройству. Чтобы удалить все сопряженные устройства, перейдите в "Настройки"> "Основные"> "Сброс"> "Сбросить настройки сети", а затем снова настройте пары Bluetooth.

Надеемся, что эти предложения помогут решить ваши проблемы с подключением Bluetooth.

Приветствия.

Отказ от ответственности: в настоящее время я работаю на Sensorberg, мы продаем маяки и SDK.

У нас также есть многочисленные сообщения об этой ошибке. Мы попросили всех наших клиентов подать отчет об ошибке в Apple. Вот шаблон, который вы можете использовать: https://gist.github.com/anonymous/5283b6941e1f7d4e4461

Лично у меня было такое поведение дважды, когда я смог его записать: https://www.youtube.com/watch?v=6a6IJzaxxJg Помогла только перезагрузка устройства.

Продолжайте подавать отчеты об ошибках Apple rdar!

Apple внесла важные изменения в Bluetooth LE в 7.1, но тоже что-то сломала внутри.

Из моих экспериментов:

  • iPhone 4S 7.x - iBeacons работают как шарм

  • 2 x iPhone 4S 7.1, 2 x iPhone 5 7.1 - работает нормально, но время от времени требует перезагрузки (недетерминировано).

Похоже, системная проблема - большая. Я связался с Estimote - они знают об этом.

Интересный факт: вы не можете найти маяки - даже демонстрационное приложение estimote не может, методы делегирования не вызываются, но вы можете превратить (сломанное) устройство в маяк, и оно будет обнаружено другими устройствами.

У меня была похожая проблема, но после некоторого времени исследования я понял, что неправильно вызывать startMonitoringForRegion(region) и startRangingBeaconsInRegion(region) друг за другом. Вот что вы (Патрик) делаете:

- (void)startBeaconMonitoring:(NSString*)forUUID {
     NSUUID * uuid = [[NSUUID alloc] initWithUUIDString:forUUID];

     self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:@"com.beacons.publicRegion"];
     [self.locationManager startMonitoringForRegion:self.beaconRegion];
     [self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
}

Вместо этого startRangingBeaconsInRegion(region) должен вызываться в методе locationManagerDelegate locationManager(manager: CLLocationManager!, состояние didDetermineState: CLRegionState, forRegion region: CLRegion!) (В данном случае код Swift). Это было мое решение.

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

Другие вопросы по тегам