Использование нескольких маяков (отображение каждого отдельного маяка)

Я начинающий в цели C. Мое приложение работает правильно с одним маяком. Я использую "Estimote SDK". У меня много проблем, я хочу использовать 2 или 3 маяка. Я хочу выдвинуть вид для каждого из маяков.

Я не понимаю, как я могу сделать это с несколькими маяками.

  1. Я не знаю, нужно ли мне использовать несколько менеджеров маяков. (ESTBeaconManager* beaconManager)

  2. Я не знаю, как передать различные регионы в маяки didRangeBeacons:(NSArray *) в регионе:(ESTBeaconRegion *)

  3. Могу ли я использовать один маяк только для уведомлений, а 2 других - для отображения 2 разных представлений, когда я рядом с ними. (один вид для каждого маяка)

Спасибо за вашу помощь.

С уважением.

Код:

#import "ESTViewController.h"
#import "PresentViewController.h"
#import <ESTBeaconManager.h>
#import <AudioToolbox/AudioToolbox.h>

@interface ESTViewController () <ESTBeaconManagerDelegate>

@property (nonatomic, strong) ESTBeaconManager* beaconManager;
@property (nonatomic, strong) ESTBeaconManager* beaconManager2;
@property (nonatomic, strong) ESTBeaconManager* beaconManager3;

@property (nonatomic, strong) ESTBeacon* selectedBeacon;


@end

@implementation ESTViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // should i create one manager instance or more ?

    self.beaconManager = [[ESTBeaconManager alloc] init];
    self.beaconManager.delegate = self;
    self.beaconManager.avoidUnknownStateBeacons = NO;

    //self.beaconManager2 = [[ESTBeaconManager alloc] init];
    //self.beaconManager2.delegate = self;
    //self.beaconManager2.avoidUnknownStateBeacons = NO;

    //self.beaconManager3 = [[ESTBeaconManager alloc] init];
    //self.beaconManager3.delegate = self;
    //self.beaconManager3.avoidUnknownStateBeacons = NO;



    // My Differents regions


    region = [[ESTBeaconRegion alloc] initWithProximityUUID:ESTIMOTE_PROXIMITY_UUID
                                                      major:12800 minor:228 identifier:@"Icy Marshmellow"];

    region2 = [[ESTBeaconRegion alloc] initWithProximityUUID:ESTIMOTE_PROXIMITY_UUID
                                                       major:12800 minor:128 identifier:@"Mint Cocktail"];

    region3 = [[ESTBeaconRegion alloc] initWithProximityUUID:ESTIMOTE_PROXIMITY_UUID
                                                       major:12800 minor:328 identifier:@"Blueberry Pie"];


    // Should i do it for each region with one ESTBeaconManager or 3 ?

    [self.beaconManager requestStateForRegion:region];
    [self.beaconManager requestStateForRegion:region2];
    [self.beaconManager requestStateForRegion:region3];


}

// NOTIFICATION METHOD :

