ios – 没有调用重要的更改位置委托方法

我的所有代码都在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,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

警报似乎不是问题,startSignificantChangeUpdates中的警报永远不会出现.一旦我距离我的初始位置500米,它应该出现吗?

UPDATE

任何人都可以帮我理解这个吗?

The methods of your delegate object are called from the thread in which you started the corresponding location services. That thread must itself have an active run loop,like the one found in your application’s main thread.

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,^{
                [_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,^{
            [_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,^{
            [_locationMgr startMonitoringSignificantLocationChanges];
        });
    }
    else {
        //
    }

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

UPDATE

我不小心删了:_locationMgr = [[CLLocationManager alloc] init];我投入,现在箭头总是在那里,今天要去测试.

UPDATE

我测试了它,仍然没有警报.

解决方法

这是您的委托方法的问题,请在下面替换
- (void)_locationManager:(CLLocationManager *)manager
      didUpdateLocations:(NSArray *)locations {
}

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

希望它会对你有所帮助.

相关文章

UITabBarController 是 iOS 中用于管理和显示选项卡界面的一...
UITableView的重用机制避免了频繁创建和销毁单元格的开销,使...
Objective-C中,类的实例变量(instance variables)和属性(...
从内存管理的角度来看,block可以作为方法的传入参数是因为b...
WKWebView 是 iOS 开发中用于显示网页内容的组件,它是在 iO...
OC中常用的多线程编程技术: 1. NSThread NSThread是Objecti...