CoreLocation , MapKit Error - objective-c

I Tried To Show My Current Location In Mapkit and this is code
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//Make this controller the delegate for the map view.
self.MapView.delegate = self;
// Ensure that you can view your own location in the map view.
[self.MapView setShowsUserLocation:YES];
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
}
and I wrote This Delegate Of Mapkit
#pragma mark - MKMapViewDelegate methods.
- (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views {
MKCoordinateRegion region;
region = MKCoordinateRegionMakeWithDistance(locationManager.location.coordinate,2000,2000);
[mv setRegion:region animated:YES];
}
But I Get Wrong Location Iam In Egypt And This Give ME iam in UnitedStates
Any One Can Hep ME ???

Just in case: if you are using the simulator, the position will not be your real position. You have to set your location in the simulator:
Debug -> Location -> Custom Location (or anything else)

First of all.
You didnt used
[locationManager startUpdatingLocation];
Please add this line after you initiate the location manager variable. Also please let me know if you are seeing this location USA in Simulator.
If it is: Your simulator simulates the location given by user preferences. Get to the simulator window, there you'll get the option to show custom location as per your selection. By default it is selected as USA.
Hope it resolves your issue.

Related

Latitude and Longitude 0 when called second time in Objective-C

I am using the below code to get coordinates on click of a button
-(CLLocationCoordinate2D) getLocation{
CLLocationCoordinate2D coordinate;
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
if ([CLLocationManager locationServicesEnabled]) {
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
[locationManager startUpdatingLocation];
[locationManager startUpdatingLocation];
CLLocation *location = [locationManager location];
coordinate = [location coordinate];
}
else {
coordinate.latitude = 0.0;
coordinate.longitude = 0.0;
}
return coordinate;
}
When the button is clicked for the first time, I do get my valid coordinates, but if I click the button again, The latitude and longitude values are 0.0000
Any suggestions
Please initialize the CLLocationManager outside the method.Take the You can initialize in viewdidload method.
It may helps to you
You cannot expect [locationManager location] to return anything useful immediately after activating a location manager with [locationManager startUpdatingLocation] .
CLLocationManager takes time to acquire a location. You need to set the CLLocationManager's delegate (eg, to 'self') and then use the delegate method - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations; to get notified when the location manager has got a location that you can use.
See: https://developer.apple.com/reference/corelocation/cllocationmanagerdelegate/1423615-locationmanager?language=objc
(If you only want one location, and not a continuous stream of location updates, instead of calling 'startUpdatingLocation' call [locationManager requestLocation] - but even then you still need to use the delegate method to be notified when a location has been acquired).
You need to split out the code for creating and starting the location manager to where it is only run once (only need one location manager for the app) - eg, viewDidLoad. Then the rest of the code, to process the locations acquired, should go in the delegate method.
In reality, if you want you button click to have a location immediately, you need to have your location manager running and updating locations before your button is available to be clicked. Eg, make your button enabled=NO and when you start getting locations via the delegate method, set the button enabled=YES.

didUpdateLocations does not get called when app enters foreground, core location, ios

my goal is whenever app enters fore ground, i will fetch the location to update my weather forecast. What I do is
- (void)viewDidLoad
{
[super viewDidLoad];
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
self.locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
}
- (void)viewWillAppear:(BOOL)animated
{
self.locationManager.delegate = self;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(enterForeground) name:UIApplicationWillEnterForegroundNotification object:nil];
}
#pragma mark - Click to get weather
-(void)enterForeground {
[self.locationManager startUpdatingLocation];
}
#pragma mark - CLLocationManagerDelegate
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
NSLog#"didUpdateLocations";
}
However, enterForeGround does get call whenver I enter fore ground but didUpdateLocations doesnot get called all the time.
I dont know what I am missing some crucial things for location service. Please advice me if you have any ideas.
Thanks
There is never a guarantee that didUpdateLocations will be called. The thing you can do is when viewDidLoad is called, you can request que last location with. self.locationManager.location.
You can now check the timestamp and the precision of that location. If the data is too old or innacurate for your needs, you then call startUpdatingLocation, and when you get a fix according to your filter and accuracy, didUpdateLocations will be called.
First you need to add Location Services in background by going to Targets -> Capabilities and under "Background Modes" check on "Location Updates".
Secondly you need to start location update [self.locationManager startUpdatingLocation] somewhere appropriately (for you code provided above in viewWillAppear seems to be the best choice)
- (void)viewWillAppear:(BOOL)animated
{
self.locationManager.delegate = self;
[self.locationManager startUpdatingLocation]
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(enterForeground) name:UIApplicationWillEnterForegroundNotification object:nil];
}
Now when you app enter background mode and reenter Foreground, the locationManager delegate method should be called.