-(void)beaconManager:(ESTBeaconManager *)manager
      didEnterRegion:(ESTBeaconRegion *)region
{
    // iPhone/iPad entered beacon zone

    // present local notification
    UILocalNotification *notification = [[UILocalNotification alloc] init];
    notification.alertBody = @"Hello blabla blabla";
    notification.soundName = UILocalNotificationDefaultSoundName;

    [[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}

-(void)beaconManager:(ESTBeaconManager *)manager
       didExitRegion:(ESTBeaconRegion *)region
{
    // iPhone/iPad left beacon zone

    // present local notification
    UILocalNotification *notification = [[UILocalNotification alloc] init];
    notification.alertBody = @"bye bye";
    notification.soundName = UILocalNotificationDefaultSoundName;

    [[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}



- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.beaconManager startRangingBeaconsInRegion:region];
    [self.beaconManager startMonitoringForRegion:region];

    //[self.beaconManager2 startRangingBeaconsInRegion:region2];
    //[self.beaconManager2 startMonitoringForRegion:region2];

    //[self.beaconManager3 startRangingBeaconsInRegion:region3];
    //[self.beaconManager3 startMonitoringForRegion:region3];


}

  - (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];

    [self.beaconManager stopRangingBeaconsInRegion:region];
    [self.beaconManager stopMonitoringForRegion:region];

    //[self.beaconManager2 stopRangingBeaconsInRegion:region2];
    //[self.beaconManager2 stopMonitoringForRegion:region2];

    //[self.beaconManager3 stopRangingBeaconsInRegion:region3];
    //[self.beaconManager3 stopMonitoringForRegion:region3];

}

// My problem is here , i dont know how i can pass differents regions here


-(void)beaconManager:(ESTBeaconManager *)manager
     didRangeBeacons:(NSArray *)beacons
            inRegion:(ESTBeaconRegion *)region
{
    if([beacons count] > 0)
    {

        if(!self.selectedBeacon)
        {
            // initialy pick closest beacon
            self.selectedBeacon = [beacons objectAtIndex:0];
        }
        else
        {
            for (ESTBeacon* cBeacon in beacons)
            {
                // update beacon it same as selected initially
                if([self.selectedBeacon.major unsignedShortValue] == [cBeacon.major unsignedShortValue] &&
                   [self.selectedBeacon.minor unsignedShortValue] == [cBeacon.minor unsignedShortValue])
                {
                    self.selectedBeacon = cBeacon;
                }
            }
        }



        switch (self.selectedBeacon.proximity)
        {
            case CLProximityUnknown:
            {

                self.rangeStatusImageView.image = [UIImage imageNamed:@"logo_signal.jpg"];
                self.descriptionStateLabel.text = @"Signal lost";
                break;
            }
            case CLProximityImmediate:
            {
                [self performSegueWithIdentifier: @"presentSegue" sender: self];
                break;
            }
            case CLProximityNear:
            {
                self.rangeStatusImageView.image = [UIImage imageNamed:@"logo_near_bleu.jpg"];
                self.descriptionStateLabel.text = @"Come closer";
                break;

            }
            case CLProximityFar:
            {
                self.rangeStatusImageView.image = [UIImage imageNamed:@"logo_far_clair.jpg"];
                self.descriptionStateLabel.text = @"Welcome";
                break;
            }

            default:
                break;
        }


    }
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];

}

@end

РЕДАКТИРОВАТЬ

Хорошо, я работал над своим кодом, и теперь я делаю это с одним регионом. у моего массива маяков есть 3 маяка.

region = [[ESTBeaconRegion alloc] initWithProximityUUID:ESTIMOTE_PROXIMITY_UUID identifier:@"multibeacons"];

я не использую мажор или минор в init.

в ViewDidAppears я делаю:

[self.beaconManager startRangingBeaconsInRegion:region];

Делегат, как это:

-(void)beaconManager:(ESTBeaconManager *)manager
     didRangeBeacons:(NSArray *)beacons
            inRegion:(ESTBeaconRegion *)region
{

// I used a sort , sorting by distance
    NSSortDescriptor *sortDescriptor;
    sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"distance" ascending:YES];
    NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];

