Chris Alvares
Porfolio About Me Contact Me Social Blog

Archive

Posts Tagged ‘part 2’

Creating an iPhone Daemon – Part 3

March 25th, 2009

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.

admin Uncategorized , , , , , , ,

Creating an iPhone Daemon – Part 2

March 25th, 2009

Here is part two of the blog series “Creating an iPhone Daemon”, for part one please click this link

As I said in part 1, we will be creating the DLocationDelegate class.
With most daemons, you do a task like read a file, do something with that file, sleep for a certain amount of time, then check for file changes, and repeat the steps over again. Unfortunately, with GPS coordinates, we have to wait for the CoreLocation delegate to give us the coordinates. The thing about Objective-C and Apple’s Cocoa framework is that most of the classes depend heavily on delegates. This is also true when dealing with the CoreLocation APIs. So lets get coding.

So lets write the DLocationDelegate header file first, this will give us a good look at what is ahead

#import <CoreLocation/CoreLocation.h>
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
 
@interface DLocationDelegate : NSObject <CLLocationManagerDelegate>
{
	BOOL trackingGPS;
	CLLocationManager *locationManager;
}
 
@property (nonatomic, retain) CLLocationManager *locationManager;
 
- (void)locationManager:(CLLocationManager *)manager
	didUpdateToLocation:(CLLocation *)newLocation
		   fromLocation:(CLLocation *)oldLocation;
 
- (void)locationManager:(CLLocationManager *)manager
	   didFailWithError:(NSError *)error;
 
-(void) startIt:(NSTimer *) timer;
-(void) startItAgain:(NSTimer *)timer;
 
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
 
@end

So lets go through this line by line starting with our imports

#import <CoreLocation/CoreLocation.h>
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

The most important import we have here is the CoreLocation framework, this will let us use the CLLocationManager class.

@interface DLocationDelegate : NSObject <CLLocationManagerDelegate>

When you have a class name in <> symbols, Objective-C now knows that you are implementing methods from this class. In this case to receive the GPS coordinates we use the CLLocationManagerDelegate protocol

	BOOL trackingGPS;
	CLLocationManager *locationManager;

The Boolean trackingGPS will tell us if we are currently tracking the GPS, this will be used to tell if the CLLocationManager is currently looking for coordinates. The locationManager is the actual class that will get the GPS coordinates from either the GPS (iPhone 3G) or the cell towers (iPhone 2G).

- (void)locationManager:(CLLocationManager *)manager
	didUpdateToLocation:(CLLocation *)newLocation
		   fromLocation:(CLLocation *)oldLocation;
 
- (void)locationManager:(CLLocationManager *)manager
	   didFailWithError:(NSError *)error;

These are the delegate methods for the CLLocationManagerDelegate. The first one “didUpdateToLocation” will give us the coordinates using a CLLocation class which contains a longitude, latitude, and sometimes even a altitude. The second function will notify our DLocationDelegate of any errors with the GPS, maybe if your iPhone is inside a lead case :) .

-(void) startIt:(NSTimer *) timer;
-(void) startItAgain:(NSTimer *)timer;

We will use these functions to start the GPS after a certain amount of time.

- (void)connectionDidFinishLoading:(NSURLConnection *)connection;

This is for the NSURLConnection object that will send the GPS coordinates to our server.

In part three of this tutorial we will create the DLocationDelegate.m file (the implementation file)

-Chris

admin Uncategorized , , , , , ,