Novedades en iOS 7

| Última modificación: 11 de noviembre de 2022 | Tiempo de Lectura: 12 minutos

Algunos de nuestros reconocimientos:

Premios KeepCoding

iOS 7 fue presentado el pasado 10 de junio de 2013 en la WWDC, desde ese momento ya estuvo disponible para los desarrolladores, tanto el SDK para poder empezar a trastear como una versión beta para instalar en los dispositivos de aquellos que tuvieran una cuenta de desarrolladores. Finalmente pusieron disponible iOS 7 al público en general el día 18 de septiembre.

Había mucha expectación ante los rumores sobre el profundo cambio que se avecinaba, no dejó a nadie indiferente (algunos iconos se las traen) y se armó un buen revuelo en la comunidad sobre como afectaría estos a las apps existentes y sobre las posibilidad que se abría, sobre todo a desarrolladores independientes. A continuación exponemos a grandes rasgos las nuevas características y mejoras.

Soporte a 64 bits

Las librerías y frameworks son compatibles con la arquitectura de 64 bits. Cuando las apps son compiladas de este modo pueden ser ejecutadas más rápidamente porque tienen disponibles las capacidades del procesador.

Veremos como afecta esto al desarrollo. Por el momento lo que hemos podido probar, si utilizamos int el compilador nos informa con un warning de que podemos estar perdiendo precisión, deberíamos usar NSInteger / NSUInteger. ¿Por qué? Un int es un entero de 32 bits mientras que NSInteger / NSUInteger están definidos como (unsigned) long que es un entero de 64 bits.

Mejoras en multitarea

Han ampliado el motivo por el cual las apps pueden acceder a segundo plano, aunque no el tiempo que tendrán para realizar las operaciones. Además no se garantiza que ese periodo sea continuo.

La idea es que cada vez que se levante la app en segundo plano haga lo que tenga que hacer y luego notifique que ha terminado al SO para que haga una captura de pantalla y la muestre en la nueva interfaz para multitasking, dando al usuario una sensación de que la app está actualizada y buscando contenido en segundo plano.

Nueva interfaz de las apps que están en segundo plano

Si no notificamos que hemos terminado “bad things can happen” según dicen en la sesión de “What’s new in multitasking” de la última WWDC.

Las principales novedades son la captura de datos en segundo (lo que llaman fetch) y las silent push notification:

  • Fetch: apps que periodicamente actualizan su contenido a través de un servidor de modo que cuando el usuario navegue por la nueva interfaz de multitasking de la sensación de tener un contenido actualizado sin necesidad de volver a la app (aquí entra en juego la captura de pantalla)
  • Silent push notifiación: nos permite enviar notificaciones push de forma que no avisen al usuario pero levanten nuestra app en segundo plano para hacer lo requerido.
Para configurar ambos modos hay que seguir unos pasos muy parecidos:
  1. Especificarlo en el fichero NombreNuestroProyecto-Info.plist el modo que vamos a utilizar. La clave será “Required background modes” (o escribir UIBackgroundModes y Xcode lo traducirá) y como valores en función de las opciones descritas anteriormente “App downloads content from network” (o bien fetch) o “App downloads content in response to push notifications” (o bien remote-notifications)
  2. Especificarle cada cuanto tiempo vamos a requerir ejecutar código en background con el método del appDelegate:
    [app setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];

    El tiempo será aproximado, Apple no nos garantiza nada, puede ser que cuando le toque entrar no tenga conectividad y por tanto saltará el slot que tenía hasta el siguiente.

  3. Tendremos que implementar un callbacks del appDelegate que será llamado cuando tengamos acceso a ejecutar código en background. Para las fetch el método será:
    application:performFetchWithCompletionHandler:

    Para las silent push notification:

    application:didReceiveRemoteNotification:fetchCompletionHandler:

    MUY importante que nos acordemos de llamar al bloque que nos pasan en el completionHandler para notificar que hemos terminado (correctamente o con fallo).

    Para que funcione la silent push notification además hay que enviarla con información extra en el payload:

    aps {
    
                content-available: 1
    
                alert: {…}
    
    }

Airdrop

Airdrop permite compartir fotos, documentos, URL y otro tipo de información a través de dispositivos cercanos. Para ello debemos indicar en Xcode que tipo de ficheros vamos a recibir vía Airdrop. Lo hacemos en la pestaña Info con el target seleccionado y Xcode nos generará las entradas correspondientes en el Info.plist con la clave “Document types”:

Configuración archivos a recibir via AirDrop

