2014-01-17 91 views
0

我试图显示一个通知,当我的应用程序在后台,并且设备进入一个iBeacon的区域,当他们的CLProximity在通知正在工作时,但它不断出现在1秒的间隔:当CLProximity附近显示背景通知

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region{ 
    NSLog(@"Entered beacon region"); 
    [self.locationManager startRangingBeaconsInRegion:self.beaconRegion]; 
} 

- (void) locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region{ 
    NSLog(@"Left region"); 
    [self.locationManager stopRangingBeaconsInRegion:self.beaconRegion]; 
} 

- (void) locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region { 
    [self.locationManager startRangingBeaconsInRegion:self.beaconRegion]; 
} 
- (void) locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region { 
    CLBeacon *beacon = [[CLBeacon alloc] init]; 
    beacon = [beacons lastObject]; 
    self.uuidLabel.text = beacon.proximityUUID.UUIDString; 

    if(beacon.proximity == CLProximityUnknown) { 
     distanceLabel.text = @"Unknown Proximity"; 
     [self.view setBackgroundColor:[UIColor grayColor]]; 
    } else if (beacon.proximity == CLProximityImmediate) { 
     distanceLabel.text = @"Immediate"; 
     [self.view setBackgroundColor:[UIColor redColor]]; 
    } else if (beacon.proximity == CLProximityNear) { 
     distanceLabel.text = @"Near"; 
     [self.view setBackgroundColor:[UIColor orangeColor]]; 
     UILocalNotification *inRange = [[UILocalNotification alloc] init]; 
     inRange.alertBody = [NSString stringWithFormat:@"Entered region!"]; 
     inRange.soundName = UILocalNotificationDefaultSoundName; 
     [[UIApplication sharedApplication] presentLocalNotificationNow:inRange]; 
    } else if (beacon.proximity == CLProximityFar) { 
     distanceLabel.text = @"Far"; 
     [self.view setBackgroundColor:[UIColor blueColor]]; 

    } 
} 

如果有一个方法调用后显示的通知,告诉它已经显示的应用程序,而不是继续调用方法didRangeBeacons直到用户超出范围并重新?

回答

1

的多个通知可以解决这样的:

如果您只想发送一次通知,简单地定义一个alreadyDisplayed标志,被发送的通知之后被设置,那么之前检查它的值发送。

像这样:

BOOL alreadyDisplayed = NO; 

... 

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

    ... 

    else if (beacon.proximity == CLProximityNear) { 
    distanceLabel.text = @"Near"; 
    if (!alreadyDisplayed) { 
     [self.view setBackgroundColor:[UIColor orangeColor]]; 
     alreadyDisplayed = YES; 
     UILocalNotification *inRange = [[UILocalNotification alloc] init]; 
     inRange.alertBody = [NSString stringWithFormat:@"Entered region!"]; 
     inRange.soundName = UILocalNotificationDefaultSoundName; 
     [[UIApplication sharedApplication] presentLocalNotificationNow:inRange]; 
    } 
    } 

... 

} 

但你仍然有第二个问题:

如果你想这样做的背景你的问题标题所暗示的,这是不会一起工作。问题在于,iOS检测到您的手机在后台进入了iBeacon区域后,它只会让其在进入睡眠状态之前运行五秒钟。由于iBeacon的范围大约为50米,因此最有可能的情况是,当您处于50米范围的边缘时,此5秒间隔将开始。用户行走得如此之快以至于他们在应用程序进入睡眠状态之前的5秒内进入“近”接近状态的可能性非常小。出于这个原因,当你在后台时,通常不可能根据特定的邻近度采取特定的操作。

也就是说,如果您想在前台执行此操作,那么如果您进行更改以防止每秒发出通知,那么这将工作得很好。

+0

因此,当用户跨越边界时,计算出跨越区域的时间间隔,以确定显示通知的适当时间,是否更好? –

+0

我不确定这有帮助。在后台,您的应用只能在边界穿越后运行五秒钟。如果用户步行到“near”附近需要15秒,那么您的应用程序将不会运行,并且根本无法显示通知。如果你等到下一次你的应用程序被唤醒,那就太迟了。不幸的是,这是iOS上的iBeacons的一个真正的限制,我不相信有一个解决方法。要在特定距离触发,您的应用必须处于前台。 – davidgyoung

1

当测距信标时,将按照您的标识每秒调用一次locationManager:didRangeBeacons:inRegion。每次,beacons参数将包含所有可见信标的数组。

您的应用需要包含逻辑来确定新的信标是否可见,或者您是否已经通知用户相关信息。我建议您存储一系列先前发现的信标,并且每次调用locationManager:didRangeBeacons:inRegion时都会将您的列表与beacons参数的内容进行比较。然后,您应该能够判断是否找到任何新的信标。