显著改变位置委托方法不会被调用

问题描述:

我所有的代码是在AppDelegate.m:显著改变位置委托方法不会被调用

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]]; 

    _locationMgr = [[CLLocationManager alloc] init]; 
    [_locationMgr setDelegate:self]; 
    if([_locationMgr respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) 
     [_locationMgr setAllowsBackgroundLocationUpdates:YES]; 
    CLAuthorizationStatus authorizationStatus= [CLLocationManager authorizationStatus]; 

    if([launchOptions valueForKey:UIApplicationLaunchOptionsLocationKey] != nil) { 
     NSLog(@"relaunching because of significant location change - restarting SLC"); 
     [_locationMgr startMonitoringSignificantLocationChanges]; 
    } 
    else 
    { 
     if (authorizationStatus == kCLAuthorizationStatusAuthorizedAlways) { 
      NSLog(@"launching with authorization to always use location - starting SLC"); 
      [_locationMgr startMonitoringSignificantLocationChanges]; 
     } 
     else 
     { 
      NSLog(@"launching with no authorization to always use location - requesting authorization"); 
      if([_locationMgr respondsToSelector:@selector(requestAlwaysAuthorization)]) 
       [_locationMgr requestAlwaysAuthorization]; 
     } 
    } 

    if([userdefaults objectForKey:@"pfuser"] == nil) { 
     NSLog(@"in delegate signup"); 
     SignUpController *signup = [[SignUpController alloc] init]; 
     [self.window setRootViewController:signup]; 
    } 
    else { 
     ViewController *map = [[ViewController alloc] init]; 
     [self.window setRootViewController:map]; 
    } 
    [self.window makeKeyAndVisible]; 

    return YES; 
} 

- (void)startSignificantChangeUpdates 
{ 
    deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"START" message:@"startSignificantChangeUpdates called" preferredStyle:UIAlertControllerStyleAlert]; 

    [deviceNotFoundAlertController addAction:deviceNotFoundAlert]; 
    // Create the location manager if this object does not 
    // already have one. 
    if (nil == _locationMgr) { 
     _locationMgr = [[CLLocationManager alloc] init]; 
     _locationMgr.delegate = self; 
    } 

    [CLLocationManager significantLocationChangeMonitoringAvailable]; 
    [_locationMgr startMonitoringSignificantLocationChanges]; 
} 

-(void)locationManger:(CLLocationManager *)manager didFailWithError:(NSError *)error { 
    NSLog(@"didFailWithError: %@", error); 
    deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"LOCATION FAIL" message:@"didFailWithError" preferredStyle:UIAlertControllerStyleAlert]; 

    [deviceNotFoundAlertController addAction:deviceNotFoundAlert]; 
} 

// Delegate method from the CLLocationManagerDelegate protocol. 
- (void)_locationManager:(CLLocationManager *)manager 
     didUpdateLocations:(NSArray *)locations { 
    deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"LOCATION UPDATE" message:@"didUpdateLocations called" preferredStyle:UIAlertControllerStyleAlert]; 

    [deviceNotFoundAlertController addAction:deviceNotFoundAlert]; 
    // If it's a relatively recent event, turn off updates to save power. 
    CLLocation* location = [locations lastObject]; 
    NSDate* eventDate = location.timestamp; 
    NSTimeInterval howRecent = [eventDate timeIntervalSinceNow]; 
    if (fabs(howRecent) < 15.0) { 
     // If the event is recent, do something with it. 
     NSLog(@"latitude %+.6f, longitude %+.6f\n", 
       location.coordinate.latitude, 
       location.coordinate.longitude); 
    } 
} 

警报都没有发生,似乎没有被称为委托方法。

UPDATE

现在我有:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]]; 

    deviceNotFoundAlert = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]; 

    ... 

} 

// Delegate method from the CLLocationManagerDelegate protocol. 
- (void)locationManager:(CLLocationManager *)manager 
     didUpdateLocations:(NSArray *)locations { 
    deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"LOCATION UPDATE" message:@"didUpdateLocations called" preferredStyle:UIAlertControllerStyleAlert]; 

    [deviceNotFoundAlertController addAction:deviceNotFoundAlert]; 
    // If it's a relatively recent event, turn off updates to save power. 
    CLLocation* location = [locations lastObject]; 
    NSDate* eventDate = location.timestamp; 
    NSTimeInterval howRecent = [eventDate timeIntervalSinceNow]; 
    if (fabs(howRecent) < 15.0) { 
     // If the event is recent, do something with it. 
     NSLog(@"latitude %+.6f, longitude %+.6f\n", 
       location.coordinate.latitude, 
       location.coordinate.longitude); 
    } 
} 

