【问题标题】:How to display notifications when multiple iBeacons are in range当多个 iBeacon 在范围内时如何显示通知
【发布时间】:2014-09-17 14:14:10
【问题描述】:

我有 3 个 iBeacon,它们被放置在 3 个不同的房间中。当我走进每个房间时,我希望在我的应用关闭时收到通知,告诉我我在哪个房间。

我的信标都有 UUID,但主要和次要版本不同。

这是我们迄今为止在我们的课程中实现的(不是在 App Delegate 中)

-(void)locationManager:(CLLocationManager*)manager didRangeBeacons:(NSArray*)beacons inRegion:(CLBeaconRegion*)region {

// firstBeacon is the closest beacon
CLBeacon *firstBeacon = [beacons firstObject];

NSLog(@" Major %@ Minor %@", firstBeacon.major, firstBeacon.minor);

int major = [firstBeacon.major intValue];
int minor = [firstBeacon.minor intValue];

if (major == 43005 && minor == 52679) {

    UILocalNotification *notification = [[UILocalNotification alloc] init];
    notification.soundName = @"Default";
    notification.alertBody = @"Green";
    [[UIApplication sharedApplication] presentLocalNotificationNow:notification];

    self.beaconColour.text = @"Green";
}
else if (major == 48891 && minor == 47852) {

    UILocalNotification *notification = [[UILocalNotification alloc] init];
    notification.soundName = @"Default";
    notification.alertBody = @"Light Blue";
    [[UIApplication sharedApplication] presentLocalNotificationNow:notification];

    self.beaconColour.text = @"Light Blue";
}
else if (major == 59510 && minor == 42953) {

    UILocalNotification *notification = [[UILocalNotification alloc] init];
    notification.soundName = @"Dark Blue";
    notification.alertBody = @"Green";
    [[UIApplication sharedApplication] presentLocalNotificationNow:notification];

    self.beaconColour.text = @"Dark Blue";
}

self.major.text = [NSString stringWithFormat:@"%d", major];
self.minor.text = [NSString stringWithFormat:@"%d", minor];

}

根据答案更新代码

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

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

    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"B9407F30-F5F8-466E-AFF9-25556B57FE6D"];

    self.myBeaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid
                                                             identifier:@"com.accenture.testregion"];


    self.myBeaconRegion.notifyEntryStateOnDisplay = YES;
    self.myBeaconRegion.notifyOnEntry = YES;
    self.myBeaconRegion.notifyOnExit = YES;
    [self.locationManager startMonitoringForRegion:self.myBeaconRegion];

}

- (void)didReceiveMemoryWarnins {

    [super didReceiveMemoryWarning];
}

BOOL _isInsideRegion;

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {

    NSLog(@"didEnterRegion");
    if ([region isKindOfClass:[CLBeaconRegion class]]) {
        CLBeaconRegion *beaconRegion = (CLBeaconRegion *)region;
        int major = [beaconRegion.major intValue];
        int minor = [beaconRegion.minor intValue];

        NSLog(@" Major %d Minor %d", major, minor);

        if (major == 43005 && minor == 52679) {

            self.beaconColour.text = @"Green";
            if (!_isInsideRegion) {
                UILocalNotification *notification = [[UILocalNotification alloc] init];
                notification.soundName = @"Default";
                notification.alertBody = @"Green";
                [[UIApplication sharedApplication] presentLocalNotificationNow:notification];
            }
            _isInsideRegion = YES;
        }
        else if (major == 48891 && minor == 47852) {

            self.beaconColour.text = @"Light Blue";
            if (!_isInsideRegion) {
                UILocalNotification *notification = [[UILocalNotification alloc] init];
                notification.soundName = @"Default";
                notification.alertBody = @"Green";
                [[UIApplication sharedApplication] presentLocalNotificationNow:notification];
            }
            _isInsideRegion = YES;
        }
        else if (major == 59510 && minor == 42953) {

            self.beaconColour.text = @"Dark Blue";
            if (!_isInsideRegion) {
                UILocalNotification *notification = [[UILocalNotification alloc] init];
                notification.soundName = @"Default";
                notification.alertBody = @"Green";
                [[UIApplication sharedApplication] presentLocalNotificationNow:notification];
            }
            _isInsideRegion = YES;
        }
    }
}

【问题讨论】:

  • 您的问题是什么?您的代码中是否有什么不工作的地方?

标签: ios objective-c bluetooth ibeacon


【解决方案1】:

尽量不要从信标数组中获取第一个对象,你应该枚举它并比较哪个是哪个,有时你可以从几个信标接收到信号。

我通过调用didEnterRegion: 委托而不是didRangeBeacons: 使其工作 您还应该创建一个布尔标志(变量)以防止重复发送通知。并在次要/主要匹配时在 if 条件内将其标记为 true,并在 didExitRegion 中将其设置为 false:

BOOL _isInsideRegion;


 - (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {

    if ([region isKindOfClass:[CLBeaconRegion class]]) {
        CLBeaconRegion *beaconRegion = (CLBeaconRegion *)region;
        int major = [beaconRegion.major intValue];
        int minor = [beaconRegion.major.minor intValue];

        if (major == 43005 && minor == 52679) {
            if (!_isInsideRegion) {
                UILocalNotification *notification = [[UILocalNotification alloc] init];
                notification.soundName = @"Default";
                notification.alertBody = @"Green";
                [[UIApplication sharedApplication] presentLocalNotificationNow:notification];
            }
            _isInsideRegion = YES;    
            self.beaconColour.text = @"Green";
    }
        else if (major == 48891 && minor == 47852) {
            if (!_isInsideRegion) {....
    }
}

- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {

    if ([region isKindOfClass:[CLBeaconRegion class]]) {
        CLBeaconRegion *beaconRegion = (CLBeaconRegion *)region;
        if (major == 43005 && minor == 52679) {
                if (!_isInsideRegion) {
                     // You can send another notification to inform user that he left the region
                 }
                _isInsideRegion = NO;
}

【讨论】:

  • 感谢您发布此信息。我们已经尝试过了,它在应用程序打开时完美运行,但在应用程序进入后台或根本不运行时无法正常工作。有没有办法解决这个问题?
  • @user3626407 它对我有用。您是否在调用 startMonitorinf... 和 startRanging... 之前配置了区域? region.notifyOnEntry = YES; region.notifyOnExit = YES; region.notifyEntryStateOnDisplay = YES;
  • 我已经更新了代码以向您展示我们现在拥有的内容。这和你的一样吗?
  • @user3626407 是的,但是您必须记住,当您进入信标范围时,您应该收到通知,但是当您离开它时,通知不会在几分钟后立即发出。查看此代码有效的最佳方法是关闭应用程序。关闭信标设备等待几分钟,然后打开信标。如果未启动,您的应用应该会收到通知 raven。你打开位置更新后台模式了吗?
  • 如果我对主要和次要执行 NSLog,我会得到主要(空)次要(空)。是 CLBeaconRegion *beaconRegion = (CLBeaconRegion *)region;访问主要和次要值的正确方法?
【解决方案2】:

当您的应用在后台时,您不会很快获得区域进入/退出事件。最多可能需要 15 分钟才能收到通知。见这里:http://developer.radiusnetworks.com/2013/11/13/ibeacon-monitoring-in-the-background-and-foreground.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-27
    • 1970-01-01
    相关资源
    最近更新 更多