Tenemos que implementar un método del app delegate que será llamado cuando se recibe el fichero:

application:openURL:sourceApplication:annotation:

Se almacena en un directorio (Documents/Inbox) que solo permite lectura y borrado, tendrías que moverla si quieres modificarla.

Nuevos frameworks

SpriteKit

Se ha introducido un nuevo framework para crear juegos en 2D y 2.5D, SpriteKit. Proporciona renderizado, animaciones, sonidos de fondo y un motor de física.

Los juegos se organizan en escenas y se integra perfectamente con Xcode para generar escenas básicas, creación de partículas y de texturas

Game Controller

Un framework para permitir a terceros fabricantes construir mandos que se integren con el dispositivo, ya sea físicamente o por bluetooth.

Inter-app Audio

Permite enviar comandos MIDI y stream de audio entre apps del mismo dispositivo.

Peer-to-Peer Connectivity

Framework que permite descubrir dispositivos cercanos y comunicarse con ellos en tiempo real sin necesidad de estar conectado a la red.

Otros

  • JavaScript Core
  • Media Accesibility
  • Safari Services

Mejoras en frameworks existentes

UIKit

Rediseño

La interfaz ha sido completamente rediseñada. La definen como: “Transparencia, toques visuales refinados y movimientos fluidos y realistas que transmiten profundidad y vitalidad a la experiencia del usuario”. Pajas mentales de Jon Ive a parte, vamos a notar un cambio significativo en la apariencia de los componentes al utilizar UIKit compilado contra iOS7. Podéis ver el nuevo aspecto que tienen aquí.

Dynamics

Podemos añadir un comportamiento más “real” a las UIView dándoles características de la física como la gravedad. Soporta los siguientes comportamientos dinámicos:

  • Enganchar dos objetos dinámicos o un objeto dinámico y un punto, de modo que si un objeto o punto se mueve, el otro objeto varía su oscilación y amortiguación en función del tiempo.
  • Responder a colisiones.
  • Gravedad.
  • Aplicar fuerzas.

Hay que tener cuidado con esto, ya que podemos sobrecargar la app con animaciones (como pasa con muchas webs con animaciones tipo jQuery) y dejar seca la batería (estamos haciendo cálculos pesados para la física) dejando como resultado una review con una estrella y un usuario activo menos.

TextKit

Nos permite trabajar con texto de una forma cómoda con el nivel de abstracción que proporciona UIKit, sin necesitar bajar al sótano a utilizar CoreText. Nos permite hacer cosas como dividir el texto en columnas, poner una imagen sobre el texto y que el texto se adapte, introducir párrafos o la capacidad de cambiar dinámicamente el tamaño de fuente en función de las preferencias del sistema.

Esto último dará al usuario una sensación de que la app ha sido desarrollada conforme a sus preferencias (no todos tienen el mismo grado de visión) y no a las preferencias del diseñador. Si utilizamos esta feature no fijaremos el tamaño de la letra si no que escogeremos un estilo (al más puro estilo de marcado HTML) y un tamaño (desde XS a XXXL). Con esta nueva característica será más necesario que nunca utilizar AutoLayout para que no se descuadre nada con los cambios de tamaño.

A parte NSAttributedString tiene más opciones como pueda ser letterpress.

UIView

La propiedad tintColor se aplica ahora tanto a las vistas como a las subvistas. Esto dota a la vista de personalidad. Veamos el ejemplo en Calendar.app:

Aspecto de Calendar.app en iOS 7

El tintColor de esta app es [UIColor redColor]. Las nuevas guidelines de Apple dicen que si una vista queda oculta parcialmente y pierde el foco, el color de la app tiene que cambiar por uno menos vivo para que el usuario no pierda el foco donde realmente está el contenido, que es lo mas importante. Por ejemplo a causa de un UIAlertView o UIActionSheet. Vamos a mostrarlo con un ejemplo de Contacts.app, cuyo tintColor es azul:

Lo que importa es el foco

Para ello tendremos que jugar con los valores de la propiedad:

@property(nonatomic) UIViewTintAdjustmentMode tintAdjustmentMode

Lo razonable sería asignar el valor UIViewTintAdjustmentModeDimmed a la vista que se esta mostrando mientras que al resto de la app (asignárselo a la window) darle el valor UIViewTintAdjustmentModeNormal. Con esto conseguimos que se oscurezca el texto, perdiendo así el foco.

Para modificar este comportamiento sobreescribiremos el método:

- (void)tintColorDidChange

