我在同一条街上有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
实际上无效时。即使应用程序根本没有运行,我也希望保持每个信标的接近状态。
有什么建议吗?
答案 0 :(得分:1)
你需要在这里做一些逻辑。
您应该为所有iBeacons设置标志。当一个特定的iBeacons到达你附近时你应该设置这个iBeacons附近的标志。的 CLProximityNear 强>
当标志远离 CLProximityFar 时,标志将会关闭。
所以你需要做下面的步骤。
确保您需要管理单独标志的所有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语句。