Lo sé porque cuándo uno empieza en esto del desarrollo iOS le gustan estas cositas.
En este post te enseñaré como puedes añadir a tus aplicaciones la funcionalidad de tomar fotos con iOS8 y Swift.
Aprenderás a usar la cámara del iPhone o iPad para tomar fotos, ver la foto en pantalla, y guardarla en el carrete.
Un Tutorial que nos va a permitir implementar en nuestras Apps la funcionalidad de tomar fotos con iOS8 y Swift.
Me lo dan «to hecho»: la clase UIMagePickerController
Pues sí, como en la mayoría de las clases de Cocoa que nos permiten hacer alguna virguería, implementar es más fácil que pensar en implementarlo.
La clase UIImagePickerController gestiona interfaces suministradas por el sistema para la toma de fotografías y películas en nuestros dispositivos.
Este controlador de imagen gestiona las interacciones del usuario y proporciona los resultados de esas interacciones a un objeto delegado.
Esto significa que tanto la selección de la foto para el guardado o su visualización en la aplicación, como el descarte de la toma, lo gestiona el controlador de imagen UIImagePickerController a través de su delegado.
Por nuestra parte sólo tenemos que «llamar» a este objeto para que a través del método delegado: picker: didFinishPickingMediaWithInfo info: se pueda gestionar la foto tomada.
Ajustar nuestro controlador de vista (ViewController) a los protocolos necesarios
En primer lugar, nuestro ViewController debe ajustarse a 2 protocolos: UINavigationControllerDelegate y UIImagePickerControllerDelegate.
El primero es obvio, para presentar la vista de la toma de foto, así como para volver a nuestro ViewController, necesitamos hacer uso de este controlador de navegación.
Por otra parte, el protocolo UIImagePickerControllerDelegate será el encargado de ofrecer a nuestro ViewController el método picker: didFinishPickingMediaWithInfo info: antes mencionado.
Guardar en carrete
Para guardar nuestra foto en carrete debemos declarar una variable de la clase UIImage, de forma que guardaremos de forma temporal la captura.
Para almacenar en el carrete debemos hacer uso del método UIImageWriteToSavedPhotosAlbum.
Vale, vale, que yo no quiero entender nada, quiero que mi App tome una foto y la guarde en carrete
En tu Storyboard añade una imagen y un botón y conéctalos con tu ViewController.
Declara una variable de la clase UIImagePickerController.
var miControladorImagen: UIImagePickerController!
A continuación implementa el método que has conectado con tu botón de la siguiente manera:
@IBAction func takePhoto(sender: UIButton) {
1. miControladorImagen = UIImagePickerController()
2. miControladorImagen.delegate = self
3. miControladorImagen.sourceType = .Camera
4. presentViewController(miControladorImagen, animated: true, completion: nil)
}
1. Inicializamos el objeto de la clase UIImagePickerController.
2. Hacemos a nuestro ViewController delegado de nuestro objeto.
3. Mediante la propiedad sourceType, simplemente decimos al controlador, la fuente a utilizar al momento de retirar la imagen o definir el tipo de medio disponible.
En nuestro ejemplo estamos usando Camera, pero podemos seleccionar otro valor de la enumeración UIImagePickerControllerSourceType.
4. Presentamos la vista que hemos seleccionado en nuestro objeto UIImagePickerController.
El método delegado
El método delegado es el encargado de gestionar cuándo el usuario cancela la foto tomada, así como de mostrar la misma en pantalla a través de la imagen que hemos añadido en nuestro storyboard y que hemos conectado, también implementaremos su guardado en el carrete.
Este es el método delegado:
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
var guardaImagen: UIImage?
miControladorImagen.dismissViewControllerAnimated(true, completion: nil)
imageView.image = info[UIImagePickerControllerOriginalImage] as? UIImage
guardaImagen = info[UIImagePickerControllerOriginalImage] as? UIImage
UIImageWriteToSavedPhotosAlbum(guardaImagen, nil, nil, nil);
}
Dónde miControladorImagen es un objeto de la clase UIImagePickerController, y imageView es la imagen que he puesto en mi storyboard y que he conectado con mi código creando una propiedad.
Si te fijas en la primera linea de código declaro una variable, que será la variable que luego guarde en mi carrete a través del método UIImageWriteToSavedPhotosAlbum implementado en la última linea de código.
Previamente a esta variable le había pasado el valor de la captura a través del parámetro del método delegado info.
Hacer una foto, o mostrar una del carrete
Aparece la vista de la cámara porque se lo decimos en la propiedad sourceType, si quisiéramos por ejemplo en vez de hacer una foto escoger una de la librería o carrete cambiaríamos esta linea de nuestro código:
miControladorImagen.sourceType = .Camera
Por esta otra:
miControladorImagen.sourceType = .PhotoLibrary
Y esta también nos valdría:
miControladorImagen.sourceType = .SavedPhotosAlbum
Quizá deberíamos eliminar toda la implementación del guardado, pues en este caso sólo queremos mostrar una imagen de nuestro carrete en pantalla.
No funciona en simulador
Por último y muy importante, este ejemplo no podrás probarlo en el simulador, ya que el simulador no puede hacer uso de la cámara, por lo que al intentar tomar una foto te dará un error y la App hará CRASH!
Lo ideal sería implementar un condicional para que evalúe si el dispositivo el cual está ejecutando tu App tiene cámara instalada, esto es tan sencillo como sobreescribir la implementación de nuestro método takePhoto con este condicional:
if (UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera)){
Aquí todo el código includo en nuestro método takePhoto.
} else {
println («No hay cámara»)
}
Observa que hacemos uso de la función isSourceTypeAvailable que nos devuelve un boleeano para indicarnos si el dispositivo tiene cámara o no.
Adjunto el proyecto por si quieres descargarlo y echar un vistazo, o copiar y pegar el código 😉
Y por supuesto, si tienes cualquier duda, déjame un comentario.
19 Comments