distanceFromLocation - getting error - iphone

I have the following code in place:
NewWorkoutViewController.h
#import <UIKit/UIKit.h>
//#import <CoreLocation/CoreLocation.h>
#import <CoreData/CoreData.h>
#import "MapViewController.h"
#import "StatisticsViewController.h"
#import "MyCLController.h"
#import "Workout.h"
#import "Route.h"
#interface NewWorkoutViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate, UITextFieldDelegate, UIAlertViewDelegate> {
MyCLController *locationController;
IBOutlet UIButton *saveButton;
IBOutlet UIButton *backButton;
IBOutlet UIButton *startButton;
IBOutlet UIButton *stopButton;
IBOutlet UIButton *resetButton;
IBOutlet MapViewController *mapViewController;
IBOutlet StatisticsViewController *statisticsViewController;
IBOutlet UIView *routePickerView;
IBOutlet UIPickerView *routePicker;
IBOutlet UIView *activityPickerView;
IBOutlet UIPickerView *activityPicker;
IBOutlet UIView *intensityPickerView;
IBOutlet UIPickerView *intensityPicker;
IBOutlet UILabel *time;
IBOutlet UITextField *route;
IBOutlet UITextField *activity;
IBOutlet UITextField *intensity;
IBOutlet UILabel *speed;
IBOutlet UILabel *distance;
IBOutlet UILabel *averageSpeed;
IBOutlet UILabel *calories;
NSMutableArray *routeArray;
NSMutableArray *activityArray;
NSMutableArray *intensityArray;
NSMutableArray *newWorkoutArray;
NSManagedObjectContext *managedObjectContext;
int counterInt;
NSTimer *myTimer;
NSInteger *startInterval;
NSInteger *stopInterval;
NSInteger *elapsedInterval;
NSString *mapID;
int pickerChoice;
NSString *walkID;
NSString *activityValue;
NSString *intensityValue;
CLLocation *currentlocation;
CLLocation *previouslocation;
//double kilometers;
//double totalkilometers;
}
#property (retain,nonatomic) NSMutableArray *newWorkoutArray;
#property (retain,nonatomic) NSTimer *myTimer;
#property (nonatomic,assign) NSManagedObjectContext *managedObjectContext;
-(IBAction)backButton;
-(IBAction)saveButton;
-(IBAction)mapButton;
-(IBAction)statisticsButton;
-(IBAction)startTimerButton;
-(IBAction)stopTimerButton;
-(IBAction)resetButton;
-(IBAction)routePickerShow;
-(IBAction)activityPickerShow;
-(IBAction)intensityPickerShow;
-(IBAction)routeDoneButton;
-(IBAction)activityDoneButton;
-(IBAction)intensityDoneButton;
-(void)showActivity;
-(void)didCreateWorkout:(NSString *)thisTime
Route:(NSString *)thisRoute
Activity:(NSString *)thisActivity
Intensity:(NSString *)thisIntensity
Speed:(NSString *)thisSpeed
Distance:(NSString *)thisDistance
AverageSpeed:(NSString *)thisAverageSpeed
Calories:(NSString *)thisCalories;
-(void)initialiseWorkoutViewController;
-(void)locationUpdate:(CLLocation *)location;
#end
NewWorkoutViewController.m
-(void)locationUpdate:(CLLocation *)location
{
currentlocation = [[CLLocation alloc] initWithLatitude:+37.364305 longitude:-122.027901];
previouslocation = [[CLLocation alloc] initWithLatitude:+37.364429 longitude:-122.028048]; //70301
if(previouslocation != nil) {
CLLocationDistance kilometers = [currentlocation distanceFromLocation:previouslocation]; // Error occurring here
NSLog(#"Distance Meters: %f", kilometers);
[speed setText:[NSString stringWithFormat:#"%.2f",[location speed]]];
[distance setText:[NSString stringWithFormat:#"%.2f", kilometers / 1000]];
previouslocation = currentlocation;
}
}
MyCLLocation.h
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#protocol MyCLControllerDelegate <NSObject>
#required
- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSError *)error;
#end
#interface MyCLController : NSObject <CLLocationManagerDelegate> {
CLLocationManager *locationManager;
id delegate;
}
#property (nonatomic, retain) CLLocationManager *locationManager;
#property (nonatomic, assign) id delegate;
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation;
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error;
#end
MyCLLocation.m
#import "MyCLController.h"
#implementation MyCLController
#synthesize locationManager;
#synthesize delegate;
- (id) init {
self = [super init];
if (self != nil) {
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.delegate = self; // send loc updates to myself
}
return self;
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
[self.delegate locationUpdate:newLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
[self.delegate locationError:error];
}
- (void)dealloc {
[self.locationManager release];
[super dealloc];
}
#end
I get the following error message on the CLLocationDistance line in NewWorkoutViewController.m "Incompatible types in initialization".
Anyone any thoughts ?
Regards,
Stephen

I've tried it in XCode but don't get the error that you get :(
I tried :
-(void)locationUpdate:(CLLocation *)location
{
CLLocation *currentlocation = [[CLLocation alloc] initWithLatitude:+37.364305 longitude:-122.027901];
CLLocation *previouslocation = [[CLLocation alloc] initWithLatitude:+37.364429 longitude:-122.028048]; //70301
if(previouslocation != nil) {
CLLocationDistance kilometers = [currentlocation distanceFromLocation:previouslocation]; // Error occurring here
NSLog(#"Distance Meters: %f", kilometers);
[speed setText:[NSString stringWithFormat:#"%.2f",[location speed]]];
[distance setText:[NSString stringWithFormat:#"%.2f", kilometers / 1000]];
previouslocation = currentlocation;
}
}
Can you edit your question and show where you have defined currentlocation and previouslocation - I've defined them in the method just to test it but I assume you've defined them somewhere else in your class (probably the .h file)?

Problem solved:
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 3130
CLLocationDistance kilometers = [currentLocation getDistanceFrom:previousLocation] / 1000;
#else
CLLocationDistance kilometers = [currentLocation distanceFromLocation:previousLocation] / 1000;
#endif

Related

How can I integrate core location data to my blank iPhone App without introducing View or tab controller?

How can I integrate core location data (Lat, Long, Altitude) into my (single view) iPhone app without creating additional view controllers or tab controllers? in other words, when I run the app I want to see a blank screen (xView) but be able to collect (Longitude, Latitude information in the background and then maybe store the coordinates in a file or pass it on to a other functions. Sorry if this sounds like a dumb question. I am new to iOS development. Thanks.
HelloXYZAppDelegate.h:
#import <UIKit/UIkit.h>
#import "MyclassView.h"
#interface HelloXYZAppDelegate: NSObject <UIApplicationDelegate>
{
MyClassView* _xView;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet MyClassView *xView;
#end
HelloXYZAppDelegate.m
#import "HelloXYZAppDelegate.h"
#implementation HelloXYZAppDelegate
#synthesize xView=_xView;
#synthesize window=_window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:
{
self.xView = [[[MyClassView alloc] initWithFrame:screenBounds] autorelease];
[self.window addSubview:_xView];
[self.window makeKeyAndVisible];
return YES;
}
#end
MyClassView.h:
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#include <OpenGLES/ES2/gl.h>
#interface MyClassView : UIView
{
CAEAGLLayer* _eaglLayer;
EAGLContext* _context;
GLuint _CRBuffer;
GLuint _PSlot;
....
....
....
CLLocationManager *LM; //not sure if I can do this in here
CLLocation *SP; //not sure if I can do this in here
}
#property (nonatomic, retain) CLLocationManager *LM;
#property (nonatomic, retain) CLLocation *SP;
#end
MyClassView.m
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
if (SP == nil)
self.SP = newLocation;
NSString *latitudeString = [[NSString alloc] initWithFormat:#"%g\u00B0",
newLocation.coordinate.latitude];
NSLog(#"latitude is %#", latitudeString);
[latitudeString release];
}
- (void)viewDidLoad
{
self.LM = [[CLLocationManager alloc] init];
LM.delegate = self;
LM.desiredAccuracy = kCLLocationAccuracyBest;
[LM startUpdatingLocation];
[super viewDidLoad];
}
very simple tutorial on core location. If you're looking to store the data for use later on you'll either want to make a data NSObject class, but seeing as you dont want to make extra classed, define two #property NSStrings lat and long, when the location is created set the two strings to the two variables and you can access them later.
The tutorial prints the data on the screen, just leave that part out if you dont want it

MapKit mapView:viewForAnnotation has no effect on pin color

I can't seem to change the pin color.
I have my view controller extend <MKMapViewDelegate> and implement mapView:viewForAnnotation I'm close but must be missing something. any help would be appreciated.
MainViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import "StopAnnotation.h"
#define METERS_PER_MILE 1609.344
#interface MainViewController : UIViewController <MKMapViewDelegate> {
}
#property (weak, nonatomic) IBOutlet MKMapView *mapView;
#end
MapViewController.m
#import "MainViewController.h"
#implementation MainViewController
#synthesize mapView=_mapView;
- (void)viewWillAppear:(BOOL)animated
{
CLLocationCoordinate2D zoomLocation;
zoomLocation.latitude = 43.066667;
zoomLocation.longitude = -89.4;
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation, METERS_PER_MILE, METERS_PER_MILE);
MKCoordinateRegion adjustRegion = [_mapView regionThatFits:viewRegion];
[_mapView setRegion:adjustRegion animated:YES];
[_mapView addAnnotation:[[StopAnnotation alloc] initWithCoordinate:zoomLocation]];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
MKPinAnnotationView *pav = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:nil];
pav.pinColor = MKPinAnnotationColorPurple;
return pav;
}
// the rest of the methods are default, i.e. viewDid* and shouldAutorotate*, etc...
StopAnnotation.h
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface StopAnnotation : NSObject <MKAnnotation> {
CLLocationCoordinate2D coordinate;
NSString *title;
NSString *subtitle;
}
- (id)initWithCoordinate:(CLLocationCoordinate2D)c;
#end
StopAnnotation.m
#import "StopAnnotation.h"
#implementation StopAnnotation
#synthesize coordinate;
- (NSString *)subtitle {
return #"subtitle";
}
- (NSString *)title {
return #"title";
}
- (id)initWithCoordinate:(CLLocationCoordinate2D)c {
coordinate = c;
NSLog(#"%f,%f", c.latitude, c.longitude);
return self;
}
#end
I'm doing an exercise & the code was mostly from here
Thanks!!
You must set MainViewController as the delegate of mapView, ie if you are not then the map view might be generating default pins, if you put a breakpoint in
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
does it actually get called?

Having trouble hooking up instance variables to AppDelegate

Am having some trouble hooking up instance variables in the visual object editor using Xcode4.
Have been able to connect the Whereami App Delegate to the mapView and activityIndicator, but for some reason, can't find the locationTitleField. Am also having trouble connecting the delegates back to the App Delegate.
What am I doing wrong?
Here is the code for Whereami App Delegate.h:
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>
#interface WhereamiAppDelegate : NSObject <UIApplicationDelegate,CLLocationManagerDelegate> {
UIWindow *window;
CLLocationManager *locationManager;
IBOutlet MKMapView *mapView;
IBOutlet UIActivityIndicatorView *activityIndicator;
IBOutlet UITextView *locationTitleField;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#end
Whereami App Delegate.m
#import "WhereamiAppDelegate.h"
#implementation WhereamiAppDelegate
#synthesize window=_window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
//-- Create location manager object --
locationManager = [[CLLocationManager alloc] init];
//-- Make this instance of WhereamiAppDelegate the delegate
//-- It will sends its messages to our Whereami delegate.
[locationManager setDelegate:self];
//-- We want all results from the location manager--
[locationManager setDistanceFilter:kCLDistanceFilterNone];
//-- And we want it to be as accurate as possible--
//-- Regardless of how much time/power it takes --
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
//-- Tell our location manager to start looking for its location
//-- immediately
[locationManager startUpdatingLocation];
[self.window makeKeyAndVisible];
return YES;
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
NSLog(#"Could not find location: %#", error);
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
NSLog(#"%#", newLocation);
}
Try making them properties instead of iVars ...
#interface WhereamiAppDelegate : NSObject <UIApplicationDelegate,CLLocationManagerDelegate>
#property (nonatomic, retain) IBOutlet CLLocationManager *locationManager;
#property (nonatomic, retain) IBOutlet MKMapView *mapView;
#property (nonatomic, retain) IBOutlet UIActivityIndicatorView *activityIndicator;
#property (nonatomic, retain) IBOutlet UITextView *locationTitleField;
#property (nonatomic, retain) IBOutlet UIWindow *window;
#end
and don't forget to synthesize them
#synthesize locationManager = _locationManager;
#synthesize mapView = _mapView;
#synthesize activityIndicator = _activityIndicator;
#synthesize locationTitleField = _locationTitleField;
I never use iVars for objects that appear in nib files; I tend to always use properties and have never experienced any issues with hooking up the outlets.

Geolocation only shows global map

I tried to make a goelocation to my iPhone app exactly as shown in this tutorials : http://www.youtube.com/watch?v=qNMNRAbIDoU
my problem is when I build and go i see the map but the geolocation service didn't track my position, so I see just the global map :(
Here is my code I hope you can help me to identifiy the problem :
appdelegate.h
#interface WhereAmIAppDelegate : NSObject <UIApplicationDelegate,CLLocationManagerDelegate> {
UIWindow *window;
WhereAmIViewController *viewController;
CLLocationManager *locationManager;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) CLLocationManager *locationManager;
#property (nonatomic, retain) IBOutlet WhereAmIViewController *viewController;
appdelegate.m:
#implementation WhereAmIAppDelegate
#synthesize window;
#synthesize viewController;
#synthesize locationManager;
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.locationManager=[[[CLLocationManager alloc] init] autorelease];
if([CLLocationManager locationServicesEnabled]) {
self.locationManager.delegate=self;
self.locationManager.distanceFilter=100;
[self.locationManager startUpdatingLocation];
}
// Add the view controller's view to the window and display.
[window addSubview:viewController.view];
[window makeKeyAndVisible];
return YES;
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
#pragma mark CLLocationManagerDelegate Methods
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
MKCoordinateSpan span;
span.latitudeDelta=0.2;
span.longitudeDelta=0.2;
MKCoordinateRegion region;
region.span=span;
region.center=newLocation.coordinate;
[viewController.mapView setRegion:region animated:YES];
viewController.mapView.showsUserLocation=YES;
viewController.latitude.text=[NSString stringWithFormat:#"%f",newLocation.coordinate.latitude];
viewController.longitude.text=[NSString stringWithFormat:#"%f",newLocation.coordinate.longitude];
}
#end
MyViewController.h
#interface WhereAmIViewController : UIViewController {
MKMapView *mapView;
UILabel *latitude;
UILabel *longitude;
}
#property (nonatomic,retain)IBOutlet MKMapView *mapView;
#property (nonatomic,retain)IBOutlet UILabel *latitude;
#property (nonatomic,retain)IBOutlet UILabel *longitude;
myViewController.m :
#implementation WhereAmIViewController
#synthesize mapView;
#synthesize latitude;
#synthesize longitude;
- (void)dealloc {
[mapView release];
[latitude release];
[longitude release];
[super dealloc];
}
#end
Two things to check:
1) The simulator does not have location, it will always show the lat/long of the Apple headquarters in California
2) It takes a little bit of time for the location to get settled, so if you ask for location right away you won't get one.
Also, you need some more code in your WhereAmI view controller. Usually you will see something in the viewWillAppear. Here is a link to a Big Nerd Ranch tutorial on view controllers and map views. Maybe it will help you.
There are a few things here to note:
1) The iPhone emulator does not have GPS capabilities, however it does have a default location of 1 Infinite Loop, Cupertino, CA (USA)
2) Your delegate method should be didUpdateFromLocation, not didUpdateToLocation.

CLLocationManager - strange Memory Leak

I'm implementing a CLLocationManager right as described in several tutorials.
Everything works fine up to the point where the LocationManager receives a second update. Then a memory leak occurs.
Instruments tells me, that the leaked objects are NSCFTimer, GeneralBlock-16 and NSCFSet
Any ideas?
Thanks for any help
[Edit]
After repeatingly starting and stopping the locationManager, the updated seem to come faster. This makes me think that the CLLocationManager initializes a new timer every time a location-update occurs... VERY strange...
And - so you don't need to read my comment - the app crashes after a while
[Edit]
Ok - I don't get it here's some code...
I'm using a separate class for the locationManager, as described here: http://www.vellios.com/2010/08/16/core-location-gps-tutorial/
locationManager.h
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#protocol locationManagerDelegate
#required
- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSError *)error;
#end
#interface locationManager : NSObject <CLLocationManagerDelegate>{
CLLocationManager *myLocationManager;
id delegate;
CLLocation *bestEffortAtLocation;
BOOL outOfRange;
}
#property (nonatomic, retain) CLLocationManager *myLocationManager;
#property (nonatomic, retain) CLLocation *bestEffortAtLocation;
#property (nonatomic, assign) id delegate;
#property (nonatomic, assign) BOOL outOfRange;
#end
locationManager.m
#import "locationManager.h"
#implementation locationManager
#synthesize myLocationManager;
#synthesize delegate;
#synthesize bestEffortAtLocation;
#synthesize outOfRange;
- (id) init {
self = [super init];
NSLog(#"initializing CLLocationManager");
if (self != nil) {
outOfRange = NO;
self.myLocationManager = [[[CLLocationManager alloc] init] autorelease];
self.myLocationManager.delegate = self;
self.myLocationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
[self performSelector:#selector(stopUpdatingLocation:) withObject:#"Timed Out" afterDelay:100.0];
}else{
NSLog(#"Location Manager could not be initialized");
}
return self;
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
if(outOfRange == NO){
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:#selector(stopUpdatingLocation:) object:nil];
NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
if (locationAge > 5.0) return;
// test that the horizontal accuracy does not indicate an invalid measurement
if (newLocation.horizontalAccuracy < 0) return;
[self.delegate locationUpdate:newLocation];
}else{
[self.myLocationManager stopUpdatingLocation];
}
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
NSLog(#"error!!!!");
[self.myLocationManager stopUpdatingLocation];
[self.delegate locationError:error];
}
- (void)dealloc {
[myLocationManager release];
[bestEffortAtLocation release];
[super dealloc];
}
#end
then, in the main-class I call:
mainFile.h (exerpt)
#import "locationManager.h"
#interface mainFile : UIViewController <locationManagerDelegate , UIAlertViewDelegate>{
locationManager *locationController;
CLLocation *myLocation;
}
#end
mainFile.m (exerpt)
#import "locationManager.h"
#implementation mainFile
#synthesize locationController;
#synthesize myLocation;
- (void)locationError:(NSError *)error{
// Do alert-Stuff
}
- (void)locationUpdate:(CLLocation *)location {
// Do location-Stuff
}
- (void)viewDidLoad
{
[super viewDidLoad];
locationController = [[[locationManager alloc] init] autorelease];
locationController.delegate = self;
[locationController.myLocationManager startUpdatingLocation];
}
- (void)dealloc {
self.locationController = nil;
[locationController release];
}
#end
It's driving me kinda crazy :)
My advice is to not be obsessed with one-time memory leaks that the iOS itself generates. It does this in many places and the leaks are all pretty harmless.
Ah, a long dead problem, I love them.
locationController is an iVar, not a property, so when you create it in viewDidLoad, assigning it to _locationController doesn't take on ownership.
You've autoreleased the object, so next time around the event loop, the auto-release pool is drained and it is released.
You could fix it by making it a retain property ( which would fit with your locationManager = nil ), or getting rid of the auto-release, and using an explicit [locationManager release] in dealloc.
Try doing a Build and Analyze. I usually find memory leaks and other non-syntax errors that way.