iBeacon发送多个信标的通知

时间:2014-06-27 04:12:17

标签: ios objective-c notifications ibeacon

方案

我在同一条街上有3个商人。每个商人都持有一个灯塔。我希望最终用户在接近CLProximityNear时收到通知。

源代码

AppDelegate.m

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

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

CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:proximityUUID identifier:@"BeaconIdentifier"];
region.notifyEntryStateOnDisplay = YES;

[self.iBeaconManager startMonitoringForRegion:region];

代表

- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region
{
    [self.iBeaconManager requestStateForRegion:region];
}

- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
    UILocalNotification *notification = [[UILocalNotification alloc] init];

    switch (state) {
        case CLRegionStateInside: {
            [self.iBeaconManager startRangingBeaconsInRegion:region];

            notification.alertBody = [NSString stringWithFormat:@"You are inside region %@", region.identifier];
            break;
        }

        case CLRegionStateOutside:
            notification.alertBody = [NSString stringWithFormat:@"You are outside region %@", region.identifier];
        case CLRegionStateUnknown:
        default:
            NSLog(@"Region unknown");
    }

    notification.soundName = UILocalNotificationDefaultSoundName;
    [[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}

- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
{
    if ([beacons count] > 0) {
        for (CLBeacon *beacon in beacons) {

            NSMutableString *logText = [NSMutableString stringWithFormat:@"Beacon: major: %d minor: %d Distance: %f is", [beacon.major intValue], [beacon.minor intValue], beacon.accuracy];

            switch (beacon.proximity) {
                case CLProximityImmediate: // 0 - 20cm
                    [logText appendString:@" IMMEDIATE"];

                    break;

                case CLProximityNear: // 20cm - 2m
                    [logText appendString:@" NEAR"];

                    break;

                case CLProximityFar: // 2m - 70m
                    [logText appendString:@" FAR"];
                    break;

                default:
                    [logText appendString:@" UNKNOWN"];
                    break;
            }
            UILocalNotification *notification = [[UILocalNotification alloc] init];
            notification.alertBody = logText;
            notification.soundName = UILocalNotificationDefaultSoundName;
            [[UIApplication sharedApplication] scheduleLocalNotification:notification];
        }
    }
}

问题

当我靠近灯塔时,我会收到无限的通知

问题

我希望这些最终用户在靠近时只收到一个通知。

e.g。 您好,欢迎来到A铺,我们只为今天提供优惠折扣

然后当他们走远时,再次通知感谢您的访问。祝你有愉快的一天

我应该将特定商家(信标)的当前状态/距离保存到NSUserDefaults吗?其实我试过了

CLProximity currentProximity = ... //从NSUserDefaults中保存的特定信标接近

switch (beacon.proximity) {
    case CLProximityImmediate: // 0 - 20cm
        [logText appendString:@" IMMEDIATE"];
        // if 1 second ago is Immediate, now still immediate
        if (currentProximity == CLProximityImmediate) continue;
        currentProximity = CLProximityImmediate;

        break;
    ...
}

修改上面的代码后,当我按下主页按钮(应用程序在后台运行)时,我没有得到通知

修改

我认为问题是当在后台运行的应用USUserDefaults实际上无效时。即使应用程序根本没有运行,我也希望保持每个信标的接近状态。

有什么建议吗?

3 个答案:

答案 0 :(得分:1)

你需要在这里做一些逻辑。

您应该为所有iBeacons设置标志。当一个特定的iBeacons到达你附近时你应该设置这个iBeacons附近的标志。的 CLProximityNear

当标志远离 CLProximityFar 时,标志将会关闭。

所以你需要做下面的步骤。

  1. 将所有iBeacons的标志设置为接近(显示通知)。
  2. 标志着什么时候走远。
  3. 确保您需要管理单独标志的所有iBeacons

答案 1 :(得分:0)

了解它将在后台运行,但仅在您的应用被事件唤醒到后台后约5秒钟。这些事件可以包括信标区域进入/退出,接收推送通知,照亮显示器等。每个事件需要不同的设置来获得它。

答案 2 :(得分:0)

我为一个类似的问题写了answer,可能对你有用。

基本上,Apple不希望你在后台进行测距,因此排除了你可以做的任何接近阅读。当然这并不意味着你不能这样做,但是你应该这样做吗?

您可以使用一种限制通知的解决方案是跟踪应用徽章的数量。

BOOL isNoAppBadges = ([[UIApplication sharedApplication]
                      applicationIconBadgeNumber] == 0);
BOOL isApplicationInBackground = ([[UIApplication sharedApplication]
                      applicationState] == UIApplicationStateBackground);

然后

        if (isNoAppBadges &&
            isApplicationInBackground)
        {
            // Red badge that appears over the app icon
            [[UIApplication sharedApplication]
             setApplicationIconBadgeNumber:1];

            UILocalNotification *notification = [
                                    [UILocalNotification alloc] init];

            notification.alertBody = @"Your notification text";

            [[UIApplication sharedApplication]
             presentLocalNotificationNow:notification];
        }

这个逻辑进入了:

- (void)locationManager:(CLLocationManager *)manager
  didDetermineState:(CLRegionState)state
          forRegion:(CLRegion *)region

当应用程序位于前台时,提示通知可能没有多大意义,但为了保持对主题的回答,您可以使用上述逻辑:

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

并实现您在示例中所做的相同的switch语句。