[MÚSICA] [MÚSICA] Hola, pues, vamos a ver cómo utilizar el acelerómetro dentro de nuestras aplicaciones, es decir, cómo tener acceso a las lecturas que nos proporciona el acelerómetro. Pero antes quisiera comentarles una pequeña discrepancia que tiene el acelerómetro con los gráficos. Normalmente, el acelerómetro va muy relacionado con los gráficos en algunas aplicaciones, por ejemplo, recordaran esta donde les mostré que el monito se mueve para un lado y para el otro, dependiendo de hacia dónde muevan el dispositivo. Esto lo hace por medio de las lecturas del acelerómetro y cómo hay muchas aplicaciones donde se relacionan el acelerómetro con los gráficos, quiero comentarles esta pequeña discrepancia. Resulta que en los gráficos computacionales, el eje y positivo va hacia abajo. Sí, tradicionalmente el eje y positivo de los gráficos va hacia abajo. En cambio, la aceleración positiva va hacia arriba. Sí en el eje vertical. Esto hay que considerarlo porque, bueno esto se resuelve con un signo de menos. Pero, esto hay que considerarlo, porque si tomamos una lectura positiva de la aceleración, significa que el objeto se estaría moviendo en esa dirección positiva y para graficarlo moviéndose hacia arriba, necesitamos en realidad moverlo en el sentido negativo de las y en los gráficos. Eso es muy importante, si no se estarían moviendo en direcciones opuestas. Hay que tomarlo en cuenta, claro esto depende de la librería de gráficos que estén utilizando. Si utilizan Quartz 2D van a tener este inconveniente. Se resuelve fácilmente. Pero si utilizan OpenGL, no se tienen que preocupar porque OpenGL tiene la misma convención que la aceleración. Tanto los gráficos en OpenGL como la aceleración positiva van hacia arriba, entonces, depende de la librería que estén usando, pero tómenlo en cuenta por favor. Bien, ahora sí, ¿cómo le hacemos para tener acceso a las lecturas que nos da el acelerómetro? Bueno, lo primero como se estarán imaginando es, definir una variable que la vamos a llamar el manejador del acelerómetro y normalmente se le llama motionManager, que es de la clase CMMotionManager. Sí. Este objeto, uno de estos objetos es suficiente para toda la aplicación. Con uno de estos objetos no tienen que definir más para hacer lecturas del acelerómetro. Desde luego que este objeto tiene ciertas propiedades, las podemos ver en la documentación, pero les quiero platicar sobre dos muy importantes. La primera de ellas se llama accelerometerAvailable y esta propiedad nos indica, es verdadera, cuando el acelerómetro está disponible. Siempre antes de iniciar el uso del acelerómetro, verifiquen que esté disponible. Si es que está disponible, entonces podemos empezar a usarlo y la primera de las cosas que tenemos que hacer es configurarlo. Dentro de la configuración, una parte fundamental es el intervalo de actualización. Definir el intervalo de actualización, ¿sí? ¿Cada qué tiempo se van a hacer lecturas en el acelerómetro? Esto se hace con la variable de instancia, accelometerUpdateInterval y esta nos dice a fin de cuentas, cuántas veces se actualiza la lectura del acelerómetro por segundo. Si vale un décimo, lo hará 10 veces por segundo. Si vale un sesentavo, lo hará 60 veces por segundo, etcétera. ¿Sí? Bueno, sobre esto tengo un comentario que les haré en el ejemplo, porque no necesariamente se respeta este valor, pero bueno, hay que tomarlo. Después lo comentamos. Desde luego que también existen dos métodos. Uno que inicia las lecturas que es el startAccelometerUpdatesToQueue:withHand- ler, tiene dos parámetros. Una cola donde guarda las lecturas y el handler que lo trataremos enseguida, porque es la parte más importante de este método. Y otro método que sirve para detener las lecturas que es stopAccelerometerUpdates. Regresando al método que inicia las lecturas, les decía que tiene dos parámetros. El segundo es un manejador, el withHandler, ¿no? Este es un bloque, este manejador es un bloque y sobre los bloques quisiera recordarles un poquito lo que son. Un bloque es una especie de Función anónima. En algunos lenguajes de programación tienen nombres diferentes pero a fin de cuentas es una función anónima. Estas funciones anónimas se crearon como una alternativa a los delegados. Todavía no hemos visto delegados, pero los veremos en algunos temas más adelante. Pero esto, antes esta lectura se hacían por medio de un delegado. Ahora se hace por medio de un bloque y la parte fundamental de un bloque, lo que debemos estar recordando es que, corre en un hilo diferente al hilo principal de su programa, ¿sí? Corren en hilos diferentes. ¿Y esto por qué se hace así? Para tratar de aumentar el poder de cómputo y que esto no tarde mucho y las gráficas se puedan hacer en el tiempo adecuado, con las lecturas adecuadas. Por eso se hace una lectura en un hilo diferente. ¿Cómo se declara un bloque? Un bloque se declara con llaves. Se pone una llave que abre y una llave que cierra y en medio se coloca todo el bloque. La primera parte del bloque es una lista de parámetros, que son los parámetros que va a recibir porque es una especie de función. Es una especie de función como las conocemos normalmente. Esta lista de parámetros es separada por comas y después de la lista de parámetros, lleva la palabra reservada in y en seguida entre la palabra resevada in y la llave que cierra, van todas las instrucciones que queremos que ejecute el bloque. Recuerden ese bloque se ejecuta en un hilo diferente al hilo principal. ¿De acuerdo? Recapitulando un poquito, el método que inicia las lecturas tiene entonces dos parámetros, una cola donde va guardando las lecturas y un bloque que es el que maneja las lecturas que se reciben del acelerómetro. El bloque a su vez, como es una función, tiene dos parámetros, recibe dos parámetros. El primer parámetro es un parámetro de tipo CMAccelerometerData, ¿de acuerdo? Es el primer parámetro. Este parámetro es el más importante porque es el que tiene las lecturas. Esta es una estructura. Ahorita lo comentamos, pero debe tener la lectura en x, la lectura en y, la lectura en z. El segundo parámetro es un error. Y ese error va a tener un valor, si es que se produce, el error. Bien, para que quede más claro, cómo nos quedan las lecturas de x, y, y z, le diré que el primer parámetro que recibe el bloque, que es el parámetro de tipo CMAccelometerData, ¿de acuerdo? Es una estructura y tiene 3 valores. Un valor para la aceleración en x, un valor para la aceleración en y, y un valor para la aceleración en z. Si alguna de ellas recibe un valor de 0, significa que no está detectando aceleración en ese eje. Pero si tiene un valor positivo o un valor negativo, significa que sí está detectando aceleración y el signo nos indica en qué sentido de acuerdo a los ejes que you les platiqué, que se pueden colocar sobre su dispositivo. Por ejemplo, si su dispositivo estuviera totalmente de frente, si su dispositivo está totalmente de frente, viendo hacia ustedes, el eje de las x estaría horizontal y la, el eje de x positivo estaría apuntando hacia la derecha. Si, lo están viendo de frente estaría vertical y el eje y positivo estaría apuntando hacia arriba. Y el eje z positivo estaría apuntando hacia ustedes, hacia fuera de la pantalla y el eje z negativo hacia dentro de la pantalla, ¿de acuerdo? Bien, por lo tanto, si tenemos el dispositivo en esta posición y lo dejamos así quietecito, la única aceleración que está recibiendo es la aceleración gravitacional, que está apuntando hacia abajo. Eso significa que la lectura en x va a ser 0. La lectura en y va a ser menos 1 porque está apuntando hacia abajo y la lectura en z va a ser 0. ¿Sí? Bien, si ustedes voltean por completo su dispositivo y lo ponen volteado hacia abajo, es como si voltearan todos los ejes. La aceleración sigue siendo la misma, está apuntando hacia abajo. Pero ahora va a tener, x va a seguir siendo 0, z va a seguir siendo 0, pero y va a ser 1 ahora, porque el eje positivo de las z, como le dimos la vuelta, de las y, perdón, como le dimos la vuelta, está apuntando hacia abajo y la lectura va a ser 1 en ese sentido. Si ponemos el dispositivo acostado, boca abajo, la pantalla viendo hacia el suelo, entonces va a tener 0 en x, 0 en y, y en z positivo, porque es el que está saliendo de la pantalla, va a ser 1. Esos son los valores y así pueden hacer muchas combinaciones. Bueno con respecto a esto, les tengo una pregunta. Desde luego que la respuesta es, lo que vamos a leer son las componentes de la aceleración de 1 G sobre cada uno de los ejes. Si el dispositivo está un poco inclinado, pues entonces la aceleración sigue estando hacia abajo y lo que tendremos que calcular son las componentes de cada, en cada uno de los ejes de esa aceleración de 1 G. ¿Sí? Eso es lo que vamos a tener como lecturas. Con respecto a los hilos, por favor, el que corra en hilos separados el bloque del hilo principal, es una ventaja porque lo hace más rápido, pero también hay que tomar en cuenta algunas cosas por ejemplo, no sabemos el hilo en el que está corriendo. Eso se maneja automáticamente por el Grand Central Dispatch, eso lo maneja automáticamente y bueno la situación es que casi siempre se quiere modificar algunos de los elementos de la vista. Los elementos de la vista que son elementos del framework UIKit, normalmente corren en el hilo principal. Si el bloque está corriendo en un hilo alterno al principal, entonces no podríamos modificar elementos que están en el hilo principal directamente desde el hilo alterno. Por eso tendríamos que usar un método especial que se llama dispatch async que nos permite hacer esta conexión, modificar algo desde otro hilo, en el hilo principal. Pero esto desde luego, lo veremos en un ejemplo más adelante. Un ejemplo de cómo hacer lecturas en el acelerómetro. Muchas gracias. [MÚSICA]