// if breakpoint here 3 beacons in array
    self.beaconsArray = [beacons sortedArrayUsingDescriptors:sortDescriptors];

    if([self.beaconsArray count] > 0)
    {

        if(!self.selectedBeacon)
        {
            // initialy pick closest beacon
            self.selectedBeacon = [beacons objectAtIndex:0];
            currentBeaconMinor = self.selectedBeacon.minor;
        }
        else
        {
            for (ESTBeacon* cBeacon in self.beaconsArray)
            {
                // update beacon it same as selected initially
                if([self.selectedBeacon.major unsignedShortValue] == [cBeacon.major unsignedShortValue] &&
                   [self.selectedBeacon.minor unsignedShortValue] == [cBeacon.minor unsignedShortValue])
                {
                    self.selectedBeacon = cBeacon;
                    currentBeaconMinor = self.selectedBeacon.minor;
                }
            }
        }

Я сортирую по расстоянию, и у меня есть значение currentBeaconMinor. В моем массиве маяков есть 3 маяка, если я поставлю точку останова, я смогу увидеть 3.

В близости Switch я сделал так:

switch (self.selectedBeacon.proximity)
        {

            case CLProximityImmediate:
            {

                if ([currentBeaconMinor floatValue] == 128)
                {
                    NSLog(@"128 128 128");
                    //[self performSegueWithIdentifier: @"presentSegue1" sender: self];
                }

                else if ([currentBeaconMinor floatValue] == 228)
                {
                    NSLog(@"228 228 228");
                    //[self performSegueWithIdentifier: @"presentSegue2" sender: self];
                }
                else if ([currentBeaconMinor floatValue] == 328)
                {
                    NSLog(@"328 328 328");
                    //[self performSegueWithIdentifier: @"presentSegue3" sender: self];
                }

                break;
            }

Но это все равно не работает:(((Я злюсь. Мое приложение выбирает вначале ближайший маяк. После этого приложение всегда сохраняет один и тот же маяк и никогда не меняется. Я перемещаю маяк рядом с устройством, но nslog всегда отправляет мне один и тот же младший номер Пожалуйста, вы можете помочь мне? Я уверен, что я делаю что-то не так.

2 ответа

Решение

Каждый маяк имеет 3 фрагмента информации - UUID, старший номер и младший номер. Когда вы создаете регион маяка, вы должны указать как минимум UUID. При желании вы можете указать основные и второстепенные значения. Существует ограничение на количество областей маяка, которые iOS будет сканировать в фоновом режиме (я полагаю, это 20), поэтому в общем случае лучше всего быть максимально широким при регистрации вашего региона, а затем определять, когда вас интересует, если вы заинтересованы в маяке, который виден.

Все маяки Estimote имеют одинаковый UUID, поэтому, если вы зарегистрируете регион только с UUID, ваше приложение будет уведомлено, когда вы находитесь в зоне действия любого маяка Estimote. Я вижу, что все ваши три маяка используют мажор 12800, так что вы можете просто создать регион, в котором указан UUID и мажор, и тогда вы будете получать уведомления всякий раз, когда маяк с этими значениями будет виден, или вы можете сделать так, как вы это сделали. и зарегистрируйте конкретные регионы для каждого из ваших трех маяков.

Вам нужен только один EstBeaconManager экземпляр для управления всеми регионами.

Всякий раз, когда вы входите или выходите из региона, ваш didEnterRegion а также didExitRegion методы будут вызваны. Также ваш didRangeBeacons метод будет вызван, если вы в данный момент используете маяки.

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

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

Наконец, хотя вы определяете три региона, вы не контролируете / отслеживаете их все, поэтому измените viewWillAppear в

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.beaconManager startRangingBeaconsInRegion:region];
    [self.beaconManager startMonitoringForRegion:region];

    [self.beaconManager startRangingBeaconsInRegion:region2];
    [self.beaconManager startMonitoringForRegion:region2];

    [self.beaconManager startRangingBeaconsInRegion:region3];
    [self.beaconManager startMonitoringForRegion:region3];


}

Я не использовал Estimote SDK раньше. Я просто рассматриваю свои маяки Estimote как ванильные iBeacons и использую фреймворк Apple Location Manager.

Мне кажется, что вы очень смущены.

Я кратко посмотрел на Estimote SDK, и он выглядел очень похоже на менеджер местоположения Apple.

В диспетчере местоположений вы создаете регион маяка, затем просите менеджера местоположения начать ранжирование для этого региона маяка (который сообщает вам о приблизительных показаниях расстояния или вы используете startMonitoringForRegion, чтобы запросить уведомление о событиях входа / выхода из региона.

Вы можете сделать оба одновременно. Глядя на API Estimate, похоже, что они используют один и тот же подход.

Вам необходимо создать регион маяка, затем вызвать startRangingBeaconsInRegion и / или startMonitoringForRegion, чтобы запросить уведомления о диапазоне и / или входе / выходе из региона.

Затем вы ждете, когда будут вызваны ваши методы делегата, когда маяк входит / выходит из диапазона (startMonitoringForRegion) или изменяет расстояние (startRangingBeaconsInRegion)

Глядя на документы, кажется, что вызов requestStateForRegion приведет к тому, что менеджер маяков Estimote вызовет ваш locationManager:didDetermineState:forRegion: делегировать метод один раз и только один раз.

В вашем коде вы не просили следить за регионами или указывать радиомаяки, поэтому все 3 региона вернут состояние "не в диапазоне".

Не вызывайте эти requestStateForRegion. Вызовите startMonitoringForRegion и / или startRangingBeaconsInRegion и подождите, пока система уведомит вас об изменении статуса маяка.

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