Que será llamado por el SO cuando estamos en el modo UIViewTintAdjuntmentModeDimmed.

UIKit también nos permite ahora crear animaciones basadas en keyframe. Es una forma de hacer animaciones con múltiples pasos. Antes de iOS 7 había que encadenar las animaciones poniéndolas en el bloque de finalización para empezar la otra o bien utilizando CoreAnimation.

Con las keyframe animations podemos definir una simple animación con múltiples pasos:

[UIView animateKeyframesWithDuration:delay:options: animations: completion];

Dentro de animations hay que poner tantas animaciones como queramos y se ejecutaran de forma secuencial:

[UIView addKeyframeWithRelativeStartTime:relativeDuration:animations0];

De igual modo que el SO hace capturas de pantalla para el background como hemos comentado al principio, esta API esta disponible para utilizarla a nuestra conveniencia, por ejemplo para hacer transiciones:

– snapshotViewAfterScreenUpdates:
– resizableSnapshotViewFromRect:afterScreenUpdates:withCapInsets:
– drawViewHierarchyInRect:afterScreenUpdates:

UIViewController

Las siguientes transiciones se pueden personalizar:

  • Presentar modalmente y hacer dismiss.
  • Cambiar entre pestañas en un UITabBarController.
  • Push/pop en un UINavigationController.
  • UICollectionViewController layout-to-layout

Las clases y protocolos involucradas para poder hacer esto son:

Novedades en iOS 7

UIViewControllerTransitioningDelegate – Protocolo que nos preguntará por el objeto que implementará UIViewControllerAnimatedTransitioning, si no le proporcionamos nada (nil) realizará las transiciones por defecto.

UIViewControllerAnimatedTransitioning – Tiene dos métodos el protocol, uno para indicarle la duración de la transición (transitionDuration: ) y el método donde realizamos la animación (animateTransition: )

UIViewControllerContextTransitioning – De donde obtenemos la información relativa a que controlador vamos, de cual venimos, etc… Nos viene dado por el framework, no tenemos que implementar nada aquí, solo consumirlo.

Se pueden hacer de forma interactiva, es decir, que nosotros las vayamos dirigiendo con el movimiento de nuestro dedo. Un buen ejemplo serían las apps de Apple en iOS7 donde podemos hacer pop del viewController actual haciendo un pan desde el margen izquierdo de la pantalla e ir viendo la animación conforme avanza el gesto (es una nueva subclase de UIGestureRecognizer). Para ello tenemos que heredar del objeto UIPercentDrivenInteractiveTransition.

También cambia la forma en que tratamos la status bar y la navigationBar ya que ahora la vista es full screen y su frame no se sitúa por debajo de ninguna de estas dos vistas comentadas, si no pegado al margen superior de la pantalla. Esto implica que tanto la status bar como la navigationBar tengan una transaparencia para que se intuya el contenido.

Si queremos que se comporte como anteriormente tendremos que hacerlo manualmente.

UIAlertView

Ya no tendremos que hacer nuestro propio UIAlertView ni buscar en cocoacontrols ya que ahora podemos poner nuestra propia UIView personalizada dentro del UIAlertView 

Parece ser que finalmente no lo han introducido en la API como así anunciaron en la WWDC, una lástima.

UIImage

Puede recibir imágenes almacenadas en los asset catalogs que es la nueva forma en Xcode 5 para guardar imágenes que tienen múltiples tamaños y resoluciones. Esta nueva característica nos permite tener más localizables las imágenes y agruparlas por el nombre (vamos a seguir teniendo que añadir los sufijos correspondientes). Xcode compila el asset catalog de forma que deja el bundle de la forma más eficiente posible reduciendo el tamaño de nuestra app. Podemos almacenar tanto recursos como el icono de la app y las launch screen:

Asset catalogs en Xcode 5
Asset catalogs en Xcode 5

Otra de las características que nos ofrece es el de slicing que es la capacidad de “estirar” las imágenes. La idea es replicar cierta fila o columna de píxeles de forma que no deformen la imagen cuando variamos su tamaño. Nos puede venir muy bien para botones.

UIGestureRecognizer 

Nuevo gesto UIScreenEdgePanGestureRecognizer que realiza el seguimiento del gesto que se inicia cerca de un margen de la pantalla. Se utiliza por ejemplo para poder hacer pop de un viewController cuando se ha empezado a hacer pan desde el margen izquierdo.

UIActivity

Soporta Airdrop, enviar elementos a la reading list de Safari y enviar contenido a Flickr, Tencent Weibo (Facebook chino) y Vimeo.

