IBeacon: didRangeBeacons перестает получать вызов, должен reset устройство, чтобы он снова работал
Я использую пользовательский делегат BeaconManager, так что дальность радиомаяка не определяется жизненным циклом контроллера вида. Все отлично работает, но время от времени (1-2 дня) диапазон радиомаяков перестает работать, а didRangeBeacons никогда не будет вызван. Единственный способ исправить это для меня до reset моего 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"];
}
Ответы
Ответ 1
Мы получили много сообщений в Radius Networks о телефонах, останавливающих обнаружение iBeacons и требующих перезагрузки или отключение и повторное включение Bluetooth для разрешения ситуации. Люди сообщили об этом на iPhone 4S, iPhone 5, iPhone 5c и iPad.
У меня нет каких-либо убедительных доказательств того, что это что-то, что сломалось с iOS 7.1, но с момента его выпуска частота отчетов увеличилась. Поэтому косвенные доказательства довольно прочны.
Когда этот телефон переходит в это состояние, телефон может все еще сканировать Bluetooth-устройства и может передавать его как iBeacon. Это не проблема с Bluetooth. Основываясь на имеющихся доказательствах, это, скорее всего, новая ошибка в CoreLocation.
Ответ 2
Собственно, это известная ошибка в 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
Приветствия.
Ответ 3
Apple представила важные изменения в Bluetooth LE в версии 7.1, но также сломала что-то внутри.
Из моих экспериментов:
-
iPhone 4S 7.x - iBeacons работают как шарм
-
2 x iPhone 4S 7.1, 2 x iPhone 5 7.1 - отлично работает, но время от времени требуется перезапуск (неопределенный).
Похоже, системная проблема - большая.
Я связался с Estimote - они знают об этом.
Интересный факт: вы не можете найти маяки - даже не может быть оценено демо-приложение, делегировать методы не вызывают, но вы можете превратить (сломано) устройство в маяк, и оно будет обнаружено другими устройствами.
Ответ 4
Отказ от ответственности: в настоящее время я работаю для сенсберга, мы продаем маяки и SDK.
У нас есть многочисленные сообщения об этой ошибке. Мы попросили всех наших клиентов подать отчет об ошибке в Apple. Вот шаблон, который вы можете использовать: https://gist.github.com/anonymous/5283b6941e1f7d4e4461
У меня лично было поведение дважды, как только я смог записать его: https://www.youtube.com/watch?v=6a6IJzaxxJg Только перезагрузка устройства помогла.
Продолжайте записывать отчеты об ошибках Apple rdar!
Ответ 5
У меня была аналогичная проблема, но после некоторого времени исследования я понял, что неправильно называть startMonitoringForRegion (область) и startRangingBeaconsInRegion (область) друг за другом. Вот что вы делаете (Патрик):
- (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 method locationManager (manager: CLLocationManager!, didDetermineState state: CLRegionState, forRegion region: CLRegion!) (В этом случае код Swift). Это было мое решение.
Это имеет смысл, потому что первым шагом является поиск любого маяка в регионе, второй - получение конкретной информации от уже наблюдаемого маяка.