当我测试的应用程序,我打开它在我的房子,然后将其关闭,这样,当我离开我的房子应该送(或3),但我没有收到来自任何委托方法(我放置警报的位置)的警报。

我刚刚有一个想法,也许我必须显示从主UIViewController,而不是AppDelegate警报?

这可能就是为什么我没有看到警报:How do I add a UIAlertController in app delegate (obj-c)

UPDATE

这就是我正在做的警报现在:

deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"START" message:@"startSignificantChangeUpdates called" preferredStyle:UIAlertControllerStyleAlert]; 

[deviceNotFoundAlertController addAction:deviceNotFoundAlert]; 

alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 
alertWindow.rootViewController = [[UIViewController alloc] init]; 
alertWindow.windowLevel = UIWindowLevelAlert + 1; 
[alertWindow makeKeyAndVisible]; 
[alertWindow.rootViewController presentViewController:deviceNotFoundAlertController animated:YES completion:nil]; 

UPDATE

警报似乎不是问题,麦芽酒rt startSignificantChangeUpdates从未出现。一旦我离开我的初始位置500米后,它会出现吗?

UPDATE

谁能帮助我理解?

您的委托对象的方法是从您启动相应位置服务的线程中调用的。该线程本身必须有一个活动的运行循环,就像在应用程序的主线程中找到的一样。

UPDATE

我想我想通了什么,以上报价是说......我有现在这样 - 我明天将测试。

... 

if([launchOptions valueForKey:UIApplicationLaunchOptionsLocationKey] != nil) { 
     NSLog(@"relaunching because of significant location change - restarting SLC"); 
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
      [_locationMgr startMonitoringSignificantLocationChanges]; 
     }); 
    } 
    else 
    { 
     if (authorizationStatus == kCLAuthorizationStatusAuthorizedAlways) { 
      NSLog(@"launching with authorization to always use location - starting SLC"); 
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
       [_locationMgr startMonitoringSignificantLocationChanges]; 
      }); 
     } 
     else 
     { 
      NSLog(@"launching with no authorization to always use location - requesting authorization"); 
      if([_locationMgr respondsToSelector:@selector(requestAlwaysAuthorization)]) 
       [_locationMgr requestAlwaysAuthorization]; 
     } 
    } 

... 

我认为代码是在自己的线程上启动位置服务。我注意到的一件事是,当我退出应用程序时,右上角的位置消失。我刚刚更新到了iOS 10.在iOS 9中,右上角的位置箭头将停留在那里,但当应用程序未运行时,它只会是黑色轮廓。这可能只是他们在iOS 10中改变的东西,或者现在因为我已更新到10,现在还没有其他工作。或者当位置服务在自己的线程上运行时会发生什么情况。从这里:iOS start Background Thread

UPDATE

也许我没有正确地使用线程,但正如我所说的,现在当我关闭应用程序,位置服务退出。当我在没有线程的情况下执行时,位置服务箭头将保留在右上角,作为大纲。

UPDATE

,我读了服务应该在主线程启动 - 所以我现在:

CLAuthorizationStatus authorizationStatus= [CLLocationManager authorizationStatus]; 

    NSLog(@"launching with no authorization to always use location - requesting authorization"); 
    if([_locationMgr respondsToSelector:@selector(requestAlwaysAuthorization)]) { 
     [_locationMgr requestAlwaysAuthorization]; 
    } 

    if([launchOptions valueForKey:UIApplicationLaunchOptionsLocationKey] != nil) { 
     NSLog(@"relaunching because of significant location change - restarting SLC"); 
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
      [_locationMgr startMonitoringSignificantLocationChanges]; 
     }); 
    } 
    else if (authorizationStatus == kCLAuthorizationStatusAuthorizedAlways) { 
     NSLog(@"launching with authorization to always use location - starting SLC"); 
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
      [_locationMgr startMonitoringSignificantLocationChanges]; 
     }); 
    } 
    else { 
     // 
    } 

中不显示时,应用程序是右侧的箭头关闭,这是iOS 10的新功能,它们不再显示它吗?

UPDATE

我不小心删除:_locationMgr = [[CLLocationManager alloc] init];我把现在的箭头是永远存在的,今天要测试。

UPDATE

我测试了,仍然没有警报。

+0

您是否配置了使用位置服务的plist?如果没有,那么你需要做到这一点。有两个选项requestAlwaysAuthorization和requestWhenInUseAuthorization。让我知道如果这可以解决您的问题 – Janmenjaya

+0

嗨,是的,我有 - 当我输入它时,更改为“隐私 - 位置总是使用说明”,然后我在另一列中输入消息...现在实际上有些不同了...我想我需要再次测试生病让你知道 – ewizard