UITableView

Soporta estimar el alto de las celdas para un mejor rendimiento del scroll. Nos podemos olvidar de tener que implementar el método del delegado para decirle el alto que tendrá la celda. El precio que tendremos que pagar será utilizar autolayout, aunque en Xcode 5 ha mejorado muchísimo.

Las celdas han cambiado el modo de separación entre ellas, ya no es una línea que ocupa todo el ancho de la celda (imagen de la izquierda), ahora podemos especificar el inset que tienen por la izquierda. Por defecto y para los distintos estilos de las celdas vienen como los de la imagen de la derecha aunque podemos especificar la nuestra por código o interfaz.

Formato de las celdas pre iOS 7 e iOS 7

UISegmentedControl/UIStepper

Ya no tienen estilos, solo hay uno y lo que cambia es su propiedad tintColor.

UIPickerView

Ahora se puede presentar inline y no solo como un viewController de forma modal.

UIDatePicker inline
UIDatePicker inline

ISearchDisplayController

Las búsquedas se pueden realizar dentro del navigationController. Hasta ahora no se podría y estaban debajo de ésta.

UISearchDisplayController en iOS 7
UISearchDisplayController en iOS 7

UICollectionView

Añade soporte para transiciones de layouts intermedios e invalidación de contextos.

Se puede aplicar UIKit Dynamics al collection view layout para animar los elementos.

UIKeyCommand

Encapsula eventos de teclados recibidos por un teclado hardware externo.

Store Kit

Ha migrado a un nuevo sistema de recibos que los desarrolladores pueden utilizar para verificar in-app purchases desde el mismo dispositivo. También puedes utilizarlo para verificar el recibo de la compra de la app en el servidor.

Pass Kit 

Incluye nuevas API para añadir múltiples entradas a Passbook en una sola operación. También se ha añadido:

  • La expiración de la entrada.
  • Especificar que la entrada es solo relevante cerca de determinados iBeacons.
  • Nuevos atributos sobre como se muestra la entrada. Agrupar entradas juntas, poner enlaces con texto personalizado en la parte trasera y controlar como el tiempo se muestra en la entrada.
  • Puedes asociar información que no tiene porque mostrarse en la entrada.
  • Puedes elegir que patrones de detección de expresiones (URL, número móvil…) aplicar a los campos de tu entrada.

OpenGL ES

Añade soporte a OpenGL ES 3.0 y añade nuevas características a OpenGL ES 2.0.

Message UI

La API para enviar emails ahora añade funcionalidad para adjuntar elementos.

Media Player

Proporciona soporte para determinar si las rutas de acceso wireless como AirPlay o Bluetooth están disponibles para ser seleccionadas por el usuario, o saber si alguna de ellas está activa.

MapKit

Soporte para mapas en 3D y control sobre la perspectiva de forma programática. También incluye las siguientes mejoras:

  • Overlays a diferentes niveles, por capas.
  • Colocar en el mapa una especie de “Street view”.
  • Obtener información de rutas.
  • Overlays que siguen la curvatura de la tierra.
  • Captura de imágenes del mapa.
  • Nueva clase para renderizar overlays más sencilla.
  • Sobrescribir los trozos de mapa (tiles) por otros.

Image I/O 

Tiene interfaces para recuperar y asignar metadatos de la imagen.

iAd

Incluye extensiones para añadir anuncios antes de la reproducción de un vídeo y una nueva subclase de UIViewController para mostrar un anuncio antes de cargar su contenido.

GameKit 

Game Center incluye las siguientes mejoras:

  • Iniciar acciones con otros jugadores aunque le toque jugar al contrario. Se puede utilizar por ejemplo para chats. La característica se llama exchange.
  • Incremento del ranking de líderes de 25 a 100.
  • Establecer condiciones para retos.
  • Mejoras en autenticación para evitar trampas.

Foundation

  • NSData añade soporte a la codificación en base 64.
  • NSURLSession es una nueva clase para manejar recursos obtenidos a través de la red (incluso cuando la app esté suspendida o sin ejecución). Sustituye (sustituirá) a NSURLDownload y NSURLConnection y su delegado.

Ventajas:

    • Subir y descargar en background aprovechando al máximo las mejoras en multitasking.
    • Pausar y reanudar operaciones de red.
    • Es como un contenedor, si le metemos cabeceras las tendremos para toda la sesión.
    • Se puede subclasificar.
    • Mejora en la autenticación a través del delegado.
    • El delegado es muy completo.

