区域监控当前位置在退出时不通知 [英] Region monitoring current location doesn't notify on exit

查看:184
本文介绍了区域监控当前位置在退出时不通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试测试区域监控,因为我正在获得这样的当前位置:

I'm trying to test region monitoring, for that I'm getting current location like this:

- (void)startLocationTracking
{
    CLLocationManager *locationManager = [[CLLocationManager alloc] init];

    // Start location manager
    if ([CLLocationManager locationServicesEnabled] && [CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized) {
        locationManager = [LocationTracker sharedLocationManager];
        locationManager.delegate = self;
        [locationManager startMonitoringSignificantLocationChanges];
    }
}

跟踪区域监控的第一个位置,如下所示:

And tracking first location with region monitoring like this:

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        CLRegion *region = [[CLRegion alloc] initCircularRegionWithCenter:manager.location.coordinate radius:300 identifier:@"first location initializer"];

        NSLog(@"0: %@", manager.location);
        NSLog(@"1: %@", region);

        [manager startMonitoringForRegion:region];
        NSLog(@"[locationManager startMonitoringForRegion:%@];", region);
    });
}

然后在当前区域的每个出口处,我正在监控这样的新位置:

Then in every exit from current region I'm monitoring the new location like this:

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    NSLog(@"%s, %@", __PRETTY_FUNCTION__, region);
}

- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
    NSLog(@"%s, %@", __PRETTY_FUNCTION__, region);

    NSArray *allRegions = manager.monitoredRegions.allObjects;

    if (allRegions.count > 0) {
        for (CLRegion *reg in allRegions) {
            [manager stopMonitoringForRegion:reg];
        }
    }

    CLLocationCoordinate2D cord = CLLocationCoordinate2DMake(manager.location.coordinate.latitude, manager.location.coordinate.longitude);
    CLRegion *regionNew = [[CLRegion alloc] initCircularRegionWithCenter:cord radius:300 identifier:@"new region"];

    NSLog(@"region: %@", region);
    NSLog(@"regionNew: %@", regionNew);

    [manager startMonitoringForRegion:regionNew];
}

我会解释我期望发生的事情:

I'll explain what I expect to happen:


  1. 在区域监控中注册当前位置。

  2. 通知用户退出当前区域。

  3. 退出日志并再次将当前位置注册为区域。

这不会发生。

我哪里错了?

我尝试使用'Freeway Drive'模拟器。

I tried on simulator with 'Freeway Drive'.

更新:

经过测试和工作,由于地理围栏中的Apple漏洞,应用程序仅支持7.1+,非常糟糕但我不喜欢我有另一个想法。

Tested and work, due to Apple bug in geofencing, app will support only 7.1+, pretty bad but I don't have an another idea.

推荐答案

我认为实施区域监控的方式可能会导致一些问题。

I think the way you implement the region monitoring might cause some problems.

原因如下: -


  1. <$> c $ c> startLocationTracking 方法,您的 locationManager 是一个本地对象,它不会延伸到该方法的生命周期。这也意味着每次调用 startLocationTracking 时,都会有一个新的 locationManager 对象,该对象被分配一个新块记忆

  1. Inside the startLocationTracking method, your locationManager is a local object that does not extend over the life cycle of that method. It also means that every time you call startLocationTracking, there will be a new locationManagerobject that is allocated with a new block of memory.

要解决此问题:您应该使用共享的单例 locationManager 应用程序整个生命周期的 locationManager

To solve this problem: You should use a singleton locationManager that is a shared locationManager for the entire life cycle of the Application.

我认为你不应该在委托方法 startMonitoringForRegion - (void )locationManager :( CLLocationManager *)manager didUpdateLocations:。原因是,如果您再次调用 startLocationTracking ,则会有多个locationManager。多个locationManagers可以监视可能导致多个通知的同一区域。

I believe you should not startMonitoringForRegion inside the delegate method -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:. The reason is, if you call startLocationTracking more once, there will be more than one locationManager. Multiple locationManagers could monitor the same region which may cause multiple notifications.

调用 [manager startMonitoringForRegion:region]; 后,将不会立即监视该区域。如果您不相信我,请尝试以下代码: -

After you call [manager startMonitoringForRegion:region];, the region will not be monitored immediately. If you do not believe believe me, try the follow code:-

[locationManager startMonitoringForRegion:region];
NSLog(@"%@",locationManager.monitoredRegions);


你会发现你所在的地区刚监控不会在 locationManager.monitoredRegions 内。由于这是在iOS级别处理的,因此,我认为可能需要几分钟时间才能让该区域进行监控。

You will find out that the region that you just monitored will not be inside the locationManager.monitoredRegions. Since this is handled on the iOS level, so, I think it might need a few minutes for the region to be ready to be monitored.

您还应该了解其他限制 iOS中的区域监控: -

You should also understand other limitations for Region Monitoring in iOS:-

https://developer.apple.com/library/mac/documentation/CoreLocation/Reference/CLLocationManager_Class/CLLocationManager/CLLocationManager.html


一个应用程序一次最多可以注册20个区域。为了及时报告
区域变化,区域监控服务
需要网络连接。

An app can register up to 20 regions at a time. In order to report region changes in a timely manner, the region monitoring service requires network connectivity.

在iOS 6中,半径区域在iPhone 4S或更高版本的设备上,1到400米之间的效果会更好
。 (在iOS 5中,半径为
的区域在1到150米之间的区域在iPhone 4S和更高版本的设备上运行得更好。)
在这些设备上,应用程序可以获得输入的相应区域
或者区域在3到5分钟内退出通知,平均价格为
,如果不是更早的话。

In iOS 6, regions with a radius between 1 and 400 meters work better on iPhone 4S or later devices. (In iOS 5, regions with a radius between 1 and 150 meters work better on iPhone 4S and later devices.) On these devices, an app can expect to receive the appropriate region entered or region exited notification within 3 to 5 minutes on average, if not sooner.

注意:应用程序可以在设备移动500美元后立即收到通知从之前的通知中获得b $ b米或更多。它不应该比每五分钟更频繁地预期
通知。如果
设备能够从网络中检索数据,则位置管理员
更有可能及时发送通知。

Note: Apps can expect a notification as soon as the device moves 500 meters or more from its previous notification. It should not expect notifications more frequently than once every five minutes. If the device is able to retrieve data from the network, the location manager is much more likely to deliver notifications in a timely manner.

我不知道你的应用是什么,我相信你应该重新设计应用程序的流程。您应该尝试监视委托方法之外的区域。

I don't know what your app is about, I believe you should redesign the flow of your app. You should try to monitor the region outside of the delegate methods.

有关 Singleton LocationManager 的详细信息,您可以查看以下答案:后台位置服务在iOS 7中不起作用。 GitHub上有一个包含 Singleton LocationManager类的完整项目,我将其命名为 LocationTracker

For more information about the Singleton LocationManager, you may check out this answer: Background Location Services not working in iOS 7. There is a complete project on GitHub that contains a Singleton LocationManager class that I named as LocationTracker.

你可能还想查看我在一个月前发现的iOS 7中的区域监控故障(解决故障的解决方法):区域监控iOS 7上的故障 - 同时发出多个通知

You might also want to check out a glitch for Region Monitoring in iOS 7 that I found out a month ago (with a workaround to solve the glitch): Region Monitoring Glitch on iOS 7 - Multiple Notifications at the same time

这篇关于区域监控当前位置在退出时不通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