Приложение iBeacon работает только иногда, передача никогда не работает на iPhone 5

У меня здесь действительно странная проблема. Я пытаюсь создать приложение для обнаружения маяков. У меня пока нет реальных маяков, поэтому я тестирую с iPhone 5 и iPad 3. Странно то, что передача работает только на iPad, iPhone не работает в качестве передатчика, хотя я использовал то же самое приложение на нем.

Но даже с iPad в качестве передатчика приложение работает только иногда - иногда iPhone уведомляет меня о том, что нашел маяк, а иногда нет. Я принудительно закрыл приложение на iPad, и после перезагрузки оно заработало, но в другой раз - нет. Поскольку все работает время от времени, я думаю, что это не может быть код, вызывающий такое поведение, но это может быть - я не опытный кодер, я только начал это. Мой код основан на этом руководстве http://www.devfright.com/ibeacons-tutorial-ios-7-clbeaconregion-clbeacon/

Сначала я подумал, что это может быть ответом, но он не решил его: иногда он все же работал, а иногда - нет.

Кто-нибудь может сказать мне, что я имею с ней дело?

Вот мой код для трекера:

ladBeaconTracker.h

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <CoreBluetooth/CoreBluetooth.h>

@interface ladBeaconTracker : UIViewController <CLLocationManagerDelegate>

@property (strong, nonatomic) CLBeaconRegion *beaconRegion;
@property (strong, nonatomic) CLLocationManager *locationManager;
@property (weak, nonatomic) IBOutlet UILabel *beaconFoundLabel;

@end

ladBeaconTracker.m

#import "ladBeaconTracker.h"

    @interface ladBeaconTracker ()

    @property NSUUID *uuid;

@end  

@implementation ladBeaconTracker

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;

    [self initRegion];
}  

- (void)initRegion {
    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"A5456D78-C85B-44C6-9F20-8268FD25EF8A"];
    self.beaconRegion = [[CLBeaconRegion alloc]initWithProximityUUID:uuid identifier:@"Museum"];

    [self.locationManager startMonitoringForRegion:self.beaconRegion];

    NSLog(@"Region %@ initated", _beaconRegion.identifier);
}

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region { 
    [self.locationManager startRangingBeaconsInRegion:self.beaconRegion];       
    self.beaconRegion.notifyEntryStateOnDisplay = YES;

    NSLog(@"Region %@ entered", _beaconRegion.identifier);
}

- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
    [self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];

    NSLog(@"Region %@ exit", _beaconRegion.identifier);
}

- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region{
    CLBeacon *beacon = [[CLBeacon alloc] init];
    beacon= [beacons lastObject];    
    self.beaconFoundLabel.text =@"Yes";

    NSLog(@"Ranged Region %@", _beaconRegion.identifier );
}


- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

И это код передатчика:

configViewController.h

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <CoreBluetooth/CoreBluetooth.h>

@interface ConfigViewController : UIViewController <CBPeripheralManagerDelegate>

@property (strong,nonatomic) CLBeaconRegion *beaconRegion;
@property(strong,nonatomic) NSDictionary *beaconPeripheralData;
@property (strong, nonatomic) CBPeripheralManager *PeripheralManager;

@end

ConfigViewController.m

#import "ConfigViewController.h"

@interface ConfigViewController ()

@end

@implementation ConfigViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [self initBeacon];  
}

- (void) peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral {
    if (peripheral.state == CBPeripheralManagerStatePoweredOn) {
        NSLog(@"Powered ON");
        [self.PeripheralManager startAdvertising:self.beaconPeripheralData];
    }
    else if (peripheral.state == CBPeripheralManagerStatePoweredOff){
        NSLog(@"Powered OFF");
        [self.PeripheralManager stopAdvertising];
    }
}

- (void)initBeacon {
    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"A5456D78-C85B-44C6-9F20-8268FD25EF8A"];
    self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid
                                                major:1
                                                minor:1
                                                identifier:@"Museum"];
}

- (IBAction)transmitBeacon:(UIButton *)sender {
    self.beaconPeripheralData = [self.beaconRegion peripheralDataWithMeasuredPower:nil];
    self.PeripheralManager = [[CBPeripheralManager alloc]initWithDelegate:self queue:nil options:nil];
}


- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

1 ответ

Решение

Ваш код выглядит хорошо для обнаружения маяков в фоновом режиме. Два предложения:

  1. Я подозреваю, что проблема, когда iPad передает не с iPad, но что iPhone не может получить. Попробуйте выключить iPhone, чтобы устранить известную ошибку в iOS 7.1.

  2. iOS может намного быстрее обнаруживать iBeacons на переднем плане, если вы устанавливаете диапазон одновременно с настройкой мониторинга. Переехать [self.locationManager startRangingBeaconsInRegion:self.beaconRegion]; в initRegion и вынуть stopRangingBeaconsInRegion полностью.

После того, как вы сделали (2), повторите ваши тесты на переднем плане и найдите ваш лог-оператор Ranged Region, Вы должны видеть это каждую секунду, когда маяк включен.

В фоновом режиме знайте, что для обнаружения iBeacon и обнаружения того, что iBeacon больше нет, может потребоваться до 15 минут. Опять же, просмотрите ваши записи в журнале на предмет подсказок о текущем состоянии и знайте, что вы не можете получить новое событие входа в регион, пока не получите первое событие выхода из региона или не перезагрузите свой телефон.

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