+0

我也有'需要的背景模式'与'Item0'和'应用程序寄存器的位置更新' – ewizard

我把我的电脑我在我的车,并观看了控制台,我看到显著位置的变化正在发生,因为我得到的位置更新每隔500米。警报是唯一不起作用的,但与程序无关 - 他们只是在那里看看它是否工作。它正在使用此代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]]; 

    ... 

    _locationMgr = [[CLLocationManager alloc] init]; 
    [_locationMgr setDelegate:self]; 

    if([_locationMgr respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) 
     [_locationMgr setAllowsBackgroundLocationUpdates:YES]; 

    CLAuthorizationStatus authorizationStatus= [CLLocationManager authorizationStatus]; 

    NSLog(@"launching with no authorization to always use location - requesting authorization"); 
    if([_locationMgr respondsToSelector:@selector(requestAlwaysAuthorization)]) { 
     [_locationMgr requestAlwaysAuthorization]; 
    } 

    if([launchOptions valueForKey:UIApplicationLaunchOptionsLocationKey] != nil) { 
     NSLog(@"relaunching because of significant location change - restarting SLC"); 
     [_locationMgr startMonitoringSignificantLocationChanges]; 
    } 
    else if (authorizationStatus == kCLAuthorizationStatusAuthorizedAlways) { 
     NSLog(@"launching with authorization to always use location - starting SLC"); 
     [_locationMgr startMonitoringSignificantLocationChanges]; 
    } 
    else { 
     // 
    } 

    ... 

    [self.window makeKeyAndVisible]; 

    return YES; 
} 

- (void)startSignificantChangeUpdates 
{ 
    // Create the location manager if this object does not 
    // already have one. 
    if (nil == _locationMgr) { 
     _locationMgr = [[CLLocationManager alloc] init]; 
     _locationMgr.delegate = self; 
    } 

    [CLLocationManager significantLocationChangeMonitoringAvailable]; 

    [_locationMgr startMonitoringSignificantLocationChanges]; 

    deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"START" message:@"startSignificantChangeUpdates called" preferredStyle:UIAlertControllerStyleAlert]; 

} 

-(void)locationManger:(CLLocationManager *)manager didFailWithError:(NSError *)error { 
    NSLog(@"didFailWithError: %@", error); 
} 

// Delegate method from the CLLocationManagerDelegate protocol. 
- (void)locationManager:(CLLocationManager *)manager 
     didUpdateLocations:(NSArray *)locations { 

    // If it's a relatively recent event, turn off updates to save power. 
    CLLocation* location = [locations lastObject]; 
    NSDate* eventDate = location.timestamp; 
    NSTimeInterval howRecent = [eventDate timeIntervalSinceNow]; 
    if (fabs(howRecent) < 15.0) { 
     // If the event is recent, do something with it. 
     NSLog(@"latitude %+.6f, longitude %+.6f\n", 
       location.coordinate.latitude, 
       location.coordinate.longitude); 
    } 
} 

它与您的委托方法有问题请及时与

- (void)locationManager:(CLLocationManager *)manager 
     didUpdateLocations:(NSArray *)locations { 
} 

希望它会帮助你更换一个下面

- (void)_locationManager:(CLLocationManager *)manager 
     didUpdateLocations:(NSArray *)locations { 
} 

+0

awesome catch ....都是因为find + replace。 ..我会尽快尝试,谢谢 – ewizard

+0

我做了改变 - 但我仍然没有得到任何警报。另外,我不应该从'startSignificantChangeUpdates'得到警报吗? – ewizard

+0

我可能已经得到它的工作,我需要再次测试......一个主要问题是,我从来没有实例化'deviceNotFoundAlert' – ewizard

You have written write code, Just add below delegate method in your code. But startMonitoringSignificantLocationChanges for updating location take 10 to 20 min. and also trigger if location channel change. 

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations 
{ 

} 

[_locationMgr startMonitoringSignificantLocationChanges];

重大更改位置服务仅在设备的位置发生重大变化(例如500米或更高)时才会提供更新。

因此,当您的设备移动超过500米时,您的委托方法会每次调用一次。

确保您的应用具有后台位置权限。

如果您的应用程序在后台或前台,那么它将调用委托方法 否则应用程序将在AppDelegate文件中启动位置选项,您必须创建位置管理器对象并再次启动位置以获取新位置。

https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html

+0

我有背景权限,它不能在500m +后工作 - 我的代码看起来是否正确? – ewizard

+0

在位置委托方法中调用本地通知,确保新的委托方法。并移动约2公里。它说500+米不叫精确500米,有时需要更多的距离取决于网络服务。所以你可以识别。它的工作我测试了它 –