iphone - requestwheninuseauthorization - location manager swift tutorial
Cómo establecer la precisión y el filtro de distancia al usar MKMapView (3)
Cuando uso setShowsUserLocation
con MKMapView
para rastrear la ubicación del usuario, ¿cómo configuro la precisión y el filtro de distancia? No estoy hablando de CLLocationManager
.
Gracias,
No puede controlar la precisión del MKMapView
ubicación MKMapView
interno (el que se usa para rastrear al usuario con el punto azul), pero puede crear el suyo propio y usarlo para volver a centrar el mapa. Aquí hay una receta ...
Para gestionar los permisos de ubicación principales
En el delegado de ubicación principal:
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied){
NSLog(@"User has denied location services");
} else {
NSLog(@"Location manager did fail with error: %@", error.localizedFailureReason);
}
}
Justo antes de configurar el administrador de ubicación:
if (![CLLocationManager locationServicesEnabled]){
NSLog(@"location services are disabled"];
return;
}
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied){
NSLog(@"location services are blocked by the user");
return;
}
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized){
NSLog(@"location services are enabled");
}
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined){
NSLog(@"about to show a dialog requesting permission");
}
Para configurar la ubicación central
self.locationManager = [CLLocationManager new];
self.locationManager.purpose = @"Tracking your movements on the map.";
self.locationManager.delegate = self;
/* Pinpoint our location with the following accuracy:
*
* kCLLocationAccuracyBestForNavigation highest + sensor data
* kCLLocationAccuracyBest highest
* kCLLocationAccuracyNearestTenMeters 10 meters
* kCLLocationAccuracyHundredMeters 100 meters
* kCLLocationAccuracyKilometer 1000 meters
* kCLLocationAccuracyThreeKilometers 3000 meters
*/
self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
/* Notify changes when device has moved x meters.
* Default value is kCLDistanceFilterNone: all movements are reported.
*/
self.locationManager.distanceFilter = 10.0f;
/* Notify heading changes when heading is > 5.
* Default value is kCLHeadingFilterNone: all movements are reported.
*/
self.locationManager.headingFilter = 5;
// update location
if ([CLLocationManager locationServicesEnabled]){
[self.locationManager startUpdatingLocation];
}
Para volver a centrar el mapa con nuestro administrador de ubicación
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
MKCoordinateRegion region = { { 0.0f, 0.0f }, { 0.0f, 0.0f } };
region.center = newLocation.coordinate;
region.span.longitudeDelta = 0.15f;
region.span.latitudeDelta = 0.15f;
[self.mapView setRegion:region animated:YES];
}
Ponlo en el delegado. MKMapView no tiene un filtro de distancia o precisión, solo lo hace CLLocationManager. Lo que MKMapView tiene es un intervalo de región alrededor de un punto, en el ejemplo anterior a 0.15 grados (0.15 * 111 Km).
Cosas que probé y no funcionó
La documentación no indica de dónde está obteniendo MKMapView
sus actualizaciones. Lo intenté
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
NSLog(@"newLocation %@", newLocation.timestamp);
NSLog(@"last map location %@", [NSString stringWithFormat:@"%@",[[[self.mapView userLocation] location] timestamp]]);
}
y obtengo diferentes valores en cada uno. Parece que MKMapView
utiliza su propio CLLocationManager
, lo que significa que no puede establecer su precisión. No puede agregar su delegado para CLLocationManager
de MKMapView
tampoco.
Mi impresión es que la única forma de establecer la precisión es establecer la posición de usuario de muestra en NO y crear una anotación personalizada con un punto azul, lo que significa recentrar el mapa manualmente tal como se publicó. Puede obtener el gráfico de punto azul del SDK con el extractor de ilustraciones del proyecto github.
No sé si me falta algo o esta parte de MKMapView
simplemente apesta.
No puede establecer la precisión, sin embargo, puede obtener la precisión a través de userLocation en el método delegado MKMapView.
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
NSLog(@"%f", userLocation.location.horizontalAccuracy);
}
Para mostrar el mapa aquí hay un código de ejemplo.
Primero importe MKMapKit y CoreLocation framework en su archivo .h.
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
Agregue MKMapKit y CoreLocation Delegate en el archivo .h
@interface MapViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate>
CGPoint gameMapCenter = CGPointMake([[UIScreen mainScreen] bounds].size.width / 2, [[UIScreen mainScreen] bounds].size.height / 2);
gameMapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 640, 620)];
[gameMapView setCenter:gameMapCenter];
[gameMapView setMapType:MKMapTypeStandard];
[gameMapView setDelegate:self];
[self.view addSubview:gameMapView];
[gameMapView setShowsUserLocation:YES];
Use CLLocationManager
para buscar la ubicación del usuario.
Declarar una instancia de CLLocationManager
CLLocationManager *locationManager;
En ViewDidLoad
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManger startUpdatingLocation];
startUpdatingLocation
método startUpdatingLocation
:
(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
//Your Stuff
}