我的所有代码都在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
中的警报从未出现过。一旦我离我的初始位置500米,它应该出现吗?
更新
任何人都可以帮我理解这个吗?
从您启动相应位置服务的线程调用委托对象的方法。该线程本身必须有一个活动的运行循环,就像在应用程序的主线程中找到的那样。
更新
我想我弄清楚上面引用的是什么......我现在有了这个 - 我明天会考试。
...
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];
我投入了,现在箭头一直在那里,今天要去测试。
更新
我测试了它,仍然没有警报。
答案 0 :(得分:2)
您的委托方法存在问题,请在下面替换
- (void)_locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations {
}
与
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations {
}
希望它会对你有所帮助。
答案 1 :(得分:2)
我带着我的电脑在我的车里,看着控制台,我看到现在正在发生重大的位置变化,因为我每隔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);
}
}
答案 2 :(得分:1)
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
{
}
答案 3 :(得分:1)
[_ locationMgr startMonitoringSignificantLocationChanges];
重要更改位置服务仅在设备位置发生重大变化(例如500米或更长)时才会提供更新。
因此,当您的设备移动超过500米时,您的委托方法每次都会调用一次。
确保您的应用具有后台位置权限。
如果您的应用是在后台或前台,那么它将调用委托方法 否则应用程序将在AppDelegate文件中使用location选项启动,您必须创建位置管理器对象并再次启动位置以获取新位置。