Error setting property on CLLocation subclass - iphone

I've defined this subclass of CLLocation
MyLocation.h
#interface MyLocation: CLLocation {
NSString *datum;
NSString *ellipsoid;
}
#property(nonatomic,retain) NSString *ellipsoid;
#property(nonatomic,retain) NSString *datum;
MyLocation.m
#synthesize datum,ellipsoid;
Now I get a CLLocation instance through the location manager delegate
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
//self.myPosition is a MyLocation myPosition;
self.myPosition = newLocation;
[myPosition setDatum: #"WGS 84"];
[myPosition setEllipsoid: #"WGS 84"];
}
When I do the self.myPosition = newLocation, I get an UNCAUGHT EXCEPTION and it dies
I've also tried this way with same results:
self.myPosition = (MyLocation *)newLocation;

newLocation is not an instance of ur subclass so doing that assignment or casting throws an error because it's an invalid cast, u should be seting the values of ur subclass that u want fromthe cllocation object something like
self.myPosition=[[MyLocation alloc] initWithCoordinate:newLocation.coordinate]
and so on

Related

Getting latitude and longitude in IOS7

I am developing an iPhone app which uses location services and runs in background.This app displays latitude and longitude exactly when it runs on IOS6.But if i run the same app on IOS7, sometimes it shows latitude and longitude exactly, sometimes -1 and -1. I'm not understanding this behaviour on IOS7. what may be the reason for this behaviour?
In order to simulate a location, select the iOS Simulator Debug -> Location menu option and select either one of the pre-defined locations or journeys (such as City Bicycle Ride), or Custom Location… to enter a specific latitude and longitude.
This code worked for me.
Creating the CLLocationManager Object
The next task is to implement the code to create an instance of the CLLocationManager class. Since this needs to occur when the view loads, an ideal location is in the view controller’s viewDidLoad method in the LocationViewController.m file:
- (void)viewDidLoad {
[super viewDidLoad];
_locationManager = [[CLLocationManager alloc] init];
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
_locationManager.delegate = self;
[_locationManager startUpdatingLocation];
_startLocation = nil;
}
Implementing the Action Method
-(void)resetDistance:(id)sender
{
_startLocation = nil;
}
Implementing the CLLocationManager Method
#pragma mark -
#pragma mark CLLocationManagerDelegate
-(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
NSString *currentLatitude = [[NSString alloc]
initWithFormat:#"%+.6f",
newLocation.coordinate.latitude];
_latitude.text = currentLatitude;
NSString *currentLongitude = [[NSString alloc]
initWithFormat:#"%+.6f",
newLocation.coordinate.longitude];
_longitude.text = currentLongitude;
NSString *currentHorizontalAccuracy =
[[NSString alloc]
initWithFormat:#"%+.6f",
newLocation.horizontalAccuracy];
_horizontalAccuracy.text = currentHorizontalAccuracy;
NSString *currentAltitude = [[NSString alloc]
initWithFormat:#"%+.6f",
newLocation.altitude];
_altitude.text = currentAltitude;
NSString *currentVerticalAccuracy =
[[NSString alloc]
initWithFormat:#"%+.6f",
newLocation.verticalAccuracy];
_verticalAccuracy.text = currentVerticalAccuracy;
if (_startLocation == nil)
_startLocation = newLocation;
CLLocationDistance distanceBetween = [newLocation
distanceFromLocation:_startLocation];
NSString *tripString = [[NSString alloc]
initWithFormat:#"%f",
distanceBetween];
_distance.text = tripString;
}
In the End Try this method
Try this method to get continuous updated latitude and longitude
(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *location_updated = [locations lastObject];
NSLog(#"updated coordinate are %#",location_updated);
}
Use this method for getting location continuously use this method
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
location_updated = [locations lastObject];
NSLog(#"updated coordinate are %#",location_updated);
}
may be you are using this method
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
This method has been Deprecated in iOS 6.0

Objective-C - Errors when passing a variable into function

What is the easiest way to pass a var into another function ?
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
NSLog(#"%#", started);
}
I tried:
Defined a global vars:
extern NSString *started;
When I set the NSString directly and passing into another function, it works well:
-(void) startTracking:(CDVInvokedUrlCommand*)command {
started = #"testing";
}
But it doesn't work:
-(void) startTracking:(CDVInvokedUrlCommand*)command {
NSString* myarg = [command.arguments objectAtIndex:0]; // http://docs.phonegap.com/en/2.5.0/guide_plugin-development_ios_index.md.html#Developing%20a%20Plugin%20on%20iOS_writing_an_ios_cordova_plugin
started = myarg;
}
(I'm a objective-C beginner, don't understand it well)
EDIT: Seems like it only crashed when I put the app into background.
Depending on wether you are using ARC, you have to retain the object. You'll probably want to use a property on your class:
in your header:
#property(strong) NSString *started;
in implementation:
-(void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
NSLog(#"%#", self.started);
}
-(void) startTracking:(CDVInvokedUrlCommand*)command {
self.started = #"testing";
}
-(void) startTracking:(CDVInvokedUrlCommand*)command {
NSString* myarg = [command.arguments objectAtIndex:0];
self.started = myarg;
}
Mate, seems like you want to track the date you started receiving location information.
How about doing it like this:
// Your .h file
#interface MyClass <CLLocationManagerDelegate>
{
BOOL hasStartedUpdatingLocation;
NSDate *startDate;
CLLocationManager *locationManager;
}
...
// Your .m file
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
// ---------------------------------------------------------------
// if has NOT started updating location, record start date
// otherwise, do not execute this if statement
// ---------------------------------------------------------------
if(!hasStartedUpdatingLocation)
{
hasStartedUpdatingLocation = YES;
// this if statement should only execute once
startDate = [NSDate date]; // get the current date and time
}
else
{
// do something else
}
}

How do I acquire data from a NSNotification object?

I am trying to send a location update with the new location as a notification object. When I do, I receive a "EXC_BAD_ACCESS" error when I try to access the data from the notification. If I execute "po location" I see the data, but it is unclear to me why I cannot acquire it. When setting the observer, I also tried assigning the object parameter to a member variable, but then locationUpdate is never called.
Here's my code (note that ARC is enabled):
// LocationController.h
#protocol LocationDelegateProtocol
#required
- (void)locationUpdate:(CLLocation *)location;
#end
#interface LocationController : NSObject <CLLocationManagerDelegate> {
CLLocationManager *locationManager;
id delegate;
}
#property(nonatomic, retain) CLLocationManager *locationManager;
#property(nonatomic, strong) id delegate;
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation;
+ (LocationController *)sharedInstance; // this class is a singleton
#end
// LocationController.m
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
[Notification locationChanged:newLocation];
}
// Notification.h
#interface Notification : NSObject
+ (void)locationChanged:(CLLocation *)newLocation;
#end
extern NSString *const kLocationChanged;
// Notification.m
NSString *const kLocationChanged = #"NewLocation";
[[NSNotificationCenter defaultCenter] postNotificationName:kLocationChanged object:newLocation];
// ViewController.h
#interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, LocationDelegateProtocol> {
...
}
...
- (void)locationUpdate:(CLLocation *)location;
#end
// ViewController.m
- (void)setupNotifications {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(locationUpdate:) name:kLocationChanged object:nil];
// I've tried setting object to a member var "CLLocation *objectFromNotification", but then locationUpdate() is never called.
}
- (void)locationUpdate:(NSNotification *)notification {
CLLocation *location = (CLLocation *) [notification object];
// program receives signal "EXC_BAD_ACCESS" when executing NSLog below. I can see data inside location when I execute "po location".
NSLog(#"latitude = %#, longitude = %#",location.coordinate.latitude, location.coordinate.longitude);
Change the format specifier in your NSLog from %# to %f. You are trying to access float value as object!
NSNotifications have a dictionary with them called userInfo where you can put information you want to be sent with the notification.
I am going to fix your code kinda going backwards, so bear with me. You really haven't used the NSNotification class as it is typically (or intended to be) used.
To fix this situation, we have to do a bunch of things. The object value of an NSNotification post is the object that is posting the NSNotification, not the object you want to pass with it.
Add the CLLocation object to a dictionary, and pass it in as the userInfo dictionary. There is also no reason for this custom notification class stuff you have. So you can get rid of the Notification.h and Notification.m
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSString *const kLocationChanged = #"NewLocation";
NSDictionary *locationDict = [NSDictionary dictionaryWithObject:newLocation forKey:#"Location"];
[[NSNotificationCenter defaultCenter] postNotificationName:kLocationChanged object:nil userInfo:locationDict];
}
So now we are posting the location information with the notification. Next, handle it when you get the notification.
- (void)locationUpdate:(NSNotification *)notification {
CLLocation *location = [[notification userInfo] valueForKey:#"Location"];
NSLog(#"latitude = %f, longitude = %f",location.coordinate.latitude, location.coordinate.longitude);
}
Also, change your view controller header to the following:
#interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, LocationDelegateProtocol> {
...
}
...
- (void)locationUpdate:(NSNotification *)notif;
#end

Retrieving Latitude & Longitude CoOrdinates, Displaying in UILabel

I am interested in grabbing my users current Latitude and Longitude coordinates, and displaying them literally as a NSSString in a UILabel on the view.
I don't need any MKMapView or to show anything graphically, just to display the coordinates in a UILabel. Is this possible?
Could anyone provide a starting block for me?
Thanks
Ya, its possible. Just import #import <CoreLocation/CoreLocation.h> and declare the delegate <CLLocationManagerDelegate>. then you can get the values in following delegate mathod.
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
CLLocationCoordinate2D location=newLocation.coordinate;
NSString *s = [NSString stringWithFormat:#"%f,%f",location.latitude,location.longitude];
}
There is the CoreLocation framework which does this job. You can get the user's current location by implementing this delegate.
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
Follow the steps:
Add MapKit.framework to your project
add to .h #import "CoreLocation/CoreLocation.h" and #import "MapKit/MapKit.h"
Use delegates as, #interface yourInterface : UIViewController < MKMapViewDelegate, CLLocationManagerDelegate >
Now Add following method to your .m file
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
[self setMapCenter:newLocation.coordinate];
[self._mapView selectAnnotation:[[self._mapView annotations] lastObject] animated:YES];
lblLong.text = [nsstring stringWithFormat:#"%f", newLocation.coordinate.longitude];
lblLat = [nsstring stringWithFormat:#"%f", newLocation.coordinate.latitude];
[self.locationManager stopUpdatingLocation];
}
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"ERROR");
}
Here mention CLLocationManager *locationManager;. good luck.

How to update a UILabel in Xcode programmatically without XIB files?

I'm stuck :(
In my application I require an update from CLLocationManager every time it gets an update to a new position. I am not using XIB/NIB files, everything I coded I have done programmatically. To the code:
the .h
#interface TestViewController : UIViewController
UILabel* theLabel;
#property (nonatomic, copy) UILabel* theLabel;
#end
the .m
...
-(void)loadView{
....
UILabel* theLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0,0.0,320.0,20.0)];
theLabel.text = #"this is some text";
[self.view addSubView:theLabel];
[theLabel release]; // even if this gets moved to the dealloc method, it changes nothing...
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
NSLog(#"Location: %#", [newLocation description]);
// THIS DOES NOTHING TO CHANGE TEXT FOR ME... HELP??
[self.view.theLabel setText:[NSString stringWithFormat: #"Your Location is: %#", [newLocation description]]];
// THIS DOES NOTHING EITHER ?!?!?!?
self.view.theLabel.text = [NSString stringWithFormat: #"Your Location is: %#", [newLocation description]];
}
...
Any ideas, or help?
(this was all hand jammed so please forgive me if it looks kinda gacked) I can provide more info if needed.
Your loadView method is wrong. You do not set the instance variable properly but instead you generate a new local variable. Change it to the following by omitting the UILabel * and do not release it because you want to keep a reference around to the label to set the text later.
-(void)loadView{
....
theLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0,0.0,320.0,20.0)];
theLabel.text = #"this is some text";
[self.view addSubView:theLabel];
}
- (void) dealloc {
[theLabel release];
[super dealloc];
}
Then later directly access the variable like this:
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
NSLog(#"Location: %#", [newLocation description]);
theLabel.text = [NSString stringWithFormat: #"Your Location is: %#", [newLocation description]];
}
Are you synthesizing theLabel in your .m file...? If not, you need to, I believe.