what i'm trying to reach is to display annotation with the city name.
So I have a class MapPoint :
#interface MapPoint : NSObject<MKAnnotation,MKReverseGeocoderDelegate> {
NSString* title;
NSString* cityName;
CLLocationCoordinate2D coordinate;
MKReverseGeocoder* reverseGeo;
}
#property (nonatomic,readonly) CLLocationCoordinate2D coordinate;
#property (nonatomic,copy) NSString* title;
#property (nonatomic,copy) NSString* cityName;
-(id) initWithCoordinate:(CLLocationCoordinate2D)c tilte:(NSString*)t;
#end
I implemented it like this :
#implementation MapPoint
#synthesize title,coordinate,cityName;
-(id) initWithCoordinate:(CLLocationCoordinate2D)c tilte:(NSString*)t
{
[super init];
coordinate = c;
reverseGeo = [[MKReverseGeocoder alloc] initWithCoordinate:c];
reverseGeo.delegate = self;
[reverseGeo start];
[self setTitle:t];
return self;
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark
{
NSString* city = [placemark.addressDictionary objectForKey:(NSString*)kABPersonAddressCityKey];
NSString* newString = [NSString stringWithFormat:#"city-> %#",city];
[self setTitle:[title stringByAppendingString:newString]];
}
-(void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error{
NSLog(#"error fetching the placemark");
}
-(void)dealloc
{
[reverseGeo release];
[cityName release];
[title release];
[super dealloc];
}
#end
Then, in my CoreLocation delegate I use MapPoint like that:
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
MapPoint* mp = [[MapPoint alloc] initWithCoordinate:[newLocation coordinate] tilte:[locationTitleField text]];
[mapView addAnnotation:mp];
[mp release];
}
Now, I have 2 issues I'm not sure of :
Is it correct to put reverseGeo as a data member , or a better option would be to just
alloc it inside the initializer and release it inside the didFindPlacemark/didFailWithError delegates(is it even possible to release it there) ?
How can I make sure then when my annotation get displayed I know for sure that the reverseGeo came back with an answer (placemark or error - whatever it is).
Maybe it's just wrong to wait for network response and I should leave it like that - I'm just not sure then when/if network response will arrive it will update the annotationView within the MapView accordingly.
Please elaborate as much as you can.
Thanks
It's fine to store it as a data member.
It looks like you're leaving a trail of annotations for the user's current location? If you're supplementing a regular user's-current-location annotation with a "bread crumb trail" showing where the user has been, then you need to wait to add the point to the map until you get the annotation back (if that's the behavior you want). I would either do that by making the class that manages your map be the MKReverseGeocoder delegate (and have it set the title property and then add the annotation to the map in reverseGeocoder:didFindPlacemark) or add a map reference to your MapPoint class and have it add itself to the map in the same callback.
By the way, the documentation for MKReverseGeocoder includes the following text:
When you want to update the location automatically (such as when the user is moving), reissue the reverse-geocoding request only when the user's location has moved a significant distance and after a reasonable amount of time has passed. For example, in a typical situation, you should not send more than one reverse-geocode request per minute.
Related
Currently I am working in a project , its requirement is to get the current location information specially latitude and longitude value in every 200m interval using wifi network or Cellular network without using gps as it is consuming more battery life.
Is this possible in ios latest version .
If any one having any idea ,please share with me ,
Thank you.
Have a look in to CLLocationManager, That will be able to tell you where the user is located.
.h
#import <CoreLocation/CoreLocation.h>
#property(nonatomic,retain) CLLocationManager *locationManager;
.m
- (void)viewDidLoad
{
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
//let the user know the purpose
locationManager.purpose = #"Enable location services";
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
NSLog(#"User latitude: %f",locationManager.location.coordinate.latitude);
NSLog(#"User longitude: %f",locationManager.location.coordinate.longitude);
[locationManager startUpdatingLocation];
}
It only way to get your location info in every 200m that is CLLocationManager's startUpdatingLocation. But it is comsuming a lot of battery.
But there is a little different way to get your location when it is changed.
CLLocationManager's startMonitoringSignificantLocationChanges.
Here is a Link
The location manager protocol reference
https://developer.apple.com/library/mac/#documentation/CoreLocation/Reference/CLLocationManagerDelegate_Protocol/CLLocationManagerDelegate/CLLocationManagerDelegate.html
1.In Appdelegate
#import <CoreLocation/CoreLocation.h>
In #interface file
CLLocationManager *locationManager;
#property (nonatomic, retain) CLLocationManager *locationManager;
and add protocol CLLocationManagerDelegate protocol.
2.Impliment these functions in .m.
#synthesize locationManager;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.distanceFilter = 1.0;
[self.locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
// Show an alert or otherwise notify the user
}
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
}
- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error
{
}
Note:If you want to debug first set current location in simulator
At Debug--->Location--->Custom Location.
its requirement is to get the current location information specially latitude and longitude value in every 200m interval using wifi network or Cellular network without using gps as it is consuming more battery life
The documentation for CLLocationManager has this to say about distance and the GPS hardware:
... setting the desired accuracy for location events to one kilometer gives the location manager the flexibility to turn off GPS hardware and rely solely on the WiFi or cell radios.
For less than 200 meters you'll probably need to roll-your-own solution here.
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
[locationManager stopUpdatingLocation];
[locationManager stopMonitoringSignificantLocationChanges];
[self performSelector:#selector(stopUpadateLocation)];
CLLocation *location = [locationManager location];
CLLocationCoordinate2D coord;
coord=[location coordinate];
NSLog(#"coord %f %f", coord.latitude, coord.longitude);
NSString *urlString = [NSString stringWithFormat:#"http://maps.google.com/maps/geo?q=%f,%f&output=json", newLocation.coordinate.latitude, newLocation.coordinate.longitude];
NSURL *url = [NSURL URLWithString:urlString];
NSString *locationString = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
NSDictionary *dic=[locationString JSONValue];
NSLog(#"locationString:%#",locationString );
[strAddr setString:[AppUtility removeNull:[NSString stringWithFormat:#"%#",[[[dic valueForKey:#"Placemark"] objectAtIndex:0] valueForKey:#"address"]]]];
[txtNear setText:strAddr];
}
- (void)startUpdateLocation{
[locationManager startUpdatingLocation];
}
- (void)stopUpadateLocation{
[locationManager stopUpdatingLocation];
[locationManager stopMonitoringSignificantLocationChanges];
}
You have to use the Core Location method startMonitoringSignificantLocationChanges which uses only the wifi or cellular networks!
I can get the result (like locality, ISOcountryCode, etc) by CLGeocoder's reverseGeocodeLocation:completionHandler: method successfully.
But how can I match the place with the result?
e.g.: If the city (locality) of result is Hangzhou City, I can match it simply by using
if ([placemark.locality isEqualToString:#"Hangzhou City"]) {...}
But as you know, there're millions of cities, it's impossible to get the city name one by one and hard code into my app.
So, is there any way to solve this problem? Or does there any framework exist? Or just several files contain countries & cities' name that match the CLGeocoder's result? Even fuzzy coordinate matching solution is okay (I mean, a city has its own region, and I can determine the city just by coordinate, but I still need to get every city's region area at the moment).
Deployment Target iOS5.0
Well there is a easier way, you can use the reverse GeocodeLocation to get the information of the place. You have to know this won't work in every city thought.
For more information check Apple's CLGeocoder Class Reference and Geocoding Location Data documentation.
So you can create and object that handle the service
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#interface locationUtility : NSObject<CLLocationManagerDelegate>{
CLLocationManager *locationManager;
CLPlacemark *myPlacemark;
CLGeocoder * geoCoder;
}
#property (nonatomic,retain) CLLocationManager *locationManager;
#end
and the implementation
#import "locationUtility.h"
#implementation locationUtility
#synthesize locationManager;
#pragma mark - Init
-(id)init {
NSLog(#"locationUtility - init");
self=[super init];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
[locationManager startMonitoringSignificantLocationChanges];
geoCoder= [[CLGeocoder alloc] init];
return self;
}
- (void) locationManager:(CLLocationManager *) manager didUpdateToLocation:(CLLocation *) newLocation
fromLocation:(CLLocation *) oldLocation {
[geoCoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, NSError *error) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
myPlacemark=placemark;
// Here you get the information you need
// placemark.country;
// placemark.administrativeArea;
// placemark.subAdministrativeArea;
// placemark.postalCode];
}];
}
-(void) locationManager:(CLLocationManager *) manager didFailWithError:(NSError *) error {
NSLog(#"locationManager didFailWithError: %#", error.description);
}
#end
I need to get current user location but I don't know if it has changed or not. Can I request a forced location update from CLLocationManager? Or is there any other way to do that?
Stopping and restarting the LocationManager should force the device to re-acquire an initial position.
[locationManager stopUpdatingLocation];
[locationmanager startUpdatingLocation];
I have had the same problem in one of my apps. I actually had to change the app structure.
This is what I have done:
This class has a public method. -(void)locateMe; an abstract class needs to instantiate this class and run the locateMe then when userIsLocated a notification will be broadcasted. and another method can get the result coordinates from (CLLocation *)currentLocation;
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface ManageUserLocation : NSOperation <CLLocationManagerDelegate> {
CLLocationManager *locationManager;
CLLocation *currentLocation;
}
#property (nonatomic, retain) CLLocationManager *locationManager;
#property (nonatomic, retain) CLLocation *currentLocation;
-(void) locateMe;
#end
in the .m
#import "ManageUserLocation.h"
#implementation ManageUserLocation
#synthesize locationManager;
#synthesize currentLocation; // Other classes use this to get the coordination even better you can make another method that even dont get the direct access to currentLocation. It is up to you.
- (id)init
{
self = [super init];
if (self) {
//[self locateMe]; // Just a hook if you need to run it
}
return self;
}
-(void) locateMe {
self.locationManager = nil;
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.desiredAccuracy=kCLLocationAccuracyBest;
self.locationManager.delegate = self;
[self.locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
// User location has been found/updated, load map data now.
[self.locationManager stopUpdatingLocation];
currentLocation = [newLocation copy];
// WooHoo Tell everyone that you found the userLocation
[[NSNotificationCenter defaultCenter] postNotificationName:#"userLocationIsFound" object:nil];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
// Failed to find the user's location. This error occurs when the user declines the location request or has location servives turned off.
NSString * errorString = #"Unable to determine your current location.";
UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:#"Error Locating" message:errorString delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
[errorAlert release];
[locationManager stopUpdatingLocation];
}
- (void)dealloc { #warning dont forget this :) }
#end
Hope this help.
I think is contrary to Apple Guidelines to force updates.
Apple says geo-update will occur automatically, but at un unknown time.
Is there a way to return the users location as a string from a model?
I have a model thats job is to download same JSON data from a web service. When sending in my request I need to add ?lat=LAT_HERE&lng=LNG_HERE to the end of the string.
I have seen tons of examples using the map or constantly updating a label. But I cant find out how to explicitly return the lat and lng values.
Im only 2 days into iPhone dev so go easy on me :)
You need to leverage Core Location, specifically CLLocationManager. Apple doesn't provide any CL programming guide, so just look at one of the samples like LocateMe to see how to do it.
You need to use CLLocationManager like this:
- (void)viewDidLoad
{
// this creates the CCLocationManager that will find your current location
CLLocationManager *locationManager = [[[CLLocationManager alloc] init] autorelease];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
[locationManager startUpdatingLocation];
}
// this delegate is called when the app successfully finds your current location
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
// retrieve lat and lng in a string from newLocation.coordinate
NSString *lat = [NSString stringWithFormat:#"%d", newLocation.coordinate.latitude];
NSString *lng = [NSString stringWithFormat:#"%d", newLocation.coordinate.longitude];
}
// this delegate method is called if an error occurs in locating your current location
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"locationManager:%# didFailWithError:%#", manager, error);
}
I am using the location manager to generate location data that I send in a URL to down load data. The first time I call the location manager, it correctly returns the current location and based on the current location I can fetch the data from the URL.
However, when I attempt to retrieve the current location a second time, I receive a EXC_BAD_EXCESS.
When I try debugging with NSZombieEnabled it shows me FirstViewController.recievedData as a zombie in the didReceiveResponse method. (see marked code below)
I dug further and I found that after releasing the initial connection an unknown connection is established and then it tries to access receivedData which is already released .
The header file info :`
#import <CoreLocation/CoreLocation.h>
define SECS_OLD_MAX 1
#interface FirstViewController : UIViewController<CLLocationManagerDelegate> {
UIActivityIndicatorView *spinner;
CLLocationManager *locationManager;
CLLocation *startingPoint;
UIButton *relocateMe;
NSMutableData *receivedData;
NSString *lat;
NSString *lon;
}
#property (nonatomic, retain) IBOutlet UIActivityIndicatorView *spinner;
#property (nonatomic, retain) CLLocationManager *locationManager;
#property (nonatomic, retain) CLLocation *startingPoint;
#property (nonatomic, retain) IBOutlet UIButton *relocateMe;
#property (nonatomic, retain) NSMutableData *receivedData;
#property (nonatomic, retain) NSString *lat;
#property (nonatomic, retain) NSString *lon;
`
The .m file code :
//starting the manger :
[spinner startAnimating];
**EDIT**************************ADDED IN THE AUTORELEASE POOL BY HIB********************************
self.locationManager = [[[CLLocationManager alloc] init]autorelease];
// Detecting the user device
NSString *currentDevice = [[UIDevice currentDevice] model];
// if its iPhone then locate the current lattitude and longitude
if([currentDevice isEqualToString:#"iPhone"] || [currentDevice isEqualToString:#"iPhone 3G"] || [currentDevice isEqualToString:#"iPhone 3G S"]){
DLog(#"I have identified the device as an iPhone");
if(locationManager.locationServicesEnabled == YES){
DLog(#"ok now the location manager gets the property");
locationManager.delegate = self;
// This is the most important property to set for the manager. It ultimately determines how the manager will
// attempt to acquire location and thus, the amount of power that will be consumed.
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
// Once configured, the location manager must be "started".
[locationManager startUpdatingLocation] ;
}else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Oops!"
message:#"Please enable location servies"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
}
//if its iPod then fetch the city based restaurants
else if([currentDevice isEqualToString:#"iPod touch"] || [currentDevice isEqualToString:#"iPod touch 2G"]){
}
else if([currentDevice isEqualToString:#"iPhone Simulator"]){
//TechZen says: there appears to be some code missing here, not sure if its relevant
}
//didupdatetolocation method
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
// store the location as the "best effort"
DLog(#"Lat = %g Long = %g",newLocation.coordinate.latitude,newLocation.coordinate.longitude);
NSDate *eventDate = newLocation.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
DLog(#"NSTIME INTERVAL = %i",howRecent);
//Is the event recent and accurate enough ?
if (abs(howRecent) < SECS_OLD_MAX) {
self.lat = [NSString stringWithFormat:#"%g",newLocation.coordinate.latitude];
self.lon = [NSString stringWithFormat:#"%g",newLocation.coordinate.longitude];
[[NSUserDefaults standardUserDefaults] setObject:lat forKey:#"LATITUDE"];
[[NSUserDefaults standardUserDefaults] setObject:lon forKey:#"LONGITUDE"];
DLog(#"inside Lat = %g Long = %g",newLocation.coordinate.latitude,newLocation.coordinate.longitude);
self.startingPoint = newLocation;
[locationManager stopUpdatingLocation];
**EDIT********************************REMOVED BY HIB******************************
self.locationManager = nil;
[locationManager release];
**EDIT********************************REMOVED BY HIB******************************
**ADDED BY HIB********************************************
locationManager.delegate = nil;
**ADDED BY HIB********************************************
#try {
//passing the parameter for more condition
self.lat = [NSString stringWithFormat:#"%g",startingPoint.coordinate.latitude];
self.lon = [NSString stringWithFormat:#"%g", startingPoint.coordinate.longitude];
NSString *string2 = [[NSString alloc] initWithFormat:#"%#/Service.asmx/someMethod?lat1=%g&lon1=%g&recordSize=0"
,[[NSUserDefaults standardUserDefaults] stringForKey:#"textEntry_key"],startingPoint.coordinate.latitude,startingPoint.coordinate.longitude];
NSURL *url = [[NSURL alloc] initWithString:string2];
[string2 release];
NSMutableURLRequest* request2=[NSMutableURLRequest requestWithURL:url];
[request2 setHTTPMethod:#"GET"];
[request2 setTimeoutInterval:25.0];
[[NSURLCache sharedURLCache] setMemoryCapacity:0];
[[NSURLCache sharedURLCache] setDiskCapacity:0];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:request2 delegate:self];
if (theConnection) {
receivedData = [[NSMutableData data]retain];
} else {
// inform the user that the download could not be made
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Sorry !"
message:#"The server is not avaialable \n Please try againa later"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[spinner stopAnimating];
}
[url release];
}
#catch (NSException * e) {
}
#finally {
}
}
}
//and the delegate methods
#pragma mark -
#pragma mark connection methods
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
// this method is called when the server has determined that it
// has enough information to create the NSURLResponse
// it can be called multiple times, for example in the case of a
// redirect, so each time we reset the data.
// receivedData is declared as a method instance elsewhere
**************************************the zombie is here *********************************
[receivedData setLength:0];
*****************************************************************************************
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// append the new data to the receivedData
// receivedData is declared as a method instance elsewhere
[receivedData appendData:data];
}
- (void)connection:(NSURLConnection *)connection
didFailWithError:(NSError *)error
{
[spinner stopAnimating];
// release the connection, and the data object
[connection release];
// receivedData is declared as a method instance elsewhere
[receivedData release];
// inform the user
DLog(#"Connection failed! Error - %# %#",
[error localizedDescription],
[[error userInfo] objectForKey:NSErrorFailingURLStringKey]);
// alert the user in the inter face.
UIAlertView* alert = [[UIAlertView alloc]initWithTitle:#"Sorry !"
message:#"The server is not available.\n Please try again later."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// do something with the data
// receivedData is declared as a method instance elsewhere
DLog(#"Succeeded! Received %d bytes of data",[receivedData length]);
[spinner stopAnimating];
// release the connection, and the data object
if(receivedData == nil)
{
UIAlertView* alert = [[UIAlertView alloc]initWithTitle:#"Sorry !"
message:#"The server is not available.\n Please try again later or select city."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
[spinner stopAnimating];
}
else
{
//just parse and use the data
}
[connection release];
[receivedData release];
}
Please help . I am stuck.
You have a systematic problem with not properly accessing your class properties. The properties will not be automatically retained and released unless you use the self.propertyName to force the call to the accessors. For example:
[locationManager stopUpdatingLocation]; <-- direct access
self.locationManager = nil; <-- access through generated accessor
[locationManager release]; <-- direct access again with release bypassing the automatic memory management
You should have:
[self.locationManager stopUpdatingLocation];
self.locationManager = nil;
//[locationManager release]; this line is now unneeded because the accessor handles it
You have the same problem with recievedData and startingPoint. In the vast majority of cases, if you use the synthesized accessors you only need to call release on retained properties in your dealloc. Use the accessors will clear up your zombie problem.
Without knowing where the EXC_BAD_ACCESS occurs I can't say definitively but since that error often occurs when messaging an non-existant object I can say that it is very likely that your bypassing of the property accessors and your releasing of them manually is probably causing the code to send to nilled property.
Fix the access and see if that resolves the problem.
Edit01:
TechZen the problem is removed 50 %.
my application runs nicely in the
debugging mode but when I pull out the
cable and starts again it crashes .
the problem is certainly with location
manager . but I am not clear about
retains and release of location
manager . can you help me
I'll take a stab at it. For your memory management:
Always access your
self.locationManager using the
self-dot-propertyName notation to
make sure you utilize the
retention/release mechanism of
generated accessors.
Never call release on any property
except in the dealloc method. If
you use the self-dot notation and
have the property set to retain, all
but the end of life release is
handled automatically for you. This
includes times when you nil the
property or set it to another object.
When in doubt, don't release. It's easier to fix a memory leak latter than it is to track down a bug caused by an object that disappears at random points in the code because its retain count is skewed. Trying to hard to prevent leaks when your learning the environment is a form of premature optimization that causes more trouble than it prevents.
I note that in your locationManager:didUpdateToLocation:fromLocation: method you don't actually query the locationManager passed to the method but instead query the class's self.locationManager property. This may or not be a problem but it is best to use the passed in manager to make sure you are in fact querying the manager instance that updated. I also don't think it necessary to destroy and recreate the location manager repeatedly. I think you can initialize it once and keep it around (check the docs on that.)
If cleaning up your property references and using the passed manager does not help, I suggest you post a new question with the cleaned up code. At that point you will legitimately have a new issue and besides we need to see the cleaned up code to spot the problem.
Edit02:
(Based on new code)
You don't need to autorelease your 'self.locationManager' property here:
self.locationManager = [[[CLLocationManager alloc] init]autorelease];
You only use autorelease when you create an object and in your class and then send it to another class. You never autorelease properties of class.
You need to stop trying to release your declared properties. You never release properties defined with retain except in the dealloc method. You are stepping on the properties generated accessors that maintain the retain count automatically.
Your are still not using the accessors consistently. This:
if(locationManager.locationServicesEnabled == YES){
DLog(#"ok now the location manager gets the property");
locationManager.delegate = self;
// This is the most important property to set for the manager. It ultimately determines how the manager will
// attempt to acquire location and thus, the amount of power that will be consumed.
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
// Once configured, the location manager must be "started".
[locationManager startUpdatingLocation] ;
should be:
if(self.locationManager.locationServicesEnabled == YES){
DLog(#"ok now the location manager gets the property");
self.locationManager.delegate = self;
// This is the most important property to set for the manager. It ultimately determines how the manager will
// attempt to acquire location and thus, the amount of power that will be consumed.
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
// Once configured, the location manager must be "started".
[self.locationManager startUpdatingLocation] ;
and this:
locationManager.delegate = nil;
should be:
self.locationManager.delegate = nil; //<-- why are you doing this anyway?
You need to track down all references to all your declared properties and affix self. to each one (expect inside a properties custom accessor which you don't seem to have use -- which is good in this case.)
I strongly suspect your problem is your unnecessary fiddling with the retention of the self.locationManager property. You maybe causing the location manager to disappear at random.
You are still not using the passed manager in locationManager:didUpdateToLocation:fromLocation: I suggest you do so or at least test that the passed manager is the same object as your self.locationManager. simply replace self.locationManager with manager.
One think you are certainly doing wrong: you need to allocate receivedData before you start the NSURLConnection. It will fork in the background right when you alloc/init it, so receivedData needs to be ready before, not after.
You are releasing recievedData at the end of a connection but are not setting your pointer to nil - it will still be pointing at where recievedData used to be.
Instead of
[recievedData release];
try
self.recievedData = nil;
Hope that helps,
Sam
I could not find the source of your problem but you have a leak in
self.locationManager = [[CLLocationManager alloc] init];
you should use
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
instead.
Edit: Download Charles Web Proxy, check what connections you are making, what responses you get, and maybe we'll have a better idea then.
Edit after Comments: The autogenerated accessor property defined to retain automatically retains the passed object, and releases it when you set the property to nil/or release. So it soes ITS job, but its YOUR job to keep track of memory management of the passed object. So, yes, the initial code above has a LEAK, and you should do your job and RELEASE/AUTORELEASE your ALLOCATED object, which in this case happens to be [[CLLocationManager alloc] init].
Edit :
I don't know how this comment can get -1. It's simple memory management. The answers on this thread all agree this is a correct post:
iPhone: Is this a leak or not
I am not sure what was the actual problem . but when I was comparing the apple LocateMe example I see locatiomManager.delegate = nil; It solves the problem completely .