-->

didEnterRegion工作在前台而不是后台或其他风险投资(didEnterRegion wor

2019-06-28 04:23发布

如果应用程序正在运行,并且CLLocationManagerDelegate类是前景(即可见),那么didEnterRegions触发器和我同时获得的NSLog还有AlertView。 不过,我还是什么也没得到,当应用程序在后台运行,基本上,如果屏幕显示什么,但委托类。

我设置了“应用程序注册了位置更新”下的plist中“所需的背景模式”虽然我不知道这是甚至是必要的。

这就是我认为是相关的代码,虽然我可能是错的(并且会很乐意增加更多)。 我要指出,在vi​​ewDidLoad中一切都包裹在其中,如果检查,如果区域的监测可用并启用。

- (void)viewDidLoad
{
    NSLog(@"MapViewController - viewDidLoad");
    self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
    self.locationManager.distanceFilter = kCLLocationAccuracyNearestTenMeters;    
    self.locationManager.delegate = self;
    [self.locationManager startMonitoringSignificantLocationChanges];
}

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    NSLog(@"MapViewController - didEnterRegion");
    NSLog(@"MVC - didEnterRegion - region.radius = %f", region.radius);
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"entered region..." message:@"You have Entered the Location." delegate:nil cancelButtonTitle:@"OK"  otherButtonTitles: nil];
    alert.tag = 2;
    [alert show];
}

这里是我得到被监控区域的名单,在AppDelegate.m:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

// other code

NSLog(@"LISTING ALL REGIONS MONITORED");
    NSArray *regions = [self.locationManager.monitoredRegions allObjects];
    if (!regions) {
        NSLog(@"no regions found");
    } else {
        NSLog(@"got %d monitored regions", [regions count]);
        for (int i = 0; i < [regions count]; i++) {
            CLRegion *region = [regions objectAtIndex:i];
            NSLog(@"region %d's identifier = %@", i, region.identifier);
            NSLog(@"region: radius: %@", region.radius);
        }
    }

// other code
}

我打电话startMonitoringForRegion两次,这里的主要场所:

- (void)doneButtonTapped {
    NSLog(@"doneButtonTapped");

    if (self.locationIdentifier) {
        if ([CLLocationManager regionMonitoringEnabled] && [CLLocationManager regionMonitoringAvailable]) {

            // core data setup
            NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
            NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"LocationReminder" inManagedObjectContext:self.managedObjectContext];
            fetchRequest.entity = entityDescription;
            NSPredicate *predicate = [NSPredicate predicateWithFormat:@"locationIdentifier == %@", self.locationIdentifier];
            fetchRequest.predicate = predicate;
            NSError *error;
            NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
            if (results) {

                // get the LocationReminder
                LocationReminder *retrievedReminder = [results objectAtIndex:0];
                retrievedReminder.audioURI = [[[self.audioPlayers objectAtIndex:self.selectedCell] url] absoluteString];
                retrievedReminder.userRecording = nil;

                // start monitoring it's region
                NSArray *coordinateArray = [retrievedReminder.locationIdentifier componentsSeparatedByString:@", "];
                CLLocationCoordinate2D coordinate = {[[coordinateArray objectAtIndex:0] doubleValue], [[coordinateArray objectAtIndex:1] doubleValue]};
                CLRegion *newRegion = [[CLRegion alloc] initCircularRegionWithCenter:coordinate radius:250.0 identifier:retrievedReminder.locationIdentifier];
                NSLog(@"about to monitor region with radius: %f", newRegion.radius);
                [self.locationManager startMonitoringForRegion:newRegion desiredAccuracy:kCLLocationAccuracyBest];

                // save the LocationReminder
                if (![self.managedObjectContext save:&error]) {
                    NSLog(@"hmm.  no managed object context.  must be something space-time going on");
                } else {
                    NSLog(@"saved locationReminder, locationIdentifier = %@", retrievedReminder.locationIdentifier);
                }
            } else {
                NSLog(@"ERROR: no LocationReminder retreived for predicate: %@", predicate);
            }
        }

        // get the mapview controller off of the navigation stack
        for (UIViewController *viewController in self.navigationController.viewControllers) {
            if ([viewController isKindOfClass:[MapViewController class]]) { 
                MapViewController *mapVC = (MapViewController *)viewController;
                mapVC.audioURI = [[[self.audioPlayers objectAtIndex:self.selectedCell] url] absoluteString];
                [self.navigationController popToViewController:mapVC animated:YES];
            }
        }
}

而且因为我的感觉,这可能是重要的,下面是的LocationManager,吸气:

- (CLLocationManager *)locationManager {
    NSLog(@"MapViewController - locationManager");
    if (_locationManager) {
        return _locationManager;
    } else {
        _locationManager = [[CLLocationManager alloc] init];
        return _locationManager;
    }
}

更新1:通过苹果的论坛(在这里我crossposted)有人提到AlertView只会在前台显示。 仍然是的NSLog不火两种。 我猜想应该工作。

Answer 1:

我的一个朋友写了一个很好的教程使用地理界线,可以帮助清理你有一些问题。

开始使用地理围栏

有很多的例子在线和这里SO。 开始时很小,您的方式工作。 一旦你开始得到您的回调,你就可以开始扩大东西出来到其他视图控制器。

UPDATE

正如评论解释创建一个单独的类来控制你的位置,经理和委托方法的好处。 通过使用一个单身,可以防止进入您的委托方法多次调用的可能性。 您可以通过仔细的编码防止这种情况,但使用一个单独做这个给你。 这也是一个很好的类来处理所有的工作需要由您的委托方法来完成。



Answer 2:

事情你做错了:

  1. 背景模式 - 应用程序注册了位置更新。 这是没有必要的。 这是必要时要收集对位置等显著的变化信息,请转至目标>您的应用程序>支持购买,并选择在后台模式所需的选项。 这将自动为您更新的plist。 现在,禁用它。
  2. 您正在尝试当用户进入某个区域来创建警报。 虽然这个而当应用程序正在运行,报警是没有用的,当你的应用程序是在后台。 难道 -而触发本地通知或API调用。

例如。 的通知:

    -(void)triggerLocalNotification:(CLRegion *)region{
    UILocalNotification *notification = [[UILocalNotification alloc]init];
    [notification setAlertBody:[NSString stringWithFormat:@"Welcome to %@", [region identifier]]];
    [notification setRepeatInterval:0];
    [notification setFireDate:[NSDate dateWithTimeIntervalSinceNow:2]];
    [notification setTimeZone:[NSTimeZone  defaultTimeZone]];
    [[UIApplication sharedApplication]scheduleLocalNotification:notification];
    NSLog(@"notification triggered with notification %@", notification);
}


Answer 3:

当你didEnterRegion您可以发布一个本地通知。

这将显示,即使你在后台是一个警告般的弹出窗口。

你可以做一个简单的测试:

1)创建您的应用程序委托的applicationDidEnterBackground内本地通知对象,任何随机的消息,并告诉本地通知立即解雇。

2)按HOME按钮,当你的应用程序最小化,你应该会看到一个弹出。



Answer 4:

我认为你需要去你app.plist

并添加所需的背景模式:添加ITME应用寄存器位置更新

1。 如果你的应用程序是在后台,你仍然可以看到在上面的箭头

2,如果应用程序杀死,你仍然可以看到在顶部空心箭头,内部监督办公室将监测区域为你,但仅限于20个地区



文章来源: didEnterRegion works in foreground but not background or other VCs