Un ejemplo de NSURLSession sería:

NSURLSession *session = [NSURLSession sharedSession];

[[session dataTaskWithURL:[NSURL URLWithString:londonWeatherUrl]
        completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            // handle response
        }] resume];
  • NSURLComponents es una nueva clase para parsear componentes de una URL.
  • NSNetService and NSNetServiceBrowser descubren dispositivos peer-to-peer sobre Bluetooth y Wi-Fi.
  • NURLCredential and NSURLCredentialStorage permiten crear y eliminar credenciales con una política de sincronización en iCloud.
  • NSURLCache, NSURLCredentialStorage y NSHTTPCookieStorage soportan el procesamiento asíncrono de peticiones de almacenamiento.
  • NSCalendar soporta nuevos tipos de calendarios.
  • NSProgress monitoriza el proceso de una operación y lo reporta a otra parte de la aplicación que quiera usarlo.

Core Telephony

Permite obtener información sobre el tipo de tecnología de radio utilizada por el dispositivo.

Core Motion 

Añade soporte para el recuento y seguimiento del movimiento. Detecta los movimientos que corresponden al usuario y con esa información da el número de pasos al dispositivo (los puede tener sin estar ejecutándose la aplicación). También puede distinguir los diferentes movimientos reflexivos de los viajes a pie, corriendo o en coche, pudiendo las apps que hacen uso de ellas cambiar el tipo de indicaciones.

Core Location 

Puede determinar su localización a través de dispositivos Bluetooth cercanos mediante iBeacons. Por ejemplo esto permitiría que si en un museo estamos observando un cuadro, la app del museo nos mostrara una descripción del cuadro de forma automática. Más adelante cuando nos lleguen los cacharros haremos una prueba de concepto para ver de lo que son capaz los iBeacons 🙂

Core Foundation

Permite organizar objetos stream en colas.

Core Bluetooth

Permite guardar información de estado para los dispositivos centrales o periféricos y restaurar el estado de la app cuando se lanza.

AVFoundation

  • AVAudioSession permite seleccionar la entrada de audio, incluyendo audio desde micrófonos. Multicanal de entrada/salida.
  • AVVideoCompositing soportan compositores de vídeos personalizados.
  • AVSpeechSynthesizer proporciona capacidades de síntesis de voz.
  • Mejoras en la captura.
  • Nueva información en metadata.
  • AVAssetWriter asistencia en la formulación de los ajustes de salida y nuevas constantes para la codificación H.264.
  • AVPlayerLayer añade la propiedad videoRect.
  • AVPlayerItem puede cargar propiedades asset automáticamente cuando está listo para playback. Éstas propiedades están no son bloqueantes y pueden devolver valores por defecto si el objeto no está listo para reproducirse, es una buena práctica utilizar el protocolo KVO.
  • AVPlayerItemLegibleOutput puede procesar texto sincronizado de archivos multimedia.
  • AVAssetResourceLoaderDelegate soporta la carga de rangos arbitrarios de bytes desde recursos multimedia.

Accelerate

  • Mejorado el soporte para manipular tipos de Core Graphics.
  • Soporte para trabajar con imágenes de escala de grises de 1, 2, 3 o 4 bits por píxel.
  • Nuevas rutinas para convertir imágenes entre distintos formatos y transformar el contenido de las imágenes.
  • Operaciones IIR

APIs discontinuadas 

Cuando la gente de Cupertino discontinúa APIs no lo hacen de la noche a la mañana, la retiran pasado un tiempo. Pero nos aconsejan que vayamos utilizando las nuevas clases (o constantes o lo que sea) para que luego no tengamos problemas en futuras versiones de iOS o bien en el proceso de revisión para subir al App Store.

  • MKOverlayView y sus subclases. Hay que utilizar MKOverlayRenderer.
  • Audio Session API en AudioToolbox. Sustituido por AVAudioSession en AVFoundation.
  • CLRegion reemplazada por CLCircularRegion.
  • La propiedad UUID de CBCentral se reemplaza por identifier.
  • wantsFullScreenLayout de UIViewController ya no tiene sentido porque ahora siempre lo soporta.

Hasta aquí el repaso general a todas las nuevas APIs que nos proporciona Apple (cerca de 1.500!!! aunque la mayoría son a causa de instancetype). En posts siguientes hablaremos sobre algunos de los cambios de forma más detallada.

Que la fuerza os acompañe en la transición a iOS 7!!!

Fernando Rodríguez

iOS Developer & Co-Fundador de KeepCoding

Posts más leídos