【发布时间】:2016-09-17 16:54:50
【问题描述】:
我所有的代码都在 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);
}
}
没有任何警报发生,似乎没有调用委托方法。
更新
现在我有:
- (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)
更新
这就是我现在做警报的方式:
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];
更新
警报似乎不是问题,startSignificantChangeUpdates 中的警报从未出现。它应该在我距离初始位置 500m 时出现吗?
更新
谁能帮我理解这个?
您的委托对象的方法是从您启动相应位置服务的线程中调用的。该线程本身必须有一个活动的运行循环,就像在您的应用程序的主线程中找到的那样。
更新
我想我明白上面引用的意思了......我现在知道了 - 我明天会测试。
...
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
更新
也许我没有正确使用线程,但正如我所说,现在当我关闭应用程序时,定位服务会退出。当我在没有线程的情况下执行此操作时,位置服务箭头将保留在右上角,作为轮廓。
更新
我读到该服务应该在主线程上启动 - 所以现在我有:
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 的新功能,不再显示了吗?
更新
我不小心删除了:_locationMgr = [[CLLocationManager alloc] init];我输入了,现在箭头一直在,今天去测试。
更新
我测试了它,仍然没有警报。
【问题讨论】:
-
您是否配置为使用 plist 中的定位服务?如果没有,那么你需要这样做。有两个选项 requestAlwaysAuthorization 和 requestWhenInUseAuthorization。让我知道这是否能解决您的问题
-
嗨,是的,我有 - 当我输入它时,它会更改为
Privacy - Location Always Usage Description,然后我在另一列中输入了一条消息......现在实际上有些不同......我想我需要再次测试生病让你知道 -
我也有
Required background modeswith`Item0` 和App registers for location updates
标签: ios objective-c properties background delegates