使用倍数信标(在每个不同的信标上弹出视图)

时间:2014-05-19 00:19:29

标签: ios objective-c ibeacon estimote

我是目标C的初学者。 我的应用程序与一个灯塔正常工作。 我正在使用" estimote SDK"。 我有很多问题,我想使用2或3个信标。我想为每个信标推送一个视图。

我不明白我怎么能用多个信标做到这一点。

  1. 我不知道是否必须使用多个信标管理器。 (ESTBeaconManager * beaconManager)

  2. 我不知道如何将不同区域传递给didRangeBeacons :( NSArray *)信标inRegion:(ESTBeaconRegion *)region

  3. 我可以使用一个信标仅用于通知,而另外两个用于弹出2个不同的视图,当我关闭它们时。 (每个灯塔的一个不同视图)

  4. 感谢您的帮助。

    最诚挚的问候。

    代码:

    #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"];
    

    我不会在初学者使用专业或辅修。

    我在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 close中,我这样做:

    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 个答案:

答案 0 :(得分:5)

每个信标都有3条信息 - 一个UUID,一个主要号码和一个次要号码。创建信标区域时,必须至少指定UUID。您可以选择指定主要值和次要值。 iOS将在后台扫描的信标区域数量有限(我相信它是20),因此通常最好在您的区域注册中尽可能广泛,然后确定何时通知您是否感兴趣在可见的灯塔中。

所有Estimote信标都具有相同的UUID,因此如果您只注册UUID区域,只要您处于任何 Estimote信标范围内,您的应用就会收到通知。我可以看到你的三个信标都使用了主要的12800,所以你可以简单地创建一个指定UUID和专业的区域,然后只要看到那些带有这些值的信标就会得到通知 - 或者你可以像你做的那样做并为三个信标中的每一个注册特定区域。

您只需要一个EstBeaconManager个实例来管理所有区域。

每当您进入或退出某个区域时,系统都会调用didEnterRegiondidExitRegion方法。如果您目前正在测量信标,也会调用didRangeBeacons方法。

在这些委托方法中,您需要检查主要和&amp;未成年人(嗯,实际上只是未成年人,因为在您的情况下,主要内容始终是相同的)值,以确定您要采取的行动。您还可以检查区域标识符字符串以确定哪个信标可见。

请注意,多个信标可能在范围内,因此您可能需要检查邻近度以确定要采取的操作。

最后,虽然您定义了三个区域,但您并未对它们进行范围/监控,因此请将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];


}

答案 1 :(得分:3)

我之前没有使用过Estimote SDK。我只是将我的Estimote信标视为vanilla iBeacons并使用Apple的位置管理器框架。

在我看来,你很困惑。

我简要地查看了Estimote SDK,它看起来与Apple的位置管理器非常相似。

在位置管理器中,您创建一个信标区域,然后您要求位置管理器为该信标区域开始测距(它会告诉您估计的距离读数,或者您使用startMonitoringForRegion来询问有关进入/退出区域事件的通知

你可以同时做两件事。浏览Estimate API,看起来他们使用相同的方法。

您需要创建一个信标区域,然后调用startRangingBeaconsInRegion和/或startMonitoringForRegion来询问范围和/或进入/退出区域通知。

然后等待信标进入/退出范围,(startMonitoringForRegion)或更改距离(startRangingBeaconsInRegion)时调用您的委托方法

查看文档,似乎调用requestStateForRegion将导致Estimote信标管理器调用您的locationManager:didDetermineState:forRegion:委托方法一次且仅一次。

在您的代码中,您还没有要求监控区域或范围信标,因此所有3个区域都将返回&#34;不在范围内&#34;状态。

不要调用那些requestStateForRegion。调用startMonitoringForRegion和/或startRangingBeaconsInRegion,并等待系统在信标状态发生变化时通知您。