Ios 使用位置跟踪测试NSTimer

Ios 使用位置跟踪测试NSTimer,ios,iphone,nstimer,cllocationmanager,Ios,Iphone,Nstimer,Cllocationmanager,我有以下代码跟踪用户位置,并通过将当前用户位置的long和lat与今天事件的long和lat+匹配来检测用户是否在JSON文件中的指定事件中,当事件开始时间等于当前iPhone时间时,然后执行以下指令NSTimer for 5分钟和after 5分钟调用此方法onTick(),它将计算5分钟后的开始时间和当前时间之间的差异,如果仍然超过5分钟,则将此事件设置为有人参加。问题是,当我在我的iPhone上测试它时,它确实可以工作,但对于所有时间间隔超过5分钟的事件,即使我只想为用户当时所在的当前事件

我有以下代码跟踪用户位置,并通过将当前用户位置的long和lat与今天事件的long和lat+匹配来检测用户是否在JSON文件中的指定事件中,当事件开始时间等于当前iPhone时间时,然后执行以下指令NSTimer for 5分钟和after 5分钟调用此方法onTick(),它将计算5分钟后的开始时间和当前时间之间的差异,如果仍然超过5分钟,则将此事件设置为有人参加。问题是,当我在我的iPhone上测试它时,它确实可以工作,但对于所有时间间隔超过5分钟的事件,即使我只想为用户当时所在的当前事件工作!!有谁能给我解释一下为什么会发生这种情况,以及解决办法是什么。。我真的很困惑

这是我的密码:

    .h file
    @property (nonatomic, strong) Event *currentEvent;
    @property (nonatomic, strong) CLLocation *currentEventLocation;
    @property (nonatomic, strong) NSDate *arrivalDate;
    @property (nonatomic, strong) CLLocation *currentLocation;
    @property (nonatomic, strong) CLLocation *theNewLocation;



  .m file
- (void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {

self.currentLocation = [locations lastObject];

if (self.currentEvent) {
    if ([self.arrivalDate timeIntervalSinceNow]<60*3) {
        if ([self.currentEventLocation distanceFromLocation:self.theNewLocation]<100) {
            [self.currentEvent setHasATTENDED:[NSNumber numberWithBool:TRUE]];
        }
    }
}

self.currentLocation = self.theNewLocation;

for (Event *event in [self loadTodaysEvents]) {

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
    NSDate *currentTime = [NSDate date];
    [dateFormatter setDateFormat:@"HH:mm"];
    NSString *resultString = [dateFormatter stringFromDate:currentTime];

    NSString *eventStartTime = event.startingTime;

    // distance
    CLLocationDegrees lat = [event.lat doubleValue];
    CLLocationDegrees lon = [event.longi doubleValue];
    CLLocation *evLocation = [[CLLocation alloc] initWithLatitude:lat longitude:lon];
    double distance = [evLocation distanceFromLocation:self.theNewLocation];

    // CLOSE !
    if (distance <= 100 && [resultString isEqualToString:eventStartTime]) {
        self.arrivalDate = currentTime;
        self.currentEvent = event;
        self.currentEventLocation = evLocation;
        NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval: 180.0
                                                          target: self
                                                        selector: @selector(onTick:)
                                                        userInfo: nil
                                                         repeats: NO];

        NSRunLoop *runner = [NSRunLoop currentRunLoop];
        [runner addTimer:timer forMode: NSDefaultRunLoopMode];
    }
  }
}



- (void)onTick:(NSTimer *)timer
 {
  [self locationManager:nil didUpdateLocations:@[self.currentLocation]];
 }


- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {

 }
.h文件
@属性(非原子,强)事件*currentEvent;
@属性(非原子,强)CLLocation*currentEventLocation;
@属性(非原子,强)NSDate*到达日期;
@属性(非原子,强)CLLocation*currentLocation;
@属性(非原子,强)CLLocation*新位置;
.m文件
-(无效)位置管理器:(CLLocationManager*)管理器更新位置:(NSArray*)位置{
self.currentLocation=[locations lastObject];
if(self.currentEvent){

如果([self.arrivalDate timeintervalencenow]问题在于,在onTick方法中,您不测试是否仍处于同一事件中!您只需检查任何事件

您应该这样做:

存储他当前在NSTimer中参加的活动以及活动地点:

NSDictionary* userInfo = 
[NSDictionary dictionaryWithObjectsAndKeys:event,@"event",evLocation,@"location", nil]
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval: 180.0
                                                          target: self
                                                        selector: @selector(onTick:)
                                                        userInfo:userInfo
                                                         repeats: NO];
将上述代码替换为调用计时器的代码

当用户移动时,您还必须存储iPhone的当前位置,以检查他是否离开了活动

这也应该在
locationManager:didUpdateToLocation:fromLocation
调用中完成

例如,使用
@property(非原子,强)CLLocation*currentLocation;

locationManager:didUpdateToLocation:fromLocation的第一行中,只需设置
self.currentLocation=newLocation;

然后在
onTick
方法中检查您是否仍然接近:

CLLocation *evLocation = timer.userInfo[@"location"];
Event *event = timer.userInfo[@"event"];

double distance = [evLocation distanceFromLocation:self.currentLocation];

   // CLOSE !
    if (distance <= 100) {
    [event setHasATTENDED:[NSNumber numberWithBool:TRUE]];
                 // save
                  NSError *error = nil;
                  if (![_managedObjectContext save:&error])
                     {
                       NSLog(@"Error in saving");
                     }
  }
}
CLLocation*evLocation=timer.userInfo[@“location”];
Event*Event=timer.userInfo[@“Event”];
双距离=[evLocation distanceFromLocation:self.currentLocation];
//接近!

如果(距离)当应用程序在后台时,另一个答案也应该有效!你必须让位置管理器不断更新位置,这样你才能知道用户何时移动,并且不断调用
位置管理器:didUpdateToLocation:fromLocation:

@property (nonatomic, strong) Event* currentEvent;
@property (nonatomic, strong) CLLocation* currentEventLocation;
@property (nonatomic, strong) NSDate* arrivalDate;
@property (nonatomic, strong) CLLocation* currentLocation;



- (void) locationManager:(CLLocationManager *)manager
     didUpdateToLocation:(CLLocation *)newLocation
            fromLocation:(CLLocation *)oldLocation {

    if (self.currentEvent) {
        if ([self.arrivalDate timeIntervalSinceNow]<60*5) {
            if ([self.currentEventLocation distanceFromLocation:newLocation]<100) {
                [self.currentEvent setHasATTENDED:[NSNumber numberWithBool:TRUE]];
            }
        }
    }
    self.currentLocation = newLocation;

    for (Event *event in [self loadTodaysEvents]) {

        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
        NSDate *currentTime = [NSDate date];
        [dateFormatter setDateFormat:@"HH:mm"];
        NSString *resultString = [dateFormatter stringFromDate:currentTime];

        NSString *eventStartTime = event.startingTime;

        // distance
        CLLocationDegrees lat = [event.lat doubleValue];
        CLLocationDegrees lon = [event.longi doubleValue];
        CLLocation *evLocation = [[CLLocation alloc] initWithLatitude:lat longitude:lon];
        double distance = [evLocation distanceFromLocation:newLocation];

        // CLOSE !
        if (distance <= 100 && [resultString isEqualToString:eventStartTime]) {
            self.arrivalDate = currentTime;
            self.currentEvent = event;
            self.currentEventLocation = evLocation;
            NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval: 300.0
                                                              target: self
                                                            selector: @selector(onTick:)
                                                            userInfo: nil
                                                             repeats: NO];

            NSRunLoop *runner = [NSRunLoop currentRunLoop];
            [runner addTimer:timer forMode: NSDefaultRunLoopMode];
        }
    } 
}

- (void)onTick:(NSTimer *)timer
{
    [self locationManager:nil didUpdateToLocation:self.currentLocation fromLocation:self.currentLocation];
}
@property(非原子,强)事件*currentEvent;
@属性(非原子,强)CLLocation*currentEventLocation;
@属性(非原子,强)NSDate*到达日期;
@属性(非原子,强)CLLocation*currentLocation;
-(无效)locationManager:(CLLocationManager*)经理
DidUpdateLocation:(CLLocation*)newLocation
fromLocation:(CLLocation*)oldLocation{
if(self.currentEvent){

如果([self.arrivalDate timeIntervalSinceNow]因为计时器已经安排好了,您不需要将它添加到运行循环中!为什么要将[NSDate date]转换为NSString并返回到NSDate?我认为这行没有意义!请确保确实要检查此事件的开始时间是否与当前时间相同![结果字符串IseQualtString:eventStartTime]@NilsZiehn so r u说runloop是导致间隔超过5分钟的所有事件都被参与的人??因此,通过删除它,只有真正参与的才会被设置为参与??我认为onTick()中有问题方法!!@NilsZiehn NSDate是我的错。我知道我不应该这样做;pemm u r right..但是如果我想使用NSTimer,我必须调用选择器..还有其他方法吗?我的意思是你根本不应该使用NSTimer!(或者至少不应该只使用NSTimer)请看我的另一个答案,它不依赖于NSTimermate,我在这里收到一个警告-->[self-locationManager:nil didUpdateToLocation:self.currentLocation fromLocation:self.currentLocation];它说这个方法在iOS 6中不推荐使用>>哦,是的,你应该使用它。在执行了一些修改之后,我已经用我的iPhone设备测试了你的代码,因为上面的代码给了我一些警告,无论如何它不起作用,我在那个特定的时间去了一个指定的位置,以便我可以看到你的代码是否正确通风口被标记为有人出席,但不幸的是,没有真正出现任何东西。你有任何线索为什么会发生这种情况吗?PS,请检查我在问题>>
@property (nonatomic, strong) Event* currentEvent;
@property (nonatomic, strong) CLLocation* currentEventLocation;
@property (nonatomic, strong) NSDate* arrivalDate;
@property (nonatomic, strong) CLLocation* currentLocation;



- (void)locationManager:(CLLocationManager )manager didUpdateLocations:(NSArray *)locations { 
    CLLocation currentLocation = [locations lastObject];

    if (self.currentEvent) {
        if ([self.arrivalDate timeIntervalSinceNow]<60*5) {
            if ([self.currentEventLocation distanceFromLocation:newLocation]<100) {
                [self.currentEvent setHasATTENDED:[NSNumber numberWithBool:TRUE]];
            }
        }
    }
    self.currentLocation = newLocation;

    for (Event *event in [self loadTodaysEvents]) {

        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
        NSDate *currentTime = [NSDate date];
        [dateFormatter setDateFormat:@"HH:mm"];
        NSString *resultString = [dateFormatter stringFromDate:currentTime];

        NSString *eventStartTime = event.startingTime;

        // distance
        CLLocationDegrees lat = [event.lat doubleValue];
        CLLocationDegrees lon = [event.longi doubleValue];
        CLLocation *evLocation = [[CLLocation alloc] initWithLatitude:lat longitude:lon];
        double distance = [evLocation distanceFromLocation:newLocation];

        // CLOSE !
        if (distance <= 100 && [resultString isEqualToString:eventStartTime]) {
            self.arrivalDate = currentTime;
            self.currentEvent = event;
            self.currentEventLocation = evLocation;
            NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval: 300.0
                                                              target: self
                                                            selector: @selector(onTick:)
                                                            userInfo: nil
                                                             repeats: NO];

            NSRunLoop *runner = [NSRunLoop currentRunLoop];
            [runner addTimer:timer forMode: NSDefaultRunLoopMode];
        }
    } 
}

- (void)onTick:(NSTimer *)timer
{
    [self locationManager:nil didUpdateLocations:@[self.currentLocation]];        
}