MapKit in iOS 8 not run - ios

I am building an iOS application that display a POI in a MapView, but firstly I can display the map, and with iOS8 this is begin a problem.
I read a lot question in this site, but none run on my app even if the code seems right.
I entered into myapplicationTest-info.plist the following code
<key>NSLocationAlwaysUsageDescription</key>
And the code in the file.m is this:
#import "MapViewController.h"
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
#interface MapViewController ()
#end
#implementation MapViewController
#synthesize mapView = _mapView ;
- (void)viewDidLoad
{
[super viewDidLoad];
self.mapView.delegate = self;
self.locationManager.delegate = self;
self.locationManager = [[CLLocationManager alloc] init];
if (IS_OS_8_OR_LATER) {
//[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
}
[self.locationManager startUpdatingLocation];
self.mapView.showsUserLocation = YES;
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
}
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:YES];
self.locationManager.distanceFilter = kCLDistanceFilterNone; //Whenever we move
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
NSLog(#"%#", [self deviceLocation]);
//View Area
MKCoordinateRegion region = { { 0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = self.locationManager.location.coordinate.latitude;
region.center.longitude = self.locationManager.location.coordinate.longitude;
region.span.longitudeDelta = 0.005f;
region.span.longitudeDelta = 0.005f;
[mapView setRegion:region animated:YES];
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800, 800);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
}
- (NSString *)deviceLocation {
return [NSString stringWithFormat:#"latitude: %f longitude: %f", self.locationManager.location.coordinate.latitude, self.locationManager.location.coordinate.longitude];
}
- (NSString *)deviceLat {
return [NSString stringWithFormat:#"%f", self.locationManager.location.coordinate.latitude];
}
- (NSString *)deviceLon {
return [NSString stringWithFormat:#"%f", self.locationManager.location.coordinate.longitude];
}
- (NSString *)deviceAlt {
return [NSString stringWithFormat:#"%f", self.locationManager.location.altitude];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Where is the mistake?
Why it doesn't run?

You need to provide a value for NSLocationAlwaysUsageDescription key which is the string that describes why your app wants to use location services -
For example -
<key>NSLocationAlwaysUsageDescription</key>
<string>FindMeDonuts will use your location to identify nearby donut shops</string>
Also, rather than checking the iOS version, it is better to check if CLLocationManager responds to the authorisation selector -
if ([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
}
finally, this won't stop your map from updating, but it doesn't make sense - you are assigning a delegate to your CLLocationManager before you allocate and initialise it.
You should say -
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate=self;

I don't know if i understand your problem.
if your problem is about the map is not show, you need to set frame of your map.
self.mapView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
hope i could help you

The best way is to use the -locationManager:didUpdateLocations method provided by CLLocationManagerDelegate.
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
[self.locationManager stopUpdatingLocation];
// Move this line here
self.mapView.showsUserLocation = YES;
}
After calling [self.locationManager startUpdatingLocation] in ViewDidLoad, you shouldn't set self.mapView.showsUserLocation to YES yet as permission to use location services is not yet approved. Use the delegate to wait/get a location update from the system before setting self.mapView.showsUserLocation to YES.

You also need to enable location services
if([CLLocationManager resolveClassMethod:#selector(locationServicesEnabled)]) {
[CLLocationManager locationServicesEnabled];
}

Related

How to locate my current location in iOS?

i got this error what that error meant to be.i can't understand what error it is.
so plz help
thanks
error
1.ViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController<MKMapViewDelegate>
#property (weak, nonatomic) IBOutlet MKMapView *mycurrentlocation;
#end
2. ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController #synthesize mycurrentlocation;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.mycurrentlocation.delegate = self; }
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated. }
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
MKCoordinateRegion re = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800,
800);
[self.mycurrentlocation setRegion:[self.mycurrentlocation regionThatFits:re] animated:YES];
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = userLocation.coordinate;
point.title = #"Where am I?";
point.subtitle = #"I'm here!!!";
[self.mycurrentlocation addAnnotation:point]; }
#end
Then put this line of code in the viewDidLoad method of your class:
[self.locationManager requestAlwaysAuthorization];
You need to add the core location framework and Map Kit framework.
In your AppName-Info.plist Add a new row with the key name being:
NSLocationWhenInUseUsageDescription
Or
NSLocationAlwaysUsageDescription
With the value being a string of the message that you want to be displayed:
YourAppName would like to use your location.
In your header file. (I use App Name-Prefix.pch but YourViewController.h will work too)
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
YourViewController.h
#import <MapKit/MapKit.h>
#import <MapKit/MKAnnotation.h>
#interface YourViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate> {
}
#property(nonatomic, retain) IBOutlet MKMapView *mapView;
#property(nonatomic, retain) CLLocationManager *locationManager;
YourViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
mapView.delegate = self;
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
#ifdef __IPHONE_8_0
if(IS_OS_8_OR_LATER) {
// Use one or the other, not both. Depending on what you put in info.plist
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
}
#endif
[self.locationManager startUpdatingLocation];
mapView.showsUserLocation = YES;
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
}
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:YES];
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
NSLog(#"%#", [self deviceLocation]);
//View Area
MKCoordinateRegion region = { { 0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = self.locationManager.location.coordinate.latitude;
region.center.longitude = self.locationManager.location.coordinate.longitude;
region.span.longitudeDelta = 0.005f;
region.span.longitudeDelta = 0.005f;
[mapView setRegion:region animated:YES];
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800, 800);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
}
- (NSString *)deviceLocation {
return [NSString stringWithFormat:#"latitude: %f longitude: %f", self.locationManager.location.coordinate.latitude, self.locationManager.location.coordinate.longitude];
}
- (NSString *)deviceLat {
return [NSString stringWithFormat:#"%f", self.locationManager.location.coordinate.latitude];
}
- (NSString *)deviceLon {
return [NSString stringWithFormat:#"%f", self.locationManager.location.coordinate.longitude];
}
- (NSString *)deviceAlt {
return [NSString stringWithFormat:#"%f", self.locationManager.location.altitude];
}

Having problems with iOS8 Core Location

Core Location usage change recently, but even after updating to the new specification I can't seem to get it working.
I tried starting a new project with just a view controller that changes its background color upon GPS coordinate finding or failure.
#import "ViewController.h"
#interface ViewController (){
CLLocationManager *locationManager;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
if (locationManager == nil)
{
locationManager = [[CLLocationManager alloc] init];
}
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
if (![CLLocationManager locationServicesEnabled]) {
[self.view setBackgroundColor:[UIColor redColor]];
}
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
[locationManager requestAlwaysAuthorization];
[locationManager startUpdatingLocation];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark CLLocationManagerDelegate
//
//
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation
{
[self.view setBackgroundColor:[UIColor greenColor]];
NSLog(#"lat:%f lon:%f", newLocation.coordinate.latitude, newLocation.coordinate.longitude);
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
//Debug(#"did fail with error. stop updating and return error.");
[self.view setBackgroundColor:[UIColor orangeColor]];
}
#end
I added
<key>NSLocationAlwaysUsageDescription</key>
<string>This app needs your location to provide the best service.</string>
to the Info.plist file, and still... no changes, the location icon appears on the status bar near the battery but no location ever comes, real or simulated.
Am I missing something?
Try adding the change authorisation method:
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
// This method has to be here to trigger the UIAlertView
switch (status) {
case kCLAuthorizationStatusDenied:
break;
case kCLAuthorizationStatusRestricted:
break;
case kCLAuthorizationStatusNotDetermined: {
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
[self.locationManager requestAlwaysAuthorization];
}
default:
break;
}
}
EDIT
You're using the wrong delegate method. didUpdateToLocation has been deprecated. Use this instead:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {}

Can't get user location with iOS MapKit

Getting the user location to work has been killing me...
I've read lots of threads explaining the new changes with iOS 8 and how there must be one of two keys (NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription) in the info.plist file in order for the app to ask permission to get user location. I did that.
I've also included what I believe as all the code needed for the location service to work...but it doesn't. Please see my mapViewController.h and mapViewController.m files below:
mapViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <MapKit/MKAnnotation.h>
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
#interface mapViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate>
#property(nonatomic, retain) IBOutlet MKMapView *mapView;
#property(nonatomic, retain) CLLocationManager *locationManager;
#end
mapViewController.m
#import "mapViewController.h"
#interface mapViewController ()
#end
#implementation mapViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.mapView.delegate = self;
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
#ifdef __IPHONE_8_0
if(IS_OS_8_OR_LATER) {
// Use one or the other, not both. Depending on what you put in info.plist
//[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
}
#endif
[self.locationManager startUpdatingLocation];
self.mapView.showsUserLocation = YES;
[self.mapView setMapType:MKMapTypeStandard];
[self.mapView setZoomEnabled:YES];
[self.mapView setScrollEnabled:YES];
}
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:YES];
self.locationManager.distanceFilter = kCLDistanceFilterNone; //Whenever we move
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
NSLog(#"%#", [self deviceLocation]);
//View Area
MKCoordinateRegion region = { { 0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = self.locationManager.location.coordinate.latitude;
region.center.longitude = self.locationManager.location.coordinate.longitude;
region.span.longitudeDelta = 0.005f;
region.span.longitudeDelta = 0.005f;
[self.mapView setRegion:region animated:YES];
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800, 800);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
}
- (NSString *)deviceLocation {
return [NSString stringWithFormat:#"latitude: %f longitude: %f", self.locationManager.location.coordinate.latitude, self.locationManager.location.coordinate.longitude];
}
- (NSString *)deviceLat {
return [NSString stringWithFormat:#"%f", self.locationManager.location.coordinate.latitude];
}
- (NSString *)deviceLon {
return [NSString stringWithFormat:#"%f", self.locationManager.location.coordinate.longitude];
}
- (NSString *)deviceAlt {
return [NSString stringWithFormat:#"%f", self.locationManager.location.altitude];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#end
Also, in case this is relevant, the mapViewController is tied to a tab in a Tab View Controller. When I click on the tab that includes the view controller containing MKMapView, I get the below image:
Use this code and run the application in device to get the current location.
If you run in simulator, then it will show the default location i.e Apple Inc's address as current location.
- (void)viewDidLoad
{
[super viewDidLoad];
self.locationManager = [[CLLocationManager alloc] init];
[self.locationManager setDelegate:self ];
self.mapView.showsUserLocation=YES;
[self.locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation: (CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
[self.mapView setCenterCoordinate:newLocation.coordinate animated:YES];
MKCoordinateRegion region=MKCoordinateRegionMakeWithDistance(newLocation.coordinate,70000 ,70000 );
MKCoordinateRegion adjustedRegion = [self.mapView regionThatFits:region];
[self.mapView setRegion:adjustedRegion animated:YES];
}
Note:
Turn on data or wifi in your device, or else you will face Location Accuracy error.
Add the below code to your ViewController.h class,
#interface ViewController : UIViewController<CLLocationManagerDelegate>
#property(nonatomic, retain) CLLocationManager *locationManager;
#end
And in ViewController.m class ,
-(void)viewWillAppear:(BOOL)animated{
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
[super viewWillAppear:animated];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
CLLocationCoordinate2D zoomLocation = CLLocationCoordinate2DMake(newLocation.coordinate.latitude, newLocation.coordinate.longitude);
}
Per the docs, [self.locationManager requestAlwaysAuthorization] is asynchronous. Implement the location services auth changed delegate callback and start monitoring there only after the auth status is allowed.

Map reverting to user's location, not allowing 'browse' iOS

The map screen of the app displays the user's current location. I want to allow the user to 'browse' the map (scroll around and explore other areas) and I have a button which returns the user to the point on the map with their current location BUT I'm what's happening is that the app isn't allowing the user to 'browse' the map and retain the view they are looking at, rather it jumps right back to the user's current location.
Here is some code:
-(void) setupLocation {
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
// locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"didFailWithError: %#", error);
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
// [self.mapView setCenterCoordinate:self.mapView.userLocation.coordinate animated:YES];
tempLat = newLocation.coordinate.latitude;
tempLon = newLocation.coordinate.longitude;
CLLocationCoordinate2D currentLocation = CLLocationCoordinate2DMake(tempLat, tempLon);
MKCoordinateRegion viewRegionLocation = MKCoordinateRegionMakeWithDistance(currentLocation, 100, 100);
[self.mapView setRegion:viewRegionLocation animated:YES];
locationNew = [[CLLocation alloc] initWithLatitude:newLocation.coordinate.latitude longitude:newLocation.coordinate.longitude];
locationOld = [[CLLocation alloc] initWithLatitude:oldLocation.coordinate.latitude longitude:oldLocation.coordinate.longitude];
}
I also have:
- (IBAction)stopUpdating:(id)sender {
[locationManager stopUpdatingLocation];
}
And:
- (IBAction)findMe:(id)sender {
[locationManager startUpdatingLocation];
}
Any ideas of why the map keeps jumping back to the user's current location??
Thank you very much!
Because, in your - (void)locationManager: didUpdateToLocation: fromLocation: method you set the region of your mapview to the updated location everytime.
Removing this part will solve your problem.
MKCoordinateRegion viewRegionLocation = MKCoordinateRegionMakeWithDistance(currentLocation, 100, 100);
[self.mapView setRegion:viewRegionLocation animated:YES];
EDIT 1:
add this line in your viewDidLoad method,
self.mapView.showsUserLocation = YES;
change the find me button press method like this,
-(IBAction) findMeButtonPressed:(id)sender;{
MKCoordinateRegion viewRegionLocation = MKCoordinateRegionMakeWithDistance([self.locationManager location].coordinate, 100, 100);
[self.mapView setRegion:viewRegionLocation animated:YES];
}

Drop pin at current user location iphone mkmapview

Ok, here's my attempt at using CLLoactionManager
- (void)viewDidLoad {
[super viewDidLoad];
mapView=[[MKMapView alloc] initWithFrame:self.view.frame];
//mapView.showsUserLocation=TRUE;
mapView.delegate=self;
[self.view insertSubview:mapView atIndex:0];
CLLocationManager *locationManager=[[CLLocationManager alloc] init];
locationManager.delegate=self;
locationManager.desiredAccuracy=kCLLocationAccuracyNearestTenMeters;
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
mStoreLocationButton.hidden=FALSE;
location=newLocation.coordinate;
//One location is obtained.. just zoom to that location
MKCoordinateRegion region;
region.center=location;
MKCoordinateSpan span;
span.latitudeDelta=0.01;
span.longitudeDelta=0.01;
region.span=span;
[mapView setRegion:region animated:TRUE];
}
My problem is that [locationManager startUpdatingLocation]; doesn't seem to fire the next method. What am I missing? I've tried setting breakpoints in the second method, but they never catch. Obviously it's not being used.
You should look into using a CLLocationManager to get the current location to feed your MKMapView with the correct coordinates.
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
MKMapView *map = [[MKMapView alloc] init];
[locationManager startUpdatingLocation];
CLLocationCoordinate2D _coordinate = locationManager.location.coordinate;
MKCoordinateRegion extentsRegion = MKCoordinateRegionMakeWithDistance(_coordinate, 800, 800);
[map setRegion:extentsRegion animated:YES];
This looks like a good place to start. In order to drop a pin, you need to know the coordinates. Using - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation will help you get the user's location so that you can create an MKAnnotation and MKPinAnnotationViews. Its pretty straight forward once you get started.

Resources