Desarrollo de aplicaciones para dispositivos móviles:
Programación para iOS
Luis Montesano ' Bob D/ Nvsjmmp
Índice
Aprovechando el hardware “específico”: Sensores del iPhone
• Vistas web, mapas, localización
• Multitouch
• Giróscopo, acelerómetro
• Cámara
localización: CORE LOCATION
“Servicio” para que la aplicación acceda a las estimaciones de localización
• Localización de 3 sensores: GPS + Wifi + Red de móviles. Cuanto más preciso más gasto de bateria. Se comprueban/complementan todos los posibles.
• Clase básica: CLLocation!
@property (readonly) CLLocationCoordinate2D coordinate; !@property(readonly) CLLocationDistance altitude; !
@property (readonly) CLLocationAccuracy horizontalAccuracy; // metros!@property (readonly) CLLocationAccuracy verticalAccuracy; // metros!(kCLLocationAccuracyBestForNavigation; kCLLocationAccuracyBest; kCLLocationAccuracyNearestTenMeters;
kCLLocationAccuracyHundredMeters; kCLLocationAccuracyKilometer; kCLLocationAccuracyThreeKilometers;) !
Y velocidad, orientación, timestamp,… !
- (CLLocationDistance)distanceFromLocation:(CLLocation *)otherLocation; //metros !
localización: CORE LOCATION
Crear un CLLocationManager: alloc/init + configurar + arrancar
• Comprobar que tenemos el hardware necesario. "@property BOOL headingAvailable; !"@property BOOL locationServicesEnabled;
• Crear CLLocationManager y establecer el “delegado”. "CLLocationManager *clm = [[CLLocationManager alloc] init]; !
"@property(assign, nonatomic) id <CLLocationManagerDelegate> delegate;
• Configurar el manager "clm.distanceFilter=10.0; //minimum distance change to report,in meters �"clm.desiredAccuracy = kCLLocationAccuracyTenMeters; !
• Arrancar la monitorización de los cambios: Monitorización continua: [clm startUpdatingLocation]; !
"Monitorización de cambios “significativos”: - (void)startMonitoringSignificantLocationChanges; !"Monitorización por zonas: - (void)startMonitoringForRegion:(CLRegion *) desiredAccuracy:(CLLocationAccuracy); !"Monitorización de la orientación: - (void)startUpdatingHeading; !
localización: CORE LOCATION
• El delegado del “manager recibira las notificaciones, por ejemplo:!- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)
newLocationfromLocation:(CLLocation *)oldLocation; !
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading;!
• También se puede acceder directamente CLLocation *location = clm.location; !CLHeading *heading = clm.heading; !
• Manejar errores/interferencias
• Solicitar permiso al usuario para usar servicios de localización
localización: CORE LOCATION
Eventos
Además de “manejadores” de eventos relacionados con las vistas y el programa (load, unload, appear, …) hay muchos otros tipos de eventos que podemos “gestionar” y capturar generados por los sensores.
• Preprocesados : “shake”, gestureRecognizer (gestos típicos) y “Servicios” (localización, movimiento)
• Datos “en crudo” (procesado personalizado de gestos o lecturas en crudo de los sensores)
Eventos UIEvent : Eventos de (multi-)touch, de movimiento y del control-remoto.typetypedef enum { UIEventTypeTouches, UIEventTypeMotion, UIEventTypeRemoteControl,} UIEventType;
.subtypetypedef enum { UIEventSubtypeNoneUIEventSubtypeMotionShakeUIEventSubtypeRemoteControlPlay UIEventSubtypeRemoteControlPause UIEventSubtypeRemoteControlStop UIEventSubtypeRemoteControlTogglePlayPause UIEventSubtypeRemoteControlNextTrack UIEventSubtypeRemoteControlPreviousTrack UIEventSubtypeRemoteControlBeginSeekingBackward UIEventSubtypeRemoteControlEndSeekingBackward UIEventSubtypeRemoteControlBeginSeekingForward
UIEventSubtypeRemoteControlEndSeekingForward} UIEventSubtype;
Eventos (multi)-touch
• UIControlEvents (código o IB)
(UIControl es la clase “base” para objetos de “control”: botones,…)
Qué es cada evento? (ejemplo: ControlDemo)
UIControlEventTouchDown
UIControlEventTouchDownRepeat
UIControlEventTouchDragInside
UIControlEventTouchDragOutside
UIControlEventTouchDragEnter
UIControlEventTouchDragExit
UIControlEventTouchUpInside
UIControlEventTouchUpOutside
UIControlEventTouchCancel
Eventos (multi)-touch UITouch: representa un toque (un dedo sólo)
@property(nonatomic,readonly) NSTimeInterval timestamp;
@property(nonatomic,readonly) UITouchPhase phase; (inicio, moviendo, parado, fin)
@property(nonatomic,readonly) NSUInteger tapCount;
@property(nonatomic,readonly,retain) UIWindow *window;
@property(nonatomic,readonly,retain) UIView *view;
- (CGPoint)locationInView:(UIView *)view; - (CGPoint)previousLocationInView:(UIView *)view;
UIEvent: contiene un conjunto de “toques” @property(nonatomic,readonly) NSTimeInterval timestamp;
-(NSSet *)allTouches;
-(NSSet *)touchesForWindow:(UIWindow *)window; -(NSSet *)touchesForView:(UIView *)view;
UIResponder: interface para objetos que manejen eventos
(super de UIApplication, UIView, UIWindow…) - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
Eventos (multi)-touch • Activar en UIView : property BOOL multipleTouchEnabled;
Multiple-touch en una vista
Touchs en varias vistas
Eventos (multi)-touch • Las subclases de UIView y UIViewController deben manejar (implementar)
todos los métodos relacionados con “touch” (y no se lo pasan al super), aunque sea null.
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
• Las demás subclases de elementos de UIKit pueden implementar los que se quiera, pero además deben pasar el evento al super [super touchesBegan:theTouches withEvent:theEvent];
Eventos (multi)-touch
Para los gestos típicos, más fácil! UIGestureRecognizer (abstract)
Actua de”supervisor” cada vez que ocurre un UITouch en una vista:
UIView: @property(nonatomic,copy) NSArray *gestureRecognizers
subclasses de UIGestureRecognizer • UITapGestureRecognizer• UIPinchGestureRecognizer• UIRotationGestureRecognizer• UISwipeGestureRecognizer• UIPanGestureRecognizer• UILongPressGestureRecognizer
Eventos (multi)-touch
UIPanGestureRecognizer– translationInView: – setTranslation:inView: – velocityInView:
UIPinchGestureRecognizer@property CGFloat scale; @property (readonly) CGFloat velocity
UIRotationGestureRecognizer@propertyCGFloatrotation @property (readonly) CGFloat velocity;
UISwipeGestureRecognizer@property UISwipeGestureRecognizerDirection direction @property NSUInteger numberOfTouchesRequired;
UITapGestureRecognizer@property NSUInteger numberOfTapsRequired; @property NSUInteger numberOfTouchesRequired;
UILongPressGestureRecognizer@property(nonatomic) CFTimeInterval minimumPressDuration;
Los gestos tienen distintas propiedades y métodos para configurar y manejarlos. Algunos son: Todos tienen @property (readonly) UIGestureRecognizerState state; (Possible, Began, Changed, Ended, Cancelled, Failed, Recognized)
Se pueden “programar” nuevos “gestureRecognizer”
Eventos (multi)-touch
Añadir gestureRecognizer a UIView desde un Controller
- (void)viewDidLoad{
UIView*panView=...; //Vista del controlador donde queremos reconocer gestos
UIGestureRecognizer *pangr = [[UIPanGestureRecognizer alloc] initWithTarget:panView action:@selector(pan:)];
[panView addGestureRecognizer:pangr];
[pangr release];}
• UIView: reconocer gestos • Cualquier objeto: pedir a UIView que reconozca gestos (mensaje “addGesture…”). • Normalmente UIView maneja los gestos reconocidos (no es obligatorio)
Método del “target” para manejar el gesto
Definir como “procesar” el evento
- (void)pan:(UIPanGestureRecognizer *)recognizer{
if ((sender.state == UIGestureRecognizerStateChanged) || (sender.state == UIGestureRecognizerStateEnded)) { CGPoint translation = [recognizer translationInView:self];
// mover algun elemento de la vista “afectada” (translation.x, translation.y) // e.g. si estamos en un grafico y el origen es una “property” origin
self.origin = CGPointMake(self.origin.x+translation.x, self.origin.y+translation.y)
[recognizer setTranslation:CGPointZero inView:self];}
}
Eventos (multi)-touch
Eventos de movimiento
Datos “preprocesados”
• Evento“agitar”: UIEvent type; @property(readonly) UIEventType @property(readonly) UIEventSubtype subtype; !
UIEventTypeMotion UIEventSubtypeMotionShake !
• Para “manejar” este evento: subclase de UIResponder que implemente
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {} !
-(void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event !
-(void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event {} !
Y además sea “first responder” - (BOOL)canBecomeFirstResponder { ! return YES; !}!- (void)viewDidAppear:(BOOL)animated { ! [self becomeFirstResponder]; !} !!
Eventos de movimiento Otros datos “preprocesados” de movimiento • La orientación de las pantallas:
en la clase UIApplication: statusBarOrientation (interface, no device orientation)
en la clase UIViewController: propiedad interfaceOrientation
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
• La orientación “real” del dispositivo: clase UIDevice **! - Arrancar notificaciones: beginGeneratingDeviceOrientationNotifications
Evento de cambio de orientación: UIDeviceOrientationDidChangeNotification (para “observadores registrados”) "[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; !"[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector"(orientationChanged:)name:UIDeviceOrientationDidChangeNotification object:nil]; !
ó acceder a propiedad orientation
- Parar notificaciones: endGeneratingDeviceOrientationNotifications
Eventos de movimiento
clase UIDevice tambien proporciona: (Instancia única + currentDevice)
• Opciones disponibles, versión, ID, OS … del dispositivo: !multitaskingSupported uniqueIdentifier name systemName systemVersion model
• Estado de la batería: batteryLevel batteryMonitoringEnabled batteryState
• Sensor de proximidad: proximityMonitoringEnabled proximityState !
“Control” de movimiento Para eventos de movimiento mas detallados:
Core Motion: acelerómetro y giróscopo (sólo iPhone4 y iPod Touch nuevo). esto es mas “completo” (integra), antes se usaba UIAccelerometer class,
CMMotionManager:- solo una instancia por aplicación pero es un recurso para “todos” - dos modos: samplear periódicamente la medición más reciente o suscribir un “manejador” para recibir todos los updates. (samplear más eficiente, mejor, salvo que “no se pueda perder ni una medida”)
1 – Comprobar disponibilidad del hardware @property (readonly) BOOL {accelerometer,gyro,deviceMotion}Available;
2 – Empezar la “captura” de datos. - (void)start{Accelerometer,Gyro,DeviceMotion}Updates;(SOLO si vamos a acceder a los datos)
@property (readonly) BOOL {accelerometer,gyro,deviceMotion}Active; (comprobar si esta “en marcha”)
3 – “desconectar” la captura (cuanto antes!! ahorro de bateria) - (void)stop{Accelerometer,Gyro,DeviceMotion}Updates;
Control de movimiento ���(Core Motion)
Acceder a los datos “en crudo”
@property (readonly) CMAccelerometerData *accelerometerData; Que contiene: @property (readonly) CMAcceleration acceleration;!typedef struct {double x;double y;double z;}CMAcceleration; !(incluye gravedad)
@property (readonly) CMGyroData *gyroData; Que contiene: @property (readonly) CMRotationRate rotationRate; !typedef struct { double x; double y; double z;} CMRotationRate; !(tiene un bias)
@property (readonly) CMDeviceMotion *deviceMotion; (combinación de medida del gyro y acelerómetros)
Control de movimiento ���(Core Motion)
Acceder a los datos “filtrados” instanciando CMDeviceMotion
Datos de aceleración @property (readonly) CMAcceleration gravity; !
@property(readonly) CMAccelerationuser Acceleration; !"//sin el “factor” gravedad gracias al giróscopo !
typedef struct { double x; double y; double z; } CMAcceleration; // x, y, z in “g”!
Datos de rotación @property CMRotationRate rotationRate; !
"//sin bias respecto a datos “crudos” gracias al acelerómetro !typedef struct {double x;double y;double z;} CMRotationRate; !
@property CMAttitude *attitude; //orientación en 3D del dispositivo !
Control de movimiento ���(Core Motion)
Control de movimiento ���(Core Motion)
Activar y samplear después (normalmente en bucle de aplicación)
- (void)startAccelerometerUpdates; !@property NSTimeInterval accelerometerUpdateInterval; !
- (void)startGyroUpdates;!@property NSTimeInterval gyroUpdateInterval; !
- (void)startDeviceMotionUpdates;!@property NSTimeInterval deviceMotionUpdateInterval; !
A partir de aquí, Core Motion actualiza la propiedad correspondiente del “UIMotionManager” con la medida más actual.
Control de movimiento ���(Core Motion)
Registrar “bloques” para recibir “updates” de las medidas (métodos del único CMMotionManager)
- (void)startAccelerometerUpdatesToQueue:(NSOperationQueue *)queue withHandler:(CMAccelerometerHandler)handler; !
- (void)startGyroUpdatesToQueue:(NSOperationQueue *)queue withHandler:(CMGyroHandler)handler; !
- (void)startDeviceMotionUpdatesToQueue:(NSOperationQueue *)queue withHandler:(CMDeviceMotionHandler)handler; !
Acceso a la cámara
• Clase UIImagePickerController (sin subclases, maneja interacciones con los UIViewController)
• Protocolo UIImagePickerControllerDelegate (implementado por el delegado)
• Configurar: ¿qué ocurre si se acepta la imagen o se cancela? ¿se puede editar antes de aceptar?
• Comprobar disponibilidad de cámara: seleccionar imagen del dispositivo disponible (cámara o archivo).
Recordar …
CUIDADO! con el gasto de batería: desconectar servicios en cuanto no se estén utilizando.
Organización de módulos
Core OS
- OS X Kernel Mach 3.0 BSD
- Sockets
- Security
- Power Mgmt
- Keychain Certif.
- File System
- Bonjour
Core Services
- Collections
- Address Book
- Networking
- File Access
- SQLite
- Core Location
- Net Services
- Threading prefs.
- URL utilities
Media
- Core Audio OpenAL
- Audio Mixing
- Audio Recording
- Video Playback
- JPG, PNG, TIFF
- Quartz (2D)
- Core Animation
- OpenGL ES
Cocoa Touch - Multi-Touch Events and Controls
- Core Motion
- View Hierarchy
- Localization
- Alerts
- Web View
- Map Kit
- Image Picker
- Camera
…
Y Mañana … • Unos cuantos puntos más interesantes …
Aplicaciones iPad y “universales”
Diseño de aplicaciones accesibles
Multi-task
Almacenamiento permanente
• Repaso general
• “Proyecto”
Multi-task
• This is a simple process:
• Open your info.plist file
• Add The Key UIApplicationExitsOnSuspend or Select Application does not run in background���
• Set the new key to YES or Fill in the tick box
Top Related