Ios iBeacon发送多个信标的通知 脚本

Ios iBeacon发送多个信标的通知 脚本,ios,objective-c,notifications,ibeacon,Ios,Objective C,Notifications,Ibeacon,我在同一条街上有三个商人。每个商人都有一个灯塔。我希望最终用户在靠近时得到通知(CLProximityNear) 源代码 AppDelegate.m self.iBeaconManager = [[CLLocationManager alloc] init]; self.iBeaconManager.delegate = self; NSUUID *proximityUUID = [[NSUUID alloc] initWithUUIDString:@"B9407F30-F5F8-466E-A

我在同一条街上有三个商人。每个商人都有一个灯塔。我希望最终用户在靠近时得到通知(
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
?实际上我已经试过了

CLAPROSSION CURRENTAPROSSION=…//从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;
    ...
}
在修改了上面的代码后,当我按下home按钮(应用程序在后台运行)时,没有收到任何通知

编辑

我认为问题在于,当应用程序在后台运行时,
USUserDefaults
实际上不起作用。我想保持每个信标的接近状态,即使应用程序根本没有运行


有什么建议吗?

你需要在这里做些逻辑分析

您应该为所有iBeacons设置标志。当一个特定的iBeacons靠近时,您应该设置该iBeacons靠近的标志CLProximityNear

当标志转到farCLProximityFar时,它将关闭

因此,您需要执行以下步骤

  • 将所有iBeacons的标志设置为接近时(显示通知位置)
  • 什么时候走得远就用旗子标出

  • 确保您需要管理的所有iBeacon都能在后台运行,但仅在应用程序被事件唤醒到后台后5秒钟内运行。这些事件可以包括信标区域进入/退出、接收推送通知、点亮显示屏等。每个事件都需要不同的设置来获取它

    我为一个类似的问题写了一篇文章,这个问题可能对你有所帮助

    基本上,苹果公司不希望你在背景中进行测距,这样就排除了你可以进行的任何近距离阅读。当然,这并不意味着你做不到,但你应该这样做吗

    一种限制通知的解决方案是跟踪应用程序徽章的数量

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

    这一逻辑已经进入:

    - (void)locationManager:(CLLocationManager *)manager
      didDetermineState:(CLRegionState)state
              forRegion:(CLRegion *)region
    
    当应用程序位于前台时,显示通知可能没有多大意义,但为了保持主题的答案,您可以使用以下逻辑:

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

    并实现与示例中相同的switch语句。

    我尝试为所有信标保留
    CLProximityImmediate
    ,但一旦添加
    if(currentproximityimmediate==CLProximityImmediate)继续
    ,当应用程序在后台运行时,它将变成完全没有通知。只有当应用程序在foregroundSunny上运行时,它才起作用。只要应用程序在前台,Sunny的解决方案就是好的。但正如Yatheesha所提到的,在进入该地区后的5秒钟内,测距在后台将不起作用。不幸的是,这个用例根本无法在后台工作,因为用户通常在距离较远的时候进入该区域,并且没有足够的背景测距时间来接近该区域。由于大多数用户不会在前台使用该应用程序,我会重新考虑这一点。@davidgyoung您确定测距在后台不起作用吗?因为我已经在ios 7.1的后台进行了测试,我已经处理了这个问题。@SunnyShah看看这个链接@davidgyoung实际上
    locationManager:didRangeBeacons:inRegion:
    即使应用程序没有运行也能正常工作。今天早上,当我走进办公室时,我突然收到了大量的通知,我的应用程序甚至不在后台。你说得对,它只持续了大约5秒钟。这项技术似乎有一定的局限性。希望将来能有所改善
    - (void)locationManager:(CLLocationManager *)manager
        didRangeBeacons:(NSArray *)beacons
               inRegion:(CLBeaconRegion *)region