Deferring Location Updates in Background

I have a app which collects location data in foreground and background. To save battery i want to use the allowDeferredLocationUpdatesUntilTraveled property as explained in Apple Doc
From the documents, allowDeferredLocationUpdatesUntilTraveled gets set(based on time and distance) in foreground. Once app goes in the background we won't receive regular location updates instead we receive them based on the allowDeferredLocationUpdatesUntilTraveled.
I have implemented following code but the deferring does not get called in the background.
#pragma mark - Location Manager
-(void) setLocationManager
{
locationManager = [[CLLocationManager alloc] init];
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.delegate = self;
[locationManager startUpdatingLocation];
}
-(void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(#"didUpdateLocations");
if (!deferringUpdates)
{
CLLocationDistance distance = 200;
NSTimeInterval time = 60;
[locationManager allowDeferredLocationUpdatesUntilTraveled:distance timeout:time];
deferringUpdates = YES;
}
}
-(void)locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error
{
NSLog(#"didFinishDeferredUpdatesWithError");
}
SetLocationManager gets called in the foreground and works fine. Once app goes in the background i still receive regular location updates rather than allowDeferredLocationUpdatesUntilTraveled.
I have also set the following values in the info.plist file
Background Fetch
Background Location Updates
Device Capabilities - location service
Anyone luck with implementing this?
You need to set deferringUpdates back to NO within didFinishDeferredUpdatesWithError : as per Apple documentation, the "delegate’s locationManager:didFinishDeferredUpdatesWithError: method is called exactly once for each time you call (allowDeferredLocationUpdatesUntilTraveled)".
Thus allowDeferredLocationUpdatesUntilTraveled is only called once until deferringUpdates is NO.

CLLocationManager updates only on Simulator Not on Devices

Here we have to update the current location by using the location manager,and its correctly updating on simulator but its not updating on device only 4 or 5 times only repeated.why the location is not updated frequently kindly hep me to solve this problem
Here i used code is showed below
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
[locationManager startUpdatingLocation];
Delegate Method:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation: (CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
NSLog(#"newLocation: %#",newLocation);
}
This is the delegate method is calling four or five times.
If you are using location accuracy as 'kCLLocationAccuracyBestForNavigation', your device should remain plugged in.
Better you set it as 'kCLLocationAccuracyBest'. Also move to significant distance to hit the delegate. initially it will hit 4-5 times to locate you. Once your location is identified, it will call the delegate when there will be change in your location.
So, in delegate write something in file stored in documents directory in append mode. log the lat/long and Time details into it. Now move for some distance.
Join the mobile and get the file from documents directory. It must have logg the required details.
Here i solved this problem using this delegate method
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations{
}

MKMapView not showing current location, or rather, any location (in simulator)

I have a MKMapView with it's delegate set to my controller (m) class.
Code below:
-(BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Create location manager object
locationManager = [[CLLocationManager alloc] init];
// Make this instance of WhereamiAppDelegate the delegate
// it will send its messages to our WhereamiApplDelegate
[locationManager setDelegate:self];
// We want all results from the location manager
[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[mapView setShowsUserLocation:YES];
[window makeKeyAndVisible];
return YES;
}
However, all I am seeing is a map of the world without a blue annotation dot?
The simulator does not "really" support that. If you bypass enough checks, it will display Apple's HQ. Any GPS testing you need a real device.
EDIT: I believe that you can drop a pin and it will display that but as far as callbacks from CLLocationManager (via CLLocationManagerDelegate), it ain't happin in the simulator; at least the most recent ones. I can't speak for anything prior to 3.0...
self.mapview.mapType = MKMapTypeStandard;
self.mapview.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.mapview.showsUserLocation = YES;
This is all you need if you have a pointer to your map called mapView, but as Merky said, you need a real device. What you can do though is, when the simulator is running, go to "Debug ->location -> own location" and input the coords of your desired coordinate.