显著改变位置委托方法不会被调用
我所有的代码是在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
我测试了,仍然没有警报。
我把我的电脑我在我的车,并观看了控制台,我看到显著位置的变化正在发生,因为我得到的位置更新每隔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 {
}
。
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文件中启动位置选项,您必须创建位置管理器对象并再次启动位置以获取新位置。
我有背景权限,它不能在500m +后工作 - 我的代码看起来是否正确? – ewizard
在位置委托方法中调用本地通知,确保新的委托方法。并移动约2公里。它说500+米不叫精确500米,有时需要更多的距离取决于网络服务。所以你可以识别。它的工作我测试了它 –
您是否配置了使用位置服务的plist?如果没有,那么你需要做到这一点。有两个选项requestAlwaysAuthorization和requestWhenInUseAuthorization。让我知道如果这可以解决您的问题 – Janmenjaya
嗨,是的,我有 - 当我输入它时,更改为“隐私 - 位置总是使用说明”,然后我在另一列中输入消息...现在实际上有些不同了...我想我需要再次测试生病让你知道 – ewizard
我也有'需要的背景模式'与'Item0'和'应用程序寄存器的位置更新' – ewizard