使用Core Data获取CLRegion 20区域上限的位置提醒 [英] Location alerts using Core Data to get around CLRegion 20 region cap

查看:230
本文介绍了使用Core Data获取CLRegion 20区域上限的位置提醒的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序将兴趣点(POI)存储在Core Data managedObjectContext 中。我的目标是如果 currentLocation managedObjectContext 中的POI的指定范围内,则警报消失。在阅读 CLRegion 时,可以监控的地区数量上限为20。



我的游戏计划是在我的 managedObjectContext 中搜索纬度/经度坐标,并计算POI之间的距离,每次我的位置管理器的 didUpdateLocations fires在我的应用程序:

   - (void)locationManager:(CLLocationManager *)manager didUpdateLocations: *)locations {
CLLocation * location = [locations lastObject];
NSLog(@LocationManager Latitude%+。6f,Longitude%+。6f \\\

location.coordinate.latitude,
location.coordinate.longitude);
// TODO:计算managedObjectContext中对象之间的距离
[self calculateDistances];
self.currentLocation = location;
}

//计算距离的方法
- (void)calculateDistances {

//对于managedObjectContext中的POI,执行以下
CLLocation * locA = [[CLLocation alloc] initWithLatitude:self.currentLocation.coordinate.latitude longitude:self.currentLocation.coordinate.longitude];

CLLocation * locB = [[CLLocation alloc] initWithLatitude:POIlatitude longitude:POIlongitude];

CLLocationDistance distance = [locA distanceFromLocation:locB];

if(distance< 1000){
//弹出式提醒
}

}

我只用 managedObjectContext 来显示数据。在这种情况下,我不显示任何东西 - 相反,我只是通过 MOC 中的对象运行 didUpdateLocations 火灾,拉出坐标和计算距离。

我把我的类命名为 LocationManager 它是一个单例类。在标题中,我为 NSManagedObjectContext 添加了一个属性。



.h

  @property(nonatomic,weak)NSManagedObjectContext * managedObjectContext; 

我的Core数据栈在我的AppDelegate,所以我调整了我的 LocationManager 实现以查看它:



.m

   - (id)init {
self = [super init];
if(!self.locationManager){
//这样我可以获得对managedObjectContext的引用
AppDelegate * appDelegate = [[UIApplication sharedApplication] delegate];
self.managedObjectContext = appDelegate.managedObjectContext;

self.locationManager = [[CLLocationManager alloc] init];

if([self.locationManager responsesToSelector:@selector(requestAlwaysAuthorization)]){
[self.locationManager requestAlwaysAuthorization];
}

self.locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
self.locationManager.distanceFilter = 100; // meters
self.locationManager.delegate = self;
}
return self;
}

进一步向下,当 didUpdateLocations 方法触发,我添加了对 [self calculateDistances] 的调用,如下所示:

   - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
CLLocation * location = [locations lastObject];
NSLog(@LocationManager Latitude%+。6f,Longitude%+。6f \\\

location.coordinate.latitude,
location.coordinate.longitude);
[self calculateDistances];
self.currentLocation = location;
}

//计算距离的方法
- (void)calculateDistances {

NSError * error;
NSFetchRequest * coordinateRetrieval = [[NSFetchRequest alloc] initWithEntityName:@PointOfInterest];
NSArray * pois = [self.managedObjectContext executeFetchRequest:coordinateRetrieval error:& error];

for(PointOfInterest * venue in poi){
CLLocation * locA = self.currentLocation;
CLLocation * locB = [[CLLocation alloc] initWithLatitude:[venue.latitude doubleValue] longitude:[venue.longitude doubleValue]];
CLLocationDistance distance = [locA distanceFromLocation:locB];

if(distance <1000){
//弹出警报
}
NSLog(@当前位置到会场的距离为%lf米 );
}
}


I have an app that stores points of interest (POIs) in a Core Data managedObjectContext. My objective is to have alerts go off if currentLocation is within a specified range of a POI in the managedObjectContext. In reading about CLRegion, it seems the amount of regions that can be monitored is capped at 20.

To get around the region monitoring cap, my game plan is to skim my managedObjectContext for latitude/longitude coordinates and compute distances between POIs every time my location manager's didUpdateLocations fires in my app:

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
    CLLocation *location = [locations lastObject];
    NSLog(@"LocationManager Latitude %+.6f, Longitude %+.6f\n",
          location.coordinate.latitude,
          location.coordinate.longitude);
    // TODO: compute distances between objects in managedObjectContext
    [self calculateDistances];
    self.currentLocation = location;
}

// method to compute distances
- (void) calculateDistances {

    // for POI in managedObjectContext, do the following
    CLLocation *locA = [[CLLocation alloc] initWithLatitude:self.currentLocation.coordinate.latitude longitude:self.currentLocation.coordinate.longitude];

    CLLocation *locB = [[CLLocation alloc] initWithLatitude:POIlatitude longitude:POIlongitude];

    CLLocationDistance distance = [locA distanceFromLocation:locB];

    if (distance < 1000) {
        // popup alert
    }

}

I've only used managedObjectContext to display data. In this case, I'm not displaying anything--instead, I'm just running through the objects in my MOC when didUpdateLocations fires, pulling out coordinates and computing a distance. Any ideas how to accomplish this?

解决方案

I called my class LocationManager and it's a singleton class. In the header, I added a property for NSManagedObjectContext.

.h

@property (nonatomic, weak) NSManagedObjectContext *managedObjectContext;

My Core Data stack is in my AppDelegate, so I tweaked the init method of my LocationManager implementation to "see" it:

.m

- (id)init {
    self = [super init];
    if (!self.locationManager) {
        // This is so I can get a reference to the managedObjectContext
        AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
        self.managedObjectContext = appDelegate.managedObjectContext;

        self.locationManager = [[CLLocationManager alloc]init];

        if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
            [self.locationManager requestAlwaysAuthorization];
        }

        self.locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
        self.locationManager.distanceFilter = 100; // meters
        self.locationManager.delegate = self;
    }
    return self;
}

Further down, when the didUpdateLocations method fires, I added a call to [self calculateDistances], like so:

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
    CLLocation *location = [locations lastObject];
    NSLog(@"LocationManager Latitude %+.6f, Longitude %+.6f\n",
          location.coordinate.latitude,
          location.coordinate.longitude);
    [self calculateDistances];
    self.currentLocation = location;
}

// method to compute distances
- (void) calculateDistances {

    NSError *error;
    NSFetchRequest *coordinateRetrieval = [[NSFetchRequest alloc]initWithEntityName:@"PointOfInterest"];
    NSArray *pois = [self.managedObjectContext executeFetchRequest:coordinateRetrieval error:&error];

    for (PointOfInterest *venue in poi) {
        CLLocation *locA = self.currentLocation;
        CLLocation *locB = [[CLLocation alloc]initWithLatitude:[venue.latitude doubleValue] longitude:[venue.longitude doubleValue]];
        CLLocationDistance distance = [locA distanceFromLocation:locB];

        if (distance < 1000) {
            // popup alert
        }
        NSLog(@"The distance from currentLocation to venue is %lf meters", distance);
    }
}

这篇关于使用Core Data获取CLRegion 20区域上限的位置提醒的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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