【问题标题】:location manager working on Always but not When In Use位置经理一直在工作,但在使用时不工作
【发布时间】:2019-02-19 18:47:34
【问题描述】:

在 Apple 坚持让用户在位置管理器的“始终”和“使用时”之间进行选择之前,我有一个运行良好的应用程序。 该应用程序使用 iBeacons 发送玩游戏的邀请并接受。
When "Always" is selected the beacons work fine but when I switch to "When In Use" they don't work at all. 我开始使用“始终”,但更改了以下代码以给用户选择。 在应用程序的 plist 中,我添加了“Privacy-Location Always and When In Use Usage Descriptions 和 Privacy-Location When In Use Usage Description”,并删除了“Privacy-Location Always Usage Description”。

在应用程序的委托中我有这个

- (void)locationManager:(CLLocationManager *)manager
didChangeAuthorizationStatus:(CLAuthorizationStatus)status{

    if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusAuthorizedAlways){
        NSLog(@"Always");
        AlertView2 = [[UIAlertView alloc] initWithTitle:@"Dual player on two devices is enabled."
                                                message:@"To save battery power go to Settings/Privacy/Location Services and choose \"Never\" when not using I'M GAME. Two people can still play on one device when in \"Never\" mode. To recieve invitations to play only when the app is open select \"When In Use\"."
                                               delegate:nil
                                      cancelButtonTitle:@"OK"
                                      otherButtonTitles:nil];
        [AlertView2 show];
        [[NSUserDefaults standardUserDefaults] setObject:@"YES" forKey:@"accessKey"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
    if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusAuthorizedWhenInUse){
        NSLog(@"WhenInUse");
        AlertView2 = [[UIAlertView alloc] initWithTitle:@"Dual player on two devices is enabled."
                                                message:@"To save battery power go to Settings/Privacy/Location Services and choose \"Never\" when not using I'M GAME. Two people can still play on one device when in \"Never\" mode. To recieve invitations to play while app is in background select \"Always\"."
                                               delegate:nil
                                      cancelButtonTitle:@"OK"
                                      otherButtonTitles:nil];
        [AlertView2 show];
        [[NSUserDefaults standardUserDefaults] setObject:@"YES" forKey:@"accessKey"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
    if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusRestricted){
        NSLog(@"restricted");
    }

    if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusDenied){
        NSLog(@"denied");
        AlertView2 = [[UIAlertView alloc] initWithTitle:@"Dual player on a single device Only."
                                                message:@"To play on two devices go to Settings Privacy/Location Services and choose \"Always\" or \"When In Use\" for I'M GAME. In \"Always\" you can recieve invites while app is in background, in \"When In Use\" invites only appear when the app is on screen. To preserve battery choose \"Never\" when not using I'M GAME."
                                               delegate:nil
                                      cancelButtonTitle:@"OK"
                                      otherButtonTitles:nil];
        [AlertView2 show];
        [[NSUserDefaults standardUserDefaults] setObject:@"YES" forKey:@"accessKey"];
        [[NSUserDefaults standardUserDefaults] synchronize];

    }
    if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusNotDetermined){
        NSLog(@"undetermined2");
         [locationManager requestAlwaysAuthorization];
       [locationManager requestWhenInUseAuthorization];
    }


}

iBeacon 是否需要将 Privacy-Location 设置为“始终”才能工作?

所以我刚刚发现,在“使用时”中,您无法监控信标区域是否进入或退出,只能找到其范围。所以我想问题是我将如何使用范围向我的用户发送通知。

【问题讨论】:

  • 我投票结束这个问题,因为这不是我们在这里发布代码的方式。
  • 你需要认真编辑这篇文章。查看How to Askhelp center,了解有关将帖子编辑为良好标准的更多信息。祝你好运!

标签: objective-c xcode cllocationmanager ibeacon


【解决方案1】:

当您的应用授权仅在前台执行信标测距时,只需一个 didRangeBeacons 回调即可轻松模拟进入/退出逻辑。

  1. 设置一个类变量:

    var beaconLastSeen: Date? = nil
    
  2. 将此代码添加到您的 didRangeBeacons 方法中:

    if beacons.count > 0 {
      if beaconLastSeen == nil {
         // call didEnterRegion logic here
      }
      beaconLastSeen = Date()
    }
    else {
      if beconLastSeen != nil && Date() - beaconLastSeen > 30 {
         beaconLastSeen = nil
         // call didExitRegion logic here
      }
    }
    

您将在最后一次信标检测后 30 秒收到退出事件。当你第一次看到一个时,你会得到一个 enter 事件。

编辑:这是 Objective C 中的相同代码:

NSDate *beaconLastSeen = nil;

...

if (beacons.count > 0) {
    if (beaconLastSeen == nil) {
        // call didEnterRegion logic here
    }
    beaconLastSeen = [[NSDate alloc] init];
}
else {
    if (beaconLastSeen != nil  && [[[NSDate alloc] init] timeIntervalSinceDate: beaconLastSeen] > 30 ) {
        beaconLastSeen = nil;
        // call didExitRegion logic here
    }
}

【讨论】:

  • 我正在使用 -(void)locationManager:(CLLocationManager*)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion*)region{ NSLog(@"manager didDetermineState state for Region"); UILocalNotification *notification = [[UILocalNotification alloc]init]; if(state == CLRegionStateInside){ 发送我的 didEnterRegion 通知。另外我将如何设置 var beaconLastSeen: Date?在objective-c中就是我正在使用的。
  • 抱歉,添加了 Objective C 版本
  • 谢谢,这对我来说很完美。现在,如果 Apple 只在飞行模式下为信标启动正确的硬件,用户就可以在飞行时邀请、接受和玩我的应用程序游戏。太糟糕了
  • 您可以检测蓝牙是否关闭并弹出一个对话框告诉用户打开它。您可以处于飞行模式并开启蓝牙——它只是在飞行模式下默认关闭。
  • 现在,当您在 Apple iOS 设备上打开“飞行模式”时,蓝牙仍处于开启状态,您可以将其用于耳机和数据传输,但根据 Apple 的说法,信标监控和测距所需的硬件不可用即使启用了蓝牙,也打开飞行模式时。不知道为什么。我已写信给 Apple 开发者技术帮助以寻求答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多