5

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

我不明白如何使用多个信标来做到这一点。

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

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

  3. 当我关闭它们时,我可以只使用一个信标来通知,而另外两个则可以弹出 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"];

我在初始化时不使用主要或次要。

在 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 (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总是向我发送相同的次要号码. 请你给我一些帮助吗?我确定我做错了什么。

4

2 回答 2

5

每个信标都有 3 条信息——一个 UUID、一个主要编号和一个次要编号。创建信标区域时,您必须至少指定 UUID。您可以选择指定主要和次要值。iOS 会在后台扫描的信标区域的数量是有限制的(我相信是 20 个),所以一般情况下最好在你的区域注册时尽可能宽泛一些,如果你有兴趣再确定什么时候通知在可见的信标中。

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

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

每当您进入或退出一个区域时,您的didEnterRegiondidExitRegion方法都会被调用。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];


}
于 2014-05-19T01:06:10.450 回答
3

我以前没有使用过 Estimote SDK。我只是将我的 Estimote 信标视为普通 iBeacons 并使用 Apple 的 Location Manager 框架。

在我看来,你很困惑。

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

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

你可以同时做这两个。看一眼 Estimate API,看起来它们使用了相同的方法。

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

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

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

在您的代码中,您没有要求监视区域或范围信标,因此所有 3 个区域都将返回“不在范围内”状态。

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

于 2014-05-19T00:57:22.077 回答