Implementing iPhone Location in Objective-C - iphone

So ive been trying to learn how to implement iPhone location in Objective-C. Currently I have several files:
locator.h
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#interface locator : NSObject
- (void)locationManager:(CLLocationManager *)manager;
#end
locator.m
#import "locator.h"
#import <CoreLocation/CoreLocation.h>
#implementation locator
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
CLLocationDegrees latitude = newLocation.coordinate.latitude;
CLLocationDegrees longitude = newLocation.coordinate.longitude;
}
#end
viewController.h
#import <UIKit/UIKit.h>
#import "locator.h"
#interface ViewController : UIViewController
#end
viewController.m
#import "ViewController.h"
#import "locator.h"
#import <CoreLocation/CoreLocation.h>
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self; // Set your controller as a <CLLocationManagerDelegate>.
[locationManager startUpdatingLocation];
[super viewDidLoad];
}
#end
Im sure ive made a major error sometimes but im quite confused and dont really understand what it is. Im getting 2 major errors when trying to run this.

#interface ViewController : UIViewController
#end
Must become :
#interface ViewController : UIViewController <CLLocationManagerDelegate>
#end
It should work now.
EDIT :
Do not use your own locatorclass if you just want to get the iDevice coordinates, it's faster to use this directly in your viewController.
Because if you want to do this with your own class you have to :
create a CLLocationManager variable
set up a specific init
declare some method to launch de tracking of the position of the iDevice
declare an extra method to return your coordinates or define your CLLocationManager variable as public !
And it's easier to explain :)
Hope this helps.

Usually I would make the CLLocationManager a class variable like so:
#interface ViewController : UIViewController <CLLocationManagerDelegate>
#property (strong, nonatomic) CLLocationManager *locationManager
#end
Then you will be able to call:
[self.locationManager stopUpdatingLocation];
when you desire. Also you need to implement:
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
}
In your viewcontroller to receive the delegate callback that has the location data.

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

Integrating GPS to my application

I am following a tutorial to integrate GPS to my application. I want to display the Latitude and Longitude values in the viewDidLoad method. According to the tutorial they have displayed it from another method. But i need it to be displayed in viewDidLoad. How can i modify the following code to display it in viewDidLoad ?
The HelloThereController.h view controller
#import "MyCLController.h"
#interface HelloThereViewController : UIViewController <MyCLControllerDelegate> {
MyCLController *locationController;
}
- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSError *)error;
#end
The HelloThereController.m view controller
#import "HelloThereViewController.h"
#implementation HelloThereViewController
- (void)viewDidLoad {
locationController = [[MyCLController alloc] init];
locationController.delegate = self;
[locationController.locationManager startUpdatingLocation];
//I need to print the latitude and logitude values here..
}
My MyCLController.h class
#protocol MyCLControllerDelegate
#required
- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSError *)error;
#end
#interface MyCLController : NSObject {
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
My MyCLController.m class
#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;
}
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
If this view controller loads as soon as the app loads, you can't.
it takes time for the location manager to get gps updates.
you'll need to display some ui component that lets the user know you're getting the location, such as UIActivityIndicatorView, and setup another method for displaying the coordinates when you get them.
In general you can accelerate the process sacrificing some accuracy setting the desiredAccuracy property. According to the documentation the values are:
kCLLocationAccuracyBestForNavigation
kCLLocationAccuracyBest
kCLLocationAccuracyNearestTenMeters
kCLLocationAccuracyHundredMeters
kCLLocationAccuracyKilometer
kCLLocationAccuracyThreeKilometers
Anyway you are interested in the first location, so still according to the documentation:
When requesting high-accuracy location data, the initial event delivered by the location
service may not have the accuracy you requested. The location service delivers the initial
event as quickly as possible. It then continues to determine the location with the accuracy
you requested and delivers additional events, as necessary, when that data is available.
You can try starting the location manager in the AppDelegate didFinishLaunchingWithOptions to have some more time before the view appears. As said by Frederick Cheung, locationManager.location can be nil, so it's better do the operations in the location manager delegate.

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.

iPhone GPS Location

I want to get my longitude and latitude on iPhone in objective C. Can any one guide me how to get these coordinates programmatically?
#import <Foundation/Foundation.h>
#class CLLocationManager;
#interface CLLocationController : NSObject {
CLLocationManager *locationManager;
}
#property (nonatomic, retain) CLLocationManager *locationManager;
#end
When i write above code is shows me following errors
/Hab/Folder/Classes/CLLocationController.m:10:30: error: CLLocationManager.h: No such file or directory
/Hab/Folder/Classes/CLLocationController.m:21: warning: receiver 'CLLocationManager' is a forward class and corresponding #interface may not exist
/Hab/Folder/Classes/CLLocationController.m:22: error: accessing unknown 'delegate' component of a property
Use the CLLocationManager, set an object as the delegate and start getting updates.
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.delegate = self;
[self.locationManager startUpdatingLocation];
Then implement the delegate:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation*)newLocation fromLocation:(CLLocation *)oldLocation {
NSLog([NSString stringWithFormat:#"%3.5f", newLocation.coordinate.latitude]);
NSLog([NSString stringWithFormat:#"%3.5f", newLocation.coordinate.longitude]);
}

iPhone Help: Odd Memory Leak In CoreLocation Framework

I've been working to iron out memory leaks in my program and I'm down to a few stragglers. The strange thing is that they're coming from when I use CoreLocation to get a gps location. The code is properly returning the location, but it's leaking all over the place: CFHTTPMessage, CFURLConnection, CFURLRequest, CFURLResponse, GeneralBlock-16,-32,-48, HTTPRequest, etc... Could anyone please guide me how to fix this?
Initialization of MyCLController
locationController = [[MyCLController alloc] init];
locationController.delegate = self;
[locationController.locationManager startUpdatingLocation];
Do some things and get a call back through the delegate:
[locationController release];
MyCLController.h:
#import <Foundation/Foundation.h>
#protocol MyCLControllerDelegate
#required
- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSError *)error;
#end
#interface MyCLController : NSObject {
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
MyCLController.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 {
[locationManager stopUpdatingLocation];
[self.delegate locationUpdate:newLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error {
[self.delegate locationError:error];
}
- (void)dealloc {
[super dealloc];
}
#end
You need to release the LocationManager. Make sure that you set its delegate to NULL prior to releasing. And also, it's not a good idea to just return the first result. Make sure horizontal accuracy is not < 0 and is also below some threshold, like 5000 meters. And to make it more robust, you might want to add a timer to make it stop after a given amount of time, if it couldn't find your location accurately enough.
you never release locationController