Revision: 23463
Initial Code
Initial URL
Initial Description
Initial Title
Initial Tags
Initial Language
at February 8, 2010 09:43 by espinallab
Initial Code
// // DistanceViewController.h // Distance // // Created by Steve Baker on 1/30/10. // Copyright Beepscore LLC 2010. All rights reserved. // #import <UIKit/UIKit.h> #import <CoreLocation/CoreLocation.h> // Note we only write to the textFields, not edit, respond to keyboard input or read from them. // So we don't need to conform to or implememnt <UITextFieldDelegate> protocol // Ref Dudney sec 4.6 pg 65-66 @interface DistanceViewController : UIViewController <CLLocationManagerDelegate> { CLLocationManager *locationManager; NSMutableArray *locations; UILabel *lastUpdate; UILabel *totalDistance; UILabel *averageSpeed; } #pragma mark - #pragma mark properties @property(nonatomic,retain)CLLocationManager *locationManager; @property(nonatomic,retain)NSMutableArray *locations; @property(nonatomic,retain)IBOutlet UILabel *lastUpdate; @property(nonatomic,retain)IBOutlet UILabel *totalDistance; @property(nonatomic,retain)IBOutlet UILabel *averageSpeed; - (void)updateDisplay; @end // // DistanceViewController.m // Distance // // Created by Steve Baker on 1/30/10. // Copyright Beepscore LLC 2010. All rights reserved. // #import "DistanceViewController.h" @implementation DistanceViewController #pragma mark - #pragma mark properties @synthesize locationManager; @synthesize locations; @synthesize lastUpdate; @synthesize totalDistance; @synthesize averageSpeed; #pragma mark - #pragma mark initializers /* // The designated initializer. Override to perform setup that is required before the view is loaded. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { // Custom initialization } return self; } */ /* // Implement loadView to create a view hierarchy programmatically, without using a nib. - (void)loadView { } */ // Implement viewDidLoad to do additional setup after loading the view, typically from a nib. - (void)viewDidLoad { [super viewDidLoad]; self.locationManager = [[[CLLocationManager alloc] init] autorelease]; self.locationManager.delegate = self; // notify us only if distance changes by 10 meters or more self.locationManager.distanceFilter = 10.0f; self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters; [self.locationManager startUpdatingLocation]; // 32 is a guess of a 'good' number self.locations = [NSMutableArray arrayWithCapacity:32]; } /* // Override to allow orientations other than the default portrait orientation. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation == UIInterfaceOrientationPortrait); } */ #pragma mark destructors and memory cleanUp // use cleanUp method to avoid repeating code in setView, viewDidUnload, and dealloc - (void)cleanUp { [locationManager release], locationManager = nil; [locations release], locations = nil; [lastUpdate release], lastUpdate = nil; [totalDistance release], totalDistance = nil; [averageSpeed release], averageSpeed = nil; } // Release IBOutlets in setView. // Ref http://developer.apple.com/iPhone/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmNibObjects.html // // http://moodle.extn.washington.edu/mod/forum/discuss.php?d=3162 - (void)setView:(UIView *)aView { if (!aView) { // view is being set to nil // set outlets to nil, e.g. // self.anOutlet = nil; [self cleanUp]; } // Invoke super's implementation last [super setView:aView]; } - (void)didReceiveMemoryWarning { // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; // Release any cached data, images, etc that aren't in use. } - (void)viewDidUnload { // Release any retained subviews of the main view. [self cleanUp]; } - (void)dealloc { [self cleanUp]; [super dealloc]; } #pragma mark Location methods - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { // if we have a valid location, and it's within 20 meters then stop // updating location, but turn it back on in 60 seconds. if (newLocation.horizontalAccuracy > 0.0f && newLocation.horizontalAccuracy < 20.0f) { if (self.locations.count > 3) { [self.locationManager stopUpdatingLocation]; [self.locationManager performSelector:@selector(startUpdatingLocation) withObject:nil afterDelay:60.0f]; } [self.locations addObject:newLocation]; [self updateDisplay]; } } - (CLLocationDistance)totalDistanceTraveled { CGFloat totalDistanceTraveled = 0.0f; CLLocation *oldLocation = nil; for (CLLocation *location in self.locations) { if (nil == oldLocation) { oldLocation = location; // continue skips the rest of the for loop continue; } totalDistanceTraveled += fabs([location getDistanceFrom:oldLocation]); oldLocation = location; } return totalDistanceTraveled; } - (NSTimeInterval)timeDelta { NSDate *first = [(CLLocation *)[self.locations objectAtIndex:0] timestamp]; NSDate *last = [(CLLocation *)[self.locations lastObject] timestamp]; return [last timeIntervalSince1970] - [first timeIntervalSince1970]; } #pragma mark - - (void)updateDisplay { CLLocationDistance distance = [self totalDistanceTraveled]; totalDistance.text = [NSString stringWithFormat:@"%5.3f", distance]; NSTimeInterval time = [self timeDelta]; // don't want to divide by zero if (0.0f == time) { averageSpeed.text = @"0.000"; } else { averageSpeed.text = [NSString stringWithFormat:@"%5.3f", distance/time]; } NSDateFormatter *inputFormatter = [[[NSDateFormatter alloc] init] autorelease]; [inputFormatter setDateFormat:@"HH:mm:ss.SSSS"]; NSDate *date = [(CLLocation *)[self.locations lastObject] timestamp]; lastUpdate.text = [inputFormatter stringFromDate:date]; } @end
Initial URL
http://github.com/beepscore/Distance/tree/master/Classes/
Initial Description
Initial Title
Distance Travel
Initial Tags
Initial Language
Objective C