This is part three of the blog series “Creating an iPhone Daemon”, for part one please click this link
In the last part of the series, we created the header file for our DLocationDelegate class, now lets create the implementation file (DLocationDelegate.h)
// // DLocationDelegate.m // // // Created by Chris Alvares on 3/25/09. // Copyright 2009 Chris Alvares. All rights reserved. // #import "DLocationDelegate.h" #define NSURLRequestReloadIgnoringLocalCacheData 1 @implementation DLocationDelegate @synthesize locationManager; -(id) init { if (self = [super init]) { trackingGPS = false; NSLog(@"starting the location Manager"); self.locationManager = [[CLLocationManager alloc] init]; self.locationManager.delegate = self; } return self; } //this function is to only be called once. -(void) startIt:(NSTimer *) timer { if(timer != nil) [timer invalidate]; trackingGPS = true; [self.locationManager startUpdatingLocation]; } //the difference in this function is that it invalidates the timer function, and can run more than one time -(void) startItAgain:(NSTimer *)timer { if(!trackingGPS) { trackingGPS = true; [self.locationManager startUpdatingLocation]; } } - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { srandom(time(0)); //do this to make sure that it does not use a cached page NSLog(@"Location found"); //if the horizontalAccuracy is negative, CoreLocation failed, and we want a good reading, so we want at least 100 meter accuracy if([newLocation horizontalAccuracy] < 100 && [newLocation horizontalAccuracy] > 0) { [self.locationManager stopUpdatingLocation]; NSNumber *num = [NSNumber numberWithInt:(random())]; NSLog(@"Latitude %lf Longitude %lf", newLocation.coordinate.latitude, newLocation.coordinate.longitude); NSNumber *latitude = [[NSNumber alloc] initWithDouble:newLocation.coordinate.latitude]; NSNumber *longitude = [[NSNumber alloc] initWithDouble:newLocation.coordinate.longitude]; NSNumber *altitude = [[NSNumber alloc] initWithDouble:newLocation.altitude]; NSMutableString *str = [[NSMutableString alloc] initWithString:@"http://chrisalvares.com/iPhoneLocationService.php?ID=2&LATITUDE="]; [str appendString:[latitude stringValue]]; [str appendString:@"&LONGITUDE="]; [str appendString:[longitude stringValue]]; [str appendString:@"&ALTITUDE="]; [str appendString:[altitude stringValue]]; [str appendString:@"&RANDOM="]; [str appendString:[num stringValue]]; NSURL *theURL = [[NSURL alloc] initWithString:str]; NSURLRequest *theRequest = [NSURLRequest requestWithURL:theURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:120]; NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self startImmediately:YES]; if(connection == nil) { trackingGPS = NO; } NSLog(@"setting timer for 30 minutes"); NSTimer *timer = [[NSTimer timerWithTimeInterval:1800.0 target:self selector:@selector(startItAgain:) userInfo:nil repeats:NO ] retain]; [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; [timer release]; [latitude release]; [longitude release]; [altitude release]; [theURL release]; } else { NSLog(@"Accuracy not good enough %lf", [newLocation horizontalAccuracy]); } } - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { trackingGPS = false; NSLog(@"trackingGPS failed"); } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { NSLog(@"GPS information Sent"); trackingGPS = false; } -(void) dealloc { [locationManager release]; [super dealloc]; } @end
Yes, it is a pretty big file, so I won’t explain it all (it has comments to help you).
self.locationManager = [[CLLocationManager alloc] init]; self.locationManager.delegate = self;
These two lines are important, after we init the locationManager we must make sure that the delegate is set to our DLocationDelegate class.
if([newLocation horizontalAccuracy] < 100 && [newLocation horizontalAccuracy] > 0)
Inside this function, you will notice the CLLocation *newlocation’s horizontalAccuracy property. If the horizontal accuracy is less than 0, than there was an error, if it is greater than 100, the accuracy is very poor, so the DLocationDelegate class will wait for a better reading.
[self.locationManager stopUpdatingLocation];
This line is VERY important, we have to stop the GPS from updating, otherwise the iPhone’s batter will die super quickly.
NSMutableString *str = [[NSMutableString alloc] initWithString:@"http://youriphonelocationserver.com/locationService.php?ID=2&LATITUDE="]; [str appendString:[latitude stringValue]]; [str appendString:@"&LONGITUDE="]; [str appendString:[longitude stringValue]]; [str appendString:@"&ALTITUDE="]; [str appendString:[altitude stringValue]]; [str appendString:@"&RANDOM="]; [str appendString:[num stringValue]];
When you put everything together, you should get a link like:
http://youriphonelocationserver.com/locationService.php?ID=iphoneid&LATITUDE=laditudeNumber&LONGITUDE=longitudeNumber&ALTITUDE=number&RANDOM=12312
We will create this PHP file in an upcoming tutorial.
NSTimer *timer = [[NSTimer timerWithTimeInterval:1800.0 target:self selector:@selector(startItAgain:) userInfo:nil repeats:NO ] retain]; [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
The DLocationDelegate timer is set for 1800.0 seconds, which is 30 minutes. I found that 30 minutes does not drain the battery too much, but still has a good amount of readings just incase your iPhone is lost.
While this will get your DLocationDelegate class setup, we still have one more issue, and that is that the iPhone will go into a hard sleep after a minute of no use. We will fix this in an upcoming tutorial.