Si hay un objeto que me encanta desde que lo conocí hace ya algunos años es la vista Web, o lo que es lo mismo la clase UIWebView.
En esta entrada voy a enseñarte como puedes implementar un UIWebView con Swift.
La clase UIWebView
La clase UIWebView nos provee de un objeto de vista Web.
Es decir que si implementamos este objeto, vamos a poder cargar el contenido de una página Web dentro de nuestra propia aplicación.
¿Suena bien no?
La verdad es que da unas posibilidades enormes, pues podemos crear una App en un servidor con cualquier lenguaje, y hacer cosas muy chulas
Lo mejor de todo es que es una clase muy sencilla de usar, y como digo se trata de un objeto muy potente y fascinante de cara al usuario.
Vamos a ver cómo podemos implementar un UIWebView con Swift.
Crear un nuevo proyecto
Cómo siempre vamos a abrir xCode y vamos a crear un nuevo proyecto.
Y vamos a seleccionar la plantilla «Single View Application».
En esta pantalla podemos configurar algunos ajustes de nuestro proyecto, algunos son muy importantes como el «Bundle Identifier» pero no vamos a ver esto en esta entrada.
Pon un nombre a tu proyecto, elige Swift como lenguaje de programación, y haz clic sobre el botón «Next» .
Después selecciona el lugar dentro de tu Mac dónde quieres guardar tu proyecto.
Crear la Interfaz de nuestro UIWebView
Hacemos click sobre el icono del Storyboard dentro de nuestro grupo de carpetas y archivos.
Para crear la interfaz vamos a hacer algo muy sencillo, pero primero vamos a adaptar nuestra pantalla a la vista de un iPhone.
Como sabéis desde la llegada de xCode 6 podemos adaptar la vista o vistas dependiendo del dispositivo al que va destinado, además de auto ajustar su tamaño. Hacemos clic sobre «wAny hAny» justo debajo de nuestro ViewController, y seleccionamos el tamaño de pantalla adecuado, en este caso iPhone.
A continuación vamos a seleccionar el objeto que va a ser el contender de nuestro contenido Web, hacemos clic en el buscador de la parte inferior, y seleccionamos el objeto UIWebView.
Debemos centrar el objeto en nuestra vista, fijaos como cuándo movemos el objeto por nuestro vista en el Storyboard, aparecen unas lineas azules indicándonos la posición del UIWebView respecto a nuestra vista.
Conectar los puntos 😉
Continuando con la misma metodología de tutoriales anteriores, vamos a conectar los puntos, esto es conectar los objetos que hemos puesto en nuestro Storyboard con el código que va a dar a nuestra aplicación cierta lógica.
Primero vamos a conectar el objeto con el delegado, esto debe hacerse para poder usar algunos métodos dentro de nuestro proyecto, es un poco más complejo de explicar, pero entraría en patrones de diseño, y no es el objetivo de esta entrada, así pues confiar en mi 😉
Hacer clic sobre el objeto UIWebView y pulsa la tecla «ctrl» volved a hacer clic sobre el objeto y no soltéis ese clic, entonces arrastrar la flecha azul hacía el botoncito circular amarillo en la parte superior de nuestra vista, os aparecerá una ventana dónde debéis hacer clic sobre «delegate», y ya está.
Para conectar los puntos y crear las siguiente conexión, vamos a dividir la pantalla de trabajo en dos, en la esquina superior derecha tenéis un botón que va a hacer precisamente esto, es el botón que parece un hombre con traje y pajarita.
Ahora hacemos click sobre el objeto UIWebView y después pulsamos la tecla «ctrl», volvemos a hacer clic ¡¡y no soltamos el clic!! entonces aparecerá una linea de color azul, la arrastramos hacía la clase de código que está en la parte derecha de nuestra vista, y ahora sí, soltamos el clic.
Al crear la conexión nos aparecerá una ventana modal. Aquí sólo tenemos que poner nombre a nuestro objeto UIWebView en el apartado Name, y hacer clic en «Connect»
Lo que acabamos de hacer es declarar una variable de instancia a la clase UIWebView, es decir, hemos puesto nombre al objeto de la clase UIWebView.
Al crear la conexión, en nuestro archivo controlador de vista ViewController.swift, se ha creado una linea de código, es la mencionada declaración de la variable de instancia.
Se crea una variable Optional, pero permitirme que no entre en esta entrada a explicar esto.
Para trabajar de una forma más cómoda, vuelve a poner la vista de xCode a su modo por defecto, para ello pulsa en el botón de la esquina superior derecha, el que tiene tres lineas horizontales.
Implementar la lógica
Una vez hemos creado nuestra interfaz, y hemos conectado a nuestro archivo controlador de vista ViewController.swift, es hora de implementar la lógica de nuestra App.
El objeto de la clase UIWebView, no hace nada de momento, si compiláramos la aplicación en este momento, no haría absolutamente nada, por eso debemos escribir algunas lineas de código para que nuestro objeto muestre algo.
Como en esta aplicación vamos a usar el patrón del delegado, tenemos que ajustar nuestra Clase ViewController.swift al protocolo UIWebViewDelegate, para ello dentro del archivo ViewController.swift, nos situamos en la linea de código:
class ViewController: UIViewController
Y añadimos lo siguiente:
class ViewController: UIViewController, UIWebViewDelegate {
La función viewDidLoad()
Para implementar la lógica en nuestras aplicaciones, esto es, dar instrucciones a cada uno de nuestros objetos para que hagan algo, escribimos secuencias de código dentro de funciones.
Nosotros podemos crear nuestras propias funciones, pero también podemos usar las que ya existen.
La clase ViewController, es decir, los controladores de vista, incorporan una función que es la función viewDidLoad().
Es una función muy útil, pues todo el código que implementemos dentro de esta función, se va a ejecutar una vez ha terminado de cargarse la vista.
Es decir, la App carga la vista, y ViewController ejecuta todo lo que contenga la función viewDidLoad() ¡Genial! ¿No?
Es en este método dónde vamos a programar el algoritmo que hará que en nuestro objeto de vista Web, se muestre una Web.
Vamos a seleccionar el archivo ViewController.swift y vamos a comenzar a sobreescribir la función viewDidLoad() con lo siguiente:
override func viewDidLoad() { super.viewDidLoad() //Crea una constante llamada url que almacena el valor de una URL let url = NSURL.URLWithString("https://cfeapps.com") //Crea una variable llamda request que hace una carga de la url contenida en url let request = NSURLRequest (URL:url) //Cargamos la web en nuestro objeto web WebView.loadRequest(request) }
Vuestro archivo ViewController.swift debería quedar como este:
Compilar el proyecto
Pues esto es todo, si compiláis el proyecto en vuestro simulador se debe haber cargado la Web que hayáis puesto en la constante url.
Hagamos un repaso:
- Crear la vista en el Storyboard
- Conectar el objeto UIWebView como delegado del ViewController, y después conectar el objeto con el código, declarando una variable
- Añadir el procotolo UIWebViewDelegate a nuestra clase ViewController.swift
- Sobreescribir la función viewDidLoad() añadiendo la lógica de nuestra App
- Compilar 😉
Conviértete en un experto en la creación de Apps
¿Quieres aprender lo que es el patrón delegado, un protocolo, y convertirte en un experto creando Apps?
Muy buen post! he aprendido muchísimo, muchas gracias!!
Hola Miguel Ángel,
Muchas Gracias, para mi es toda una satisfacción que mis post sirvan de ayuda, y también me ha gustado mucho que expreses tu opinión con un comentario.
Por aquí eres bienvenido, seguimos enseñando y aprendiendo a partes iguales 😉
Un abrazo.
Sergio Becerril
Disculpa, estoy desarrollando una app en lenguaje Swift, pero no sé como manejar la transición de las escenas en el storyboard con código o siquiera sé si esto es posible. Otro ejemplo sería enviar datos de una escena a otra. Sería de mucha ayuda que me guiaras para resolver mis dudas. Gracias
Hola Enrique,
Puedes visitar la última entrada de mi Blog, quizá resuelva algunas de tus dudas.
Gracias por visitar mi Blog 😉
Un abrazo.
Sergio Becerril
Muchísimas gracias, la verdad había buscado esta información por muchos lugares.
Disculpa, estoy desarrollando una app para IOS la cual requiere un menú lateral (como el de facebook); el problema es que no encuentro un tutorial claro, ya que todos los que hay hacen uso de diferentes técnicas y a la hora de tratar de adaptar el ejemplo a mi proyecto resulta que no son digamoslo “compatibles” a la hora de codificar, ya que en los tutoriales lo hacen de una manera y yo de otra. He encontrado una forma de hacerlo, es mediante los UISplitViewControllers, mas me pasa lo mismo que en los casos anteriores. Te agradecería mucho que me pudieces ayudar, ya que llevo mucho tiempo tratando de encontrar un ejemplo o tutorial claro. Gracias
Hola Fermín,
El UISplitViewController no es el controlador que tú quieres.
Te dejo que descargues un ejemplito que hice hace tiempo, que muestra como implementar el controlador de vista que quieres.
En mi caso usé una libreria de un tercero, que es completamente modulable y exportable a cualquier proyecto, para eso está la programación orientada a objetos 😉
Por otra parte, entiende que no pueda darte ningún tipo de ayuda o darte soporte para implementar esta funcionalidad, por esta vía.
DESCARGAR EJEMPLO
Si necesitas ayuda para implementar esta solución, escríbeme a: cfeapps@gmail.com dónde podemos hablar de que es lo que necesitas.
Gracias por visitar mi Blog.
Un abrazo.
Sergio Becerril
Muchísimas gracias por tu tutorial estimado :D. Sin embargo tengo una duda con respecto a un error que me da al dar la sintaxis URLWithString.
Me dice que «URLWithString ‘is unavailable: use object construction ‘ …. me podrias orientas un poco?
Hola Iván,
Encantado de saludarte.
En realidad desde que Apple publicó la versión de Swift 1.1 ha cambiado un poco la forma en cómo se implementa una Web, ahora se hace de la siguiente manera:
//Crear una constante que almacenará la URL
let url = «http://www.apple.com/es»
//Crear una constante llamada urlRequest
let urlRequest = NSURL (string: url)
//Crear una constante llamada request
let request = NSURLRequest(URL: urlRequest!)
//Cargamos la web en nuestro objeto de la clase UIWebView
miWeb.loadRequest(request)
Espero te sirva.
Gracias por visitar el Blog y por supuesto por comentar.
Un abrazo.
Sergio Becerril
Muchísimas gracias, al investigar más efectivamente encontré lo que me comentaste y logre hacerlo funcionar ;). Lo que si tengo ahora otra duda, como tu sabes iphone 6 y 6 plus son resoluciones distintas. Existe alguna manera en que se pueda adaptar la pantalla automáticamente para que sea compatible tanto como para iphone 4,4s,5,5c,5s,6 y 6plus?
Agradeciendo desde ya tu tiempo y ayuda, saludos
Iván
Hola Iván,
A ver si te sirve el contenido de este Post:
https://cfeapps.com/vistas-en-ios
Si no fuera así, te ánimo a que te inscribas en alguno de mis Cursos de pago, dónde se ve como usar Auto Layout, así como la nueva tecnología que ha llegado con iOS 8, las clases de tamaño o Size Classes 😉
Un abrazo.
Sergio Becerril
Muchísimas gracias, al investigar más efectivamente encontré lo que me comentaste y logre hacerlo funcionar ;). Lo que si tengo ahora otra duda, como tu sabes iphone 6 y 6 plus son resoluciones distintas. Existe alguna manera en que se pueda adaptar la pantalla automáticamente para que sea compatible tanto como para iphone 4,4s,5,5c,5s,6 y 6plus?
Agradeciendo desde ya tu tiempo y ayuda, saludos
Iván
Hola Iván,
A ver si te sirve el contenido de este Post:
https://cfeapps.com/vistas-en-ios
Si no fuera así, te ánimo a que te inscribas en alguno de mis Cursos de pago, dónde se ve como usar Auto Layout, así como la nueva tecnología que ha llegado con iOS 8, las clases de tamaño o Size Classes 😉
Un abrazo.
Sergio Becerril
Hola buen día!!
Muy buen post!! Solo que tengo una duda, apenas estoy aprendiendo a programar, al realizar el paso: «Ahora hacemos click sobre el objeto UIWebView y después pulsamos la tecla “ctrl”, volvemos a hacer clic ¡¡y no soltamos el clic!! entonces aparecerá una linea de color azul, la arrastramos hacía la clase de código que está en la parte derecha de nuestra vista, y ahora sí, soltamos el clic.»
no me muestra la linea azul y no me deja declararlo. Que puedo hacer?
De antemano gracias.
Hola Fanny,
Requiere practica, las primeras veces cuesta conectar, pero una vez lo consigues es muy sencillo.
Tienes que hacer clic en el objeto que quieres conectar, y luego con la tecla CTRL pulsada volver a hacer clic y «arrastrar».
El proceso es muy sencillo, pero como digo las primeras veces cuesta un poco, sobre todo porque la primera vez que se hace clic con el objeto, no se suelta este clic, y entonces no funciona.
Los pasos serían los siguientes:
1.Seleccionar el objeto, es decir hacer clic sobre el mismo ( y soltar el ratón)
2.Con la tecla CTRL pulsada hacer clic sobre el objeto y arrastrar hacía afuera, la linea azul debe aparecer.
¡Suerte! 😉
Gracias por comentar y pasarte por el Blog.
Un abrazo.
Sergio Becerril
Hola Sergio,
Buen articulo y muy detallado.
He conseguido visualizar un sitio web, pero al hacer la compilación y el preview no funciona el responsive de la web, es correcto eso? solo se visualiza así en el preview? o hay que especificar algún paso más?
Saludos y muchas gracias
Hola Hector,
No entiendo que quieres decirme.
La Web que se visualiza en el dispositivo o en el simulador, será responsive si está creada en el servidor como tal, es decir que sea responsive no tiene nada que ver con el desarrollo iOS.
Dime cual es la URL que estás intentado visualizar y pruebo yo y te digo 😉
Muchas gracias por visitar mi Blog y por supuesto por comentar.
Un abrazo.
Sergio Becerril
Perdona quizás no me he explicado bien 🙂
En la previsualización de la app la web me sale como cortada, pero creo que ya he encontrado el error, pruebo una cosa y te cuento
Muchas gracias!
Buenas, estoy empezando en esto de las app de IOS y me encuentro que siguiendo este tutorial miWeb.loadRequest(request) no funciona en 8.4.
¿Cómo se solucionaria?
Hola Joshus,
Encantado de saludarte.
En realidad desde que Apple publicó la versión de Swift 1.1 ha cambiado un poco la forma en cómo se implementa una Web, ahora se hace de la siguiente manera:
//Crear una constante que almacenará la URL
let url = “http://www.apple.com/es”
//Crear una constante llamada urlRequest
let urlRequest = NSURL (string: url)
//Crear una constante llamada request
let request = NSURLRequest(URL: urlRequest!)
//Cargamos la web en nuestro objeto de la clase UIWebView
miWeb.loadRequest(request)
Espero te sirva.
Gracias por visitar el Blog y por supuesto por comentar.
Un abrazo.
Sergio Becerril
¿como podría hacer que mi UIWebView guarde las cookies, al iniciar mi sesion ?
Hola Jesús,
Lo siento pero no resuelvo este tipo de cuestiones por el Blog.
Un abrazo.
Sergio Becerril
Saludos
Tengo una consulta se puede subir archivos desde una WebView, tengo una pagina web que desde un navegador como Mozilla Firefox puedo subir archivos pero desde la WebView no puedo, la aplicación se cierra en el iPhone
Hola José,
iPhone no tiene un explorador de archivos, entonces cuando intentas acceder a «algo» la aplicación se cierra, otra opción es que estés recibiendo un «nil» en algún sitio, y Swift no se lleva muy bien con los valores varios, de hecho tiene mecanismos creados específicamente para no errar con datos nulos, como son los Optionals, la cláusula Guard, etc.
Gracias por visitar el blog y por comentar.
Un abrazo.
Sergio Becerril
Muy buenos dias,tengo un problema ,cuando pongo una pagina como por ejemplo facebook,si me funciona perfectamente el codigo,pero cuando pongo una pagina que yo hice ,se queda en blanco la pantalla y no carga la pagina,todo esta bien ,solo no carga,no se si tenga que ver que como uno es una pagina certificada o segura,no permita abrirla,o que puede ser,no se si tenga que ver que no sea .com,es una pagina que es mas o menos asi https://www.mipágina.pe.hu
ya intente de todo y no carga ,no marca error ni nada.
saludos
hola que tal buen día seguí la guía al pie de la letra pero me dan errores con el URLwithString estoy en swift4
Hola Luis,
Sí cambió, aquí tienes la solución:
/Crear una constante que almacenará la URL
let url = “http://www.apple.com/es”
//Crear una constante llamada urlRequest
let urlRequest = NSURL (string: url)
//Crear una constante llamada request
let request = NSURLRequest(URL: urlRequest!)
//Cargamos la web en nuestro objeto de la clase UIWebView
miWeb.loadRequest(request)
Un abrazo!
Sergio Becerril