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