Documento

IMPLEMENTANDO SERVICIOS DE LOCALIZACIÓN. Ing. Roberto Mar.nez Román -­‐ [email protected] USANDO GPS •  En iOS tenemos el framework Core Loca)on para saber en qué lugar del mundo se encuentra el disposiEvo. Incluye Map Kit para visualizar mapas. •  Core LocaEon puede ubicar el disposiEvo con 3 tecnologías: •  GPS •  WiFi •  Antenas Ing. Roberto Mar.nez Román -­‐ [email protected] Ing. Roberto Mar.nez Román -­‐ [email protected] 1 USANDO CORE LOCATION •  Core LocaEon no Eene componentes para la GUI, simplemente entrega lecturas de la posición. •  LaEtud •  Longitud •  AlEtud Ing. Roberto Mar.nez Román -­‐ [email protected] MOSTRANDO LA POSICIÓN DEL DISPOSITIVO •  Vamos a crear un proyecto para visualizar la posición del disposiEvo en la pantalla (valores numéricos) •  Crea un proyecto vacío y agrega componentes para visualizar las coordenadas. Ing. Roberto Mar.nez Román -­‐ [email protected] Ing. Roberto Mar.nez Román -­‐ [email protected] 2 CONFIGURANDO EL GPS Agrega el framework CoreLocaEon al proyecto e importa CoreLocaEon.h en el archivo GpsVC.h. En la clase GpsVC •  Declara una propiedad de Epo CLLocaEonManager y otra CLLocaEon. •  Implementa el protocolo CLLocaEonManagerDelegate #import <UIKit/UIKit.h> #import <CoreLocaEon/CoreLocaEon.h> @interface GpsVC : UIViewController <CLLoca)onManagerDelegate> // Outlets `AlEtud, `Longitud, `LaEtud // ****** Para GPS @property (nonatomic,strong) CLLoca)onManager *gps; @property (nonatomic,strong) CLLoca)on *posicion; @end Ing. Roberto Mar.nez Román -­‐ [email protected] CONFIGURANDO EL GPS •  Escribe un método que configura la localización del disposiEvo. Éste se llamará desde viewDidLoad. • 
• 
• 
• 
• 
Crea el objeto de Epo CLLocaEonManager. Asigna el delegado. Asigna la precisión deseada. (la menor posible) Pide permiso al usuario para usar el GPS (iOS 8). Agregar en plist la entrada "NSLocaEonWhenInUseUsageDescripEon" Inicia el monitoreo de posición. •  Sobrescribe el método loca)onManager: didUpdateLoca)ons: que se ejecuta cada vez que hay una nueva posición Ing. Roberto Mar.nez Román -­‐ [email protected] Ing. Roberto Mar.nez Román -­‐ [email protected] 3 CONFIGURANDO EL GPS -­‐(void) configurarGPS { self.gps = [[CLLocaEonManager alloc] init]; self.gps.delegate = self; self.gps.desiredAccuracy = kCLLocaEonAccuracyBest; // Nuevo en iOS8 if ([self.gps respondsToSelector:@selector(requestWhenInUseAuthorizaEon)]) { [self.gps requestWhenInUseAuthoriza)on]; } [self.gps startUpdaEngLocaEon]; } Ing. Roberto Mar.nez Román -­‐ [email protected] ACTUALIZANDO LA POSICIÓN ACTUAL -­‐(void) loca)onManager:(CLLocaEonManager *)manager didUpdateLoca)ons:
(NSArray *)locaEons { self.posicion = [locaEons lastObject]; // La posición más reciente self.`LaEtud.text = [NSString stringWithFormat:@"%f", self.posicion.coordinate.la)tude]; self.`Longitud.text = [NSString stringWithFormat:@"%f", self.posicion.coordinate.longitude]; self.`AlEtud.text = [NSString stringWithFormat:@"%f", self.posicion.al)tude]; } Ing. Roberto Mar.nez Román -­‐ [email protected] Ing. Roberto Mar.nez Román -­‐ [email protected] 4 DETENIENDO/REANUDANDO Si la aplicación no necesita ya los datos de posición, debes detener el monitoreo para ahorro de batería. Usa las noEficaciones para saber cuando inicia/termina la app. Sugerencia: •  [[NSNoEficaEonCenter defaultCenter] addObserver:self selector:@selector(iniciarApp) name:UIApplicaEonDidBecomeAcEveNoEficaEon object:nil]; •  [[NSNoEficaEonCenter defaultCenter] addObserver:self selector:@selector(terminarApp) name:UIApplicaEonDidEnterBackgroundNoEficaEon object:nil]; Ing. Roberto Mar.nez Román -­‐ [email protected] OTROS DATOS •  Se puede obtener la precisión horizontal y verEcal de la lectura •  CLLocaEonAccuracy precisionH = self.gps.locaEon.horizontalAccuracy; •  CLLocaEonAccuracy precisionV = self.gps.locaEon.verEcalAccuracy; •  Servicio de geodecodificación •  htp://services.gisgraphy.com/street/streetsearch?
format=XML&lat=19&lng=-­‐99&from=1&to=3 Ing. Roberto Mar.nez Román -­‐ [email protected] Ing. Roberto Mar.nez Román -­‐ [email protected] 5 BONUS. SOLICITANDO MAPA A GOOGLE •  Puedes solicitar una imagen con el url: htp://maps.google.com/maps/api/staEcmap?
zoom=18&size=512x512&maptype=hybrid&markers=19.59
7509,-­‐99.225996&sensor=true Ing. Roberto Mar.nez Román -­‐ [email protected] GEODECODIFICACIÓN (API IOS) •  Usando la clase CLGeocoder podemos converEr una posición (laEtud, longitud) en texto (y al revés). -­‐(void) geoDecodificar:(CLLocaEon*)posicion { CLGeocoder *gd = [CLGeocoder new]; [gd reverseGeocodeLoca)on:posicion comple)onHandler:^(NSArray *placemarks, NSError *error) { CLPlacemark *lugar = [placemarks objectAtIndex:0]; NSString *direccion = lugar.descripEon; ITESM-­‐CEM, ITESM-­‐CEM, Boulevard CuauEtlán Izcalli 154, Hacienda de la Luz, 52929 Ciudad Lopez NSLog(@"%@",direccion); Mateos Edomex, Mexico @ <
}]; +19.59803200,-­‐99.22764590> +/-­‐ 100.00m } Ing. Roberto Mar.nez Román -­‐ [email protected] Ing. Roberto Mar.nez Román -­‐ [email protected] 6 GEODECODIFICACIÓN (API GOOGLE) NSString *dirUrl = [NSString stringWithFormat:@
htps://maps.googleapis.com/maps/api/geocode/json?latlng=%f,
%f&sensor=true, posicion.coordinate.laEtude, posicion.coordinate.longitude]; { "results" : [ { "address_components" : [ { "long_name" : "156", "short_name" : "156", "types" : [ "street_number" ] }, { "long_name" : "CuauEtlan Izcalli AEzapán", "short_name" : "CuauEtlan Izcalli AEzapán", "types" : [ "route" ] }, { "long_name" : "Villas de La Hacienda", "short_name" : "Villas de La Hacienda", "types" : [ "neighborhood", "poliEcal" ] }, { "long_name" : "Ciudad López Mateos", "short_name" : "Cd López Mateos", "types" : [ "locality", "poliEcal" ] }, { "long_name" : "Estado de México", "short_name" : "MEX", "types" : [ "administraEve_area_level_1", "poliEcal" ] }, { "long_name" : "México", "short_name" : "MX", "types" : [ "country", "poliEcal" ] }, { "long_name" : "52929", "short_name" : "52929", "types" : [ "postal_code" ] } ], "formaNed_address" : "Cuau)tlan Izcalli A)zapán 156, Villas de La Hacienda, 52929 Ciudad López Mateos, MEX, México", "geometry" : { Ing. Roberto Mar.nez Román -­‐ [email protected] MAPAS Ing. Roberto Mar.nez Román -­‐ [email protected] Ing. Roberto Mar.nez Román -­‐ [email protected] 7 MOSTRANDO MAPAS •  Mostrar el mapa sobre la pantalla es muy simple: •  Arrastra un objeto de Epo Map View desde la biblioteca de Xcode a la vista. •  Configura el Epo de mapa que quieres mostrar y habilita la opción de mostrar la ubicación del usuario. •  ¡Eso es todo!, bueno hasta antes de iOS8. Ing. Roberto Mar.nez Román -­‐ [email protected] ASIGNANDO EL PERMISO •  Para permiEr que el mapa acceda al gps (igual que en el ejemplo anterior). self.gps = [[CLLocaEonManager alloc] init]; [self.gps requestWhenInUseAuthoriza)on]; self.mvMapa.showsUserLocaEon = YES; Ing. Roberto Mar.nez Román -­‐ [email protected] Ing. Roberto Mar.nez Román -­‐ [email protected] 8 CONFIGURANDO EL MAPA -­‐ (void) viewDidLoad { [super viewDidLoad]; MKCoordinateSpan span = MKCoordinateSpanMake(0.01, 0.01); // 1º-­‐>111.131 km CLLocaEonCoordinate2D centro = CLLocaEonCoordinate2DMake(0, 0); MKCoordinateRegion region = MKCoordinateRegionMake(centro, span); [self.mvMapa setRegion:region animated:YES]; self.mvMapa.delegate = self; } Ing. Roberto Mar.nez Román -­‐ [email protected] PARA MANTENER EL MAPA CENTRADO •  Sobrescribe el método. -­‐(void) mapView:(MKMapView *) mapView didUpdateUserLoca)on:(MKUserLocaEon *) userLocaEon { [mapView setCenterCoordinate:userLocaEon.coordinate]; } Ing. Roberto Mar.nez Román -­‐ [email protected] Ing. Roberto Mar.nez Román -­‐ [email protected] 9 PARA AHORRAR BATERÍA Puedes usar las noEficaciones para encender/apagar la localización: -­‐(void) iniciar { self.mvMapa.showsUserLoca)on = YES; self.mvMapa.delegate = self; } -­‐(void) terminar { self.mvMapa.showsUserLoca)on = NO; self.mvMapa.delegate = no; } Ing. Roberto Mar.nez Román -­‐ [email protected] BONUS Ing. Roberto Mar.nez Román -­‐ [email protected] Ing. Roberto Mar.nez Román -­‐ [email protected] 10 USANDO MKPOINTANNOTATION •  Los objetos de esta clase representan pines en el mapa. @property (nonatomic,strong) MKPointAnnotaEon *anotacion; //.h self.anotacion = [[MKPointAnnotaEon alloc] init]; self.anotacion.coordinate = userLocaEon.locaEon.coordinate; self.anotacion.Etle = @"AQUI"; self.anotacion.subEtle = @"estas..."; [self.mvMapa addAnnotaEon:self.anotacion]; Ing. Roberto Mar.nez Román -­‐ [email protected] PERSONALIZAR EL PIN -­‐(MKAnnotaEonView*) mapView:(MKMapView *)mapView viewForAnnotaEon:(id<MKAnnotaEon>)annotaEon { MKPinAnnotaEonView *anotacionV= (MKPinAnnotaEonView *) [self.mvMapa dequeueReusableAnnotaEonViewWithIdenEfier:@"pin"]; if ( !anotacionV ) { anotacionV= [[MKPinAnnotaEonView alloc] initWithAnnotaEon:annotaEon reuseIdenEfier:@"pin"]; } else { anotacionV.annotaEon = annotaEon; } anotacionV.pinColor = MKPinAnnotaEonColorGreen; anotacionV.enabled = YES; anotacionV.canShowCallout = YES; anotacionV.animatesDrop = YES; anotacionV.rightCalloutAccessoryView=[UIButon butonWithType:UIButonTypeDetailDisclosure]; anotacionV.le„CalloutAccessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"estadio.jpg"]]; return anotacionV; } Ing. Roberto Mar.nez Román -­‐ [email protected] Ing. Roberto Mar.nez Román -­‐ [email protected] 11 RESPONDER AL TAP SOBRE EL PIN -­‐(void)mapView:(MKMapView *)mapView annotaEonView:(MKAnnotaEonView *)view calloutAccessoryControlTapped:(UIControl *)control { MKPointAnnotaEon *pa = (MKPointAnnotaEon*)view.annotaEon; UIAlertView *alerta = [[UIAlertView alloc] initWithTitle:@"AVISO" message:
[NSString stringWithFormat:@"Tap sobre: %@",pa.subEtle] delegate:nil cancelButonTitle:@"Aceptar" otherButonTitles:nil]; [alerta show]; } Ing. Roberto Mar.nez Román -­‐ [email protected] CAMBIANDO LA IMAGEN DEL PIN -­‐(MKAnnotaEonView*) mapView:(MKMapView *)mapView viewForAnnotaEon:(id<MKAnnotaEon>)annotaEon { MKAnnota)onView *annotaEonView = (MKPinAnnotaEonView *) [self.self.mvMapa dequeueReusableAnnotaEonViewWithIdenEfier:idenEfier]; if (annotaEonView == nil) { annotaEonView = [[MKAnnota)onView alloc] initWithAnnotaEon:annotaEon reuseIdenEfier:@"pin"]; } else { annotaEonView.annotaEon = annotaEon; } annota)onView.image = [UIImage imageNamed:@"estrella.png"]; annotaEonView.enabled = YES; annotaEonView.canShowCallout = YES; annotaEonView.rightCalloutAccessoryView=[UIButon butonWithType:UIButonTypeDetailDisclosure]; annotaEonView.le„CalloutAccessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"torres.png"]]; return annotaEonView; } Ing. Roberto Mar.nez Román -­‐ [email protected] Ing. Roberto Mar.nez Román -­‐ [email protected] 12