servicios y herramientas en ios - ua · 2.4 integrando in-apps: desbloquear pantalla secreta ......

99
Servicios y herramientas en iOS Índice 1 iAd, AdMob e In Apps................................................................................................. 2 1.1 La publicidad de Apple: iAd.................................................................................... 2 1.2 La publicidad de Google: AdMob......................................................................... 12 1.3 Otras plataformas de publicidad en iOS................................................................ 23 1.4 Micropagos: In-Apps............................................................................................. 24 2 iAd, AdMob e In Apps - Ejercicios............................................................................ 42 2.1 Incorporando iAd a una aplicación iOS................................................................. 42 2.2 (*) Gestionando las orientaciones del dispositivo con iAd.................................... 43 2.3 Incorporando AdMob a una aplicación iOS.......................................................... 43 2.4 Integrando in-apps: desbloquear pantalla secreta.................................................. 43 3 iCloud y notifications push......................................................................................... 45 3.1 iCloud..................................................................................................................... 45 3.2 Notificaciones push................................................................................................ 60 4 iCloud y notifications push - Ejercicios..................................................................... 74 4.1 Compartiendo datos en la nube: iCloud................................................................. 74 4.2 Notificaciones push................................................................................................ 74 5 Depuración y pruebas................................................................................................. 75 5.1 Depuración clásica: Uso de NSLog y Asserts....................................................... 75 5.2 Usando el depurador de XCode............................................................................. 77 5.3 Usando Instruments para detectar problemas de memoria.................................... 81 5.4 Pruebas de unidad.................................................................................................. 91 6 Depuración y pruebas - Ejercicios.............................................................................. 97 6.1 Usando NSLog con distintos tipos de datos.......................................................... 97 6.2 Breakpoints y análisis de variables........................................................................ 97 6.3 NSZombie: Detectando las excepciones de memoria............................................ 97 6.4 Instruments: detectando memory leaks.................................................................. 97 Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

Upload: others

Post on 26-Jul-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

  • Servicios y herramientas en iOS

    Índice

    1 iAd, AdMob e In Apps................................................................................................. 2

    1.1 La publicidad de Apple: iAd....................................................................................2

    1.2 La publicidad de Google: AdMob......................................................................... 12

    1.3 Otras plataformas de publicidad en iOS................................................................ 23

    1.4 Micropagos: In-Apps............................................................................................. 24

    2 iAd, AdMob e In Apps - Ejercicios............................................................................42

    2.1 Incorporando iAd a una aplicación iOS.................................................................42

    2.2 (*) Gestionando las orientaciones del dispositivo con iAd....................................43

    2.3 Incorporando AdMob a una aplicación iOS.......................................................... 43

    2.4 Integrando in-apps: desbloquear pantalla secreta.................................................. 43

    3 iCloud y notifications push.........................................................................................45

    3.1 iCloud.....................................................................................................................45

    3.2 Notificaciones push................................................................................................60

    4 iCloud y notifications push - Ejercicios..................................................................... 74

    4.1 Compartiendo datos en la nube: iCloud.................................................................74

    4.2 Notificaciones push................................................................................................74

    5 Depuración y pruebas.................................................................................................75

    5.1 Depuración clásica: Uso de NSLog y Asserts....................................................... 75

    5.2 Usando el depurador de XCode............................................................................. 77

    5.3 Usando Instruments para detectar problemas de memoria.................................... 81

    5.4 Pruebas de unidad.................................................................................................. 91

    6 Depuración y pruebas - Ejercicios..............................................................................97

    6.1 Usando NSLog con distintos tipos de datos.......................................................... 97

    6.2 Breakpoints y análisis de variables........................................................................ 97

    6.3 NSZombie: Detectando las excepciones de memoria............................................97

    6.4 Instruments: detectando memory leaks..................................................................97

    Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • 1. iAd, AdMob e In Apps

    En esta primera sesión de Servicios iOS comenzaremos estudiando el sistema depublicidad de Apple: iAd. iAd está siendo actualmente uno de los servicios de publicidadmás usados en aplicaciones iOS junto con otros como AdMob, el propio de Google.Durante esta sesión veremos las ventajas y desventajas usar iAd en nuestras aplicaciones,configuraremos el servicio de iAd desde el portal de desarrolladores, iTunes Connect, yrealizaremos una aplicacion de ejemplo que lo use.

    Una vez visto iAd analizaremos el otro sistema de publicidad más usado en aplicacionesmóviles: AdMob. Al igual que iAd, analizaremos en detalle las ventajas y desventajas desu uso y veremos un ejemplo paso a paso de integración en una aplicación.

    Por último analizaremos el uso de las compras dentro de las aplicaciones, tambiénllamados "micropagos" o como Apple los llama: in-app. El uso de in-apps está a dia dehoy muy extendido como modelo de negocio en las aplicaciones para móviles. Su uso seestá extendiendo cada vez más ya que permite explotar económicamente las aplicacionesgratuitas de una forma "limpia" y bastante atractiva al usuario final. En esta sesiónveremos detenidamente como preparar nuestras aplicaciones para el uso de in-apps yrealizaremos un ejemplo paso a paso.

    1.1. La publicidad de Apple: iAd

    Durante la keynote de 2010 Apple presentó algo muy novedoso y atractivo para el mundode las aplicaciones iOS, una nueva plataforma de publicidad que denominó como iAd. Elnuevo sistema de publicidad estuvo disponible junto con la salida del iPhone 4. La ideafundamental de iAd es proporcionar al usuario una publicidad de calidad y con un granatractivo por la forma de integrarse en las aplicaciones.

    1.1.1. Ventajas y desventajas del uso de iAd

    iAd ofrece un sistema de publicidad no intrusivo: los anuncios se muestran en unaventana a parte (popup) dentro de la aplicación, lo que permite que el usuario acceda aesta publicidad sin salir de la aplicación, algo que no ocurre con el resto de modelos depublicidad. Este es un punto a favor.

    Otra de las ventajas de iAd es el sistema de reparto de ganancias que tiene. En un sistemade publicidad común nosotros, como desarrolladores editores, recibimos unos beneficiosbasados en el ratio de CPC (Coste por click) o CPM (Coste por impresión). En iAd elsistema vuelve a cambiar y nosotros recibiremos ganancias de ambos ratios, eso sí, aligual que ocurre en las aplicaciones de pago, recibiremos un 60% de las gananciasobtenidas. Es habitual que el desarrollador obtenga más beneficios de iAd que de otrasplataformas de publicidad.

    Servicios y herramientas en iOS

    2Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • iAd está integrado en su totalidad con el sistema de APIs del SDK de iOS, así como enlos portales de desarrolladores lo que supone una facilidad enorme a la hora de preparar laaplicación para mostrar anuncios así como para gestionar las ganancias. No necesitaremosacceder a otro sistema y gestionar todo por otro lado, con iAd lo tenemos integrado al100%.

    Pero todo no son cosas buenas... iAd tiene una gran desventaja respecto a otrasplataformas: la disponibilidad. Actualmente aún existen muchos paises sin total coberturade anuncios, lo que supone un problema grave para aquellos desarrolladores que basen sumodelo de negocio unicamente en este sistema. El país que más disponibilidad tiene deiAd es, como no podría ser de otra manera, Estados Unidos. En España, por ejemplo, ladisponibilidad es baja. Existen métodos alternativos que nos permiten detectar que en elcaso de que nuestra aplicación no reciba anuncios aparezca otra plataforma como AdMobo nuestros propios anuncios.

    La falta de disponibilidad de anunciantes es en gran medida debido a las altísimas tarifasque impone Apple a los anunciantes, los cuales se ven obligados a dejar a un lado iAdpara pasarse a otras plataformas más baratas. En este sentido Apple está progresivamentebajando las tarifas, por lo que se espera que a corto-medio plazo existan muchos másanunciantes en iAd y por lo tanto, más disponibilidad.

    Por útlimo comentar que una de las grandes desventajas del modelo de negocio depublicidad en aplicaciones móviles es la necesidad de disponer de una conexión activa aInternet para acceder a los anuncios. Como en el punto anterior, existen varios métodosalternativos que deberemos de contemplar en el caso de que el usuario no disponga deInternet, como por ejemplo mostrar anuncios propios que promocionen nuestrosproductos (otras aplicaciones...).

    1.1.2. Integrando iAd en nuestras aplicacioness

    En este punto veremos como integrar la plataforma de publicidad iAd en nuestrasaplicaciones iOS. El banner de publicidad estará preparado para la rotación deldispositivo: este tiene que rotar junto con el dispositivo. Comenzaremos creando unproyecto desde cero en XCode el cual contendrá una vista únicamente y despuésincorporaremos iAd. ¡Comenzamos!

    Empezamos creando un proyecto nuevo en XCode usando la plantilla Single ViewApplication. Los datos del proyecto serán los siguientes:

    • Product name: serviciosios_sesion01_iad• Company Identifier: es.ua.jtech• Class prefix: UA• Device family: iPhone• Seleccionar sólo "Use Automatic Reference Counting", el resto de opciones las

    dejamos desmarcadas.

    Servicios y herramientas en iOS

    3Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • Datos del proyecto

    Una vez creado el proyecto en XCode vamos a modificar la vista que se crea por defecto,UAViewController.xib y vamos a añadirle dos campos y un fondo de color de textoquedando la vista de la siguiente forma:

    Servicios y herramientas en iOS

    4Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • UAViewController.xib

    Una vez que hemos diseñado la vista principal de nuestra aplicación vamos a crear losoutlets para relacionar los campos de texto y así poder acceder a ellos desde lacontroladora. Para hacer esto debemos abrir el fichero UAViewController.h y añadir lassiguientes líneas justo antes de la etiqueta @end:

    Servicios y herramientas en iOS

    5Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • @property (weak, nonatomic) IBOutlet UILabel*labelEstadoiAd;

    @property (weak, nonatomic) IBOutlet UITextView *texto;

    Ahora hacemos lo propio en el fichero de implementación UAViewController.m,añadimos los @synthesize para poder acceder a las propiedades:

    @synthesize labelEstadoiAd = _labelEstadoiAd;@synthesize texto = _texto;

    Ahora sólo nos queda relacionar los componentes de la vista (los dos campos de texto)con los outlets. Una vez hecho esto ya tenemos la vista creada y lista para usar.

    Con la vista diseñada y relacionada desde la controladora vamos a implementar el sistemade iAd. Comenzamos añadiendo el framework de iAd al proyecto. Esto lo hacemos desdela pestaña de Build Phases de la pantalla de información del proyecto. Deplegamos lapestaña Link Binary With Libraries y añadimos el framework iAd.framework.

    Elegir el framework

    Deberemos de modificar la controladora UAViewController: Añadimos la referencia a laclase ADBannerView que será la encargada de mostrar el banner en la vista. Tambiéncreamos dos nuevas propiedades en la clase, un flag que nos indique si el banner estávisible y otra para referenciar al propio banner. Por último debemos de indicar a lacontroladora que esta implementará los métodos del protocolo ADBannerViewDelegate,los cuales nos advertirán si se visualiza el banner, si se ha pulsado sobre el, etc. El archivoUAViewController.h quedaría por tanto de la siguiente manera:

    Servicios y herramientas en iOS

    6Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • #import #import "iAd/ADBannerView.h"

    @interface UAViewController : UIViewController

    @property (weak, nonatomic) IBOutlet UILabel *labelEstadoiAd;@property (weak, nonatomic) IBOutlet UITextView *texto;@property (nonatomic, strong) IBOutlet ADBannerView *adBannerView;@property (nonatomic) BOOL bannerEsVisible;

    @end

    Abrimos de nuevo el archivo UAViewController.xib y arrastramos el objeto AdBannerView a la vista situándolo en la parte superior. Una vez ajustado el banner lorelacionamos como hemos hecho con el resto de outlets quedando la vista principal de lasiguiente forma. También deberemos indicar en la vista que la propiedad delegate delobjeto Ad BannerView referencia a la controladora, para ello pulsamos la tecla ctrl sobreel banner y sin soltar la tecla arrastramos el cursor del ratón hasta File's owner yseleccionamos "delegate".

    Servicios y herramientas en iOS

    7Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • Ad BannerView

    Por último nos queda completar la implementación de la controladora añadiendo los@synthesize que faltan y los métodos del protocolo ADBannerViewDelegate:

    //synthesize despues de @end@synthesize adBannerView = _adBannerView;

    @synthesize bannerEsVisible = _bannerEsVisible;

    //metodos de la clase delegada de ADBannerView#pragma mark ADBannerViewDelegate

    - (void)bannerViewDidLoadAd:(ADBannerView *)banner {if (!self.bannerEsVisible) {

    self.bannerEsVisible = YES;

    }

    Servicios y herramientas en iOS

    8Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • }

    - (void)bannerView:(ADBannerView *)bannerdidFailToReceiveAdWithError:(NSError *)error{

    if (self.bannerEsVisible){

    self.bannerEsVisible = NO;

    }}

    En primer método de los dos implementados se ejecutará cuando se cargue la vista delbanner. El segundo método servirá para indicarnos si ha ocurrido algún error al recibir elbanner de Apple. Para terminar modificaremos los dos métodos anteriores para queactualicen el campo de texto según el banner sea visible o no:

    - (void)bannerViewDidLoadAd:(ADBannerView *)banner {if (!self.bannerEsVisible) {

    self.bannerEsVisible = YES;self.labelEstadoiAd.text = @"iAd funcionando";

    }

    }

    - (void)bannerView:(ADBannerView *)bannerdidFailToReceiveAdWithError:(NSError *)error{

    if (self.bannerEsVisible){

    self.bannerEsVisible = NO;self.labelEstadoiAd.text = @"Error en iAd :(";

    }

    }

    Con esto útlimo ya tenemos iAd integrado en una aplicación muy sencilla. Si arrancamosla aplicación veremos que aparecerá un banner de test el cual si pulsamos sobre el nosaparecerá una ventana emergente que con la publicidad (ahora nos aparecerá publicidadde pruebas). La publicidad real aparece únicamente cuando la aplicación está a la ventaen la App Store.

    Si rotamos el dispositivo podemos ver que el banner no se adapta bien a la rotación, parasolucionar esto deberemos de completar la implementación añadiendo un par de métodosnuevos y modificando los del protocolo ADBannerViewDelegate. Comenzamosañadiendo dos métodos nuevos para gestionar la rotación del dispositivo y la de la vistadel banner:

    // Método que adapta el tamaño del banner según la rotación deldispositivo

    -(void)rotaBannerPosicion:(UIInterfaceOrientation)toInterfaceOrientation {

    if (self.adBannerView != nil) {

    Servicios y herramientas en iOS

    9Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {[self.adBannerView setCurrentContentSizeIdentifier:ADBannerContentSizeIdentifierLandscape];

    } else {[self.adBannerView setCurrentContentSizeIdentifier:ADBannerContentSizeIdentifierPortrait];

    }}

    }

    // Método que se ejecuta automáticamente cuando el dispositivo rota-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientationduration:(NSTimeInterval)duration {

    [self rotaBannerPosicion:toInterfaceOrientation];}

    Ahora añadimos una llamada al método rotaBannerPosicion desde los métodos delprotocolo del AdBannerView quedando los métodos de la siguiente manera:

    - (void)bannerViewDidLoadAd:(ADBannerView *)banner {if (!self.bannerEsVisible) {

    self.bannerEsVisible = YES;self.labelEstadoiAd.text = @"iAd funcionando";

    [self rotaBannerPosicion:[UIDevice currentDevice].orientation];}

    }

    - (void)bannerView:(ADBannerView *)bannerdidFailToReceiveAdWithError:(NSError *)error{

    if (self.bannerEsVisible){

    self.bannerEsVisible = NO;self.labelEstadoiAd.text = @"Error en iAd :(";

    [self rotaBannerPosicion:[UIDevice currentDevice].orientation];}

    }

    Si volvemos a ejecutar la aplicación veremos que el banner rota junto con el dispositivo yeste se adapta al tamaño adecuado.

    Servicios y herramientas en iOS

    10Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • Vista vertical

    Servicios y herramientas en iOS

    11Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • Vista horizontal

    1.2. La publicidad de Google: AdMob

    En este apartado analizaremos las ventajas y desventajas de usar la plataforma depublicidad de Google para móviles AdMob y veremos cómo implementarla en unaaplicación propia.

    1.2.1. AdMob: Ventajas y desventajas

    Se podría decir que, en iOS, AdMob es el complemento perfecto de iAd y es que AdMobtiene varios puntos a favor bastante destacables, vamos a analizarlos uno a uno:

    Por un lado, en contra de lo que ocurre con iAd, la publicidad de AdMob está disponibleen la mayoría de paises y de ellos las impresiones son casi al 100%, por lo que en el casode implementarlo nos aseguraremos que siempre o casi siempre nos aparecerá el banner,algo que no podemos asegurar a dia de hoy con iAd.

    Google es es encargado de la plataforma AdMob, lo que nos asegura una fiabilidad yestabilidad bastante importante. También disponemos de una API bastante documentaday diversos tutoriales para implementar AdMob en nuestras aplicaciones, lo que nosfacilita el trabajo.

    Servicios y herramientas en iOS

    12Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • Otro punto a favor tiene que ver con la compatibilidad de la plataforma, y es que AdMobes, aparte de iOS, compatible con Android, por lo que podremos tener asociada unamisma cuenta para distintas plataformas de móviles.

    Por otro lado, una desventaja que tiene AdMob es que no está integrada con el sistema dedesarrolladores de Apple, en concreto con el portal de iTunes Connect, por lo que todaslas estadísticas de clicks, ganancias, etc. funcionan de otra forma y deberemos degestionar dos cuentas distintas, una para AdMob y otra para Apple. Respecto a lasganancias y al reparto de beneficios de la publicidad, en AdMob se suele obtener algomenos de ganancias ya que los ratios de CPC y CPM son algo menores.

    Por último comentar que la publicidad de AdMob en versiones anteriore era intrusivapara la experiencia del usuario. En la versión actual han mejorado este punto y yafunciona de manera similar a iAd: al pulsar sobre el banner de publicidad no saldrá de laaplicación y se abrirá a cambio una ventana emergente. Esto es un punto a favor, sin dudaalguna.

    1.2.2. Integrando AdMob

    Con el fin de aprender a integrar AdMob en nuestras aplicaciones iOS vamos a realizarun sencillo ejemplo en el que mediante una serie de pasos sencillos nos registraremoscomo desarrolladores, nos descargaremos el SDK de AdMob para iOS y finalmente loimplementaremos.

    Para poder hacer uso de AdMob tanto en iOS como en Android deberemos deregistrarnos previamente en su sitio web, para ello abrimos un navegador y entramos enhttp://www.admob.com. Una vez dentro pulsamos sobre Register en la parte superiorderecha, rellenamos todos los campos del formulario y pulsamos en Submit.

    Servicios y herramientas en iOS

    13Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

    http://www.admob.com

  • AdMob

    Una vez registrados en el portal, pulsamos sobre Sitios y aplicaciones > Agregarsitio/aplicación. De nuevo deberemos de rellenar todos nuestros datos de la empresa y dela cuenta personal del banco para los ingresos.

    Servicios y herramientas en iOS

    14Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • AdMob

    Una vez rellenado el formulario anterior nos aparecerá una nueva ventana para elegir laplataforma de la aplicación que vamos a realizar. Ahi seleccionamos Aplicación deiPhone

    Servicios y herramientas en iOS

    15Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • AdMob

    Ahora rellenamos los detalles de la aplicación (nombre, categoría, descripción, estilo delos banners...). En el nombre de la aplicación escribiremos sesion01 admob.Completamos el resto de datos y pulsamos en Continuar.

    Servicios y herramientas en iOS

    16Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • AdMob

    Una vez completados los datos básicos de la aplicación vamos a descargarnos el SDK deAdMob. Para descargar el SDK debemos pulsar en Descargar AdMob iOS SDK. Tambiénpodemos acceder a la documentación entrando en el enlace que hay justo debajo delbotón de descarga.

    AdMob

    Con esto ya nos hemos creado una cuenta en AdMob y nos hemos descargado la última

    Servicios y herramientas en iOS

    17Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • versión del SDK para iOS. Ahora vamos a crear un nuevo proyecto en XCode usando laplantilla Single View Application y que tendrá los siguientes datos:

    • Product name: serviciosios_sesion01_admob• Company Identifier: es.ua.jtech• Class prefix: UA• Device family: iPhone• Seleccionar sólo "Use Automatic Reference Counting", el resto de opciones las

    dejamos desmarcadas.

    Ahora, con el proyecto abierto, arrastramos la carpeta completa del SDK de AdMob a laraiz del proyecto seleccionando la opción Copy items into destination group'sfolder (if needed). También deberemos de añadir al proyecto los siguientesframeworks: AudioTollbox.framework,MediaPlayer.framework,MessageUI.framework y

    SystemConfiguration.framework.

    AdMob

    Una vez añadidos los frameworks necesarios y el SDK de AdMob vamos a "comenzar"con el desarrollo del contenido de la aplicación. Vamos a modificar la vista principalUAViewController.xib añadiéndole, al igual que en el ejemplo de iAd, dos campos detexto y un fondo, la vista deberá quedar de la siguiente manera:

    Servicios y herramientas en iOS

    18Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • AdMob

    Ahora vamos a modificar la controladora UAViewController para añadirle el códigonecesario del banner. El archivo UAViewController.h debe quedar como sigue:

    Servicios y herramientas en iOS

    19Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • #import #import "GADBannerView.h"

    @interface UAViewController : UIViewController

    @property (strong, nonatomic) GADBannerView *AdMob;

    @end

    Ahora modificamos el archivo UAViewController.m añadiendo el siguiente código almétodo viewDidLoad:

    - (void)viewDidLoad{

    [super viewDidLoad];// Do any additional setup after loading the view, typically from

    a nib.

    // Posicionamos el banner en la parte inferior de la vistaself.AdMob = [[GADBannerView alloc] initWithFrame:CGRectMake(0.0, self.view.frame.size.height -

    GAD_SIZE_320x50.height,GAD_SIZE_320x50.width,GAD_SIZE_320x50.height)];

    self.AdMob.adUnitID = AdMob_ID;

    // Añadimos el banner a la vistaself.AdMob.rootViewController = self;[self.view addSubview:self.AdMob];

    // Hacemos una petición de test para el bannerGADRequest *r = [[GADRequest alloc] init];r.testing = YES;[self.AdMob loadRequest:r];

    }

    También deberemos definir nuestro AdMob ID y el @synthesize del banner:

    // Debajo del import#define AdMob_ID @"a14f52699ef091a" // Nuestro Publisher

    ID (www.admob.com)

    // Debajo de la etiqueta implementation@synthesize AdMob = _AdMob;

    Una vez hechos estos últimos cambios ya podemos compilar y arrancar nuestraaplicación. Si todo ha ido bien veremos el banner de prueba en la parte inferior de lavista.

    Servicios y herramientas en iOS

    20Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • AdMob

    Si queremos que el banner aparezca en la parte superior de la pantalla, al igual quehicimos en el ejemplo de iAd, deberemos de modificar ligeramente el código deposicionamiento del método viewDidLoad de la siguiente manera:

    self.AdMob = [[GADBannerView alloc]initWithFrame:CGRectMake(0.0, 0.0,GAD_SIZE_320x50.width,GAD_SIZE_320x50.height)];

    Servicios y herramientas en iOS

    21Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • AdMob

    Si queremos que el banner rote al mismo tiempo que giramos el dispositivo deberemos deimplementarlo nosotros. Podemos acceder a más información sobre la API de AdMob asícomo a código de ejemplo en esta dirección:https://developers.google.com/mobile-ads-sdk/docs/ios/fundamentals.

    Servicios y herramientas en iOS

    22Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

    https://developers.google.com/mobile-ads-sdk/docs/ios/fundamentals

  • 1.3. Otras plataformas de publicidad en iOS

    Además de iAd (Apple) y de AdMob (Google) existen otras plataformas de publicidad delas cuales podemos hacer uso en nuestras aplicaciones. Una de las más conocidas esAdSense (también de Google) y MobClix. Esta útlima se suele usar como complemento aiAd o AdMob ya que sus ratios de CPM y CPC son bastantes pequeños por lo que losbeneficios que obtenemos son pocos.

    AdSense en cambio ofrece unos porcentajes de ganancias algo mayores pero tiene elinconveniente que la publicidad que ofrece es muy poco atractiva: banners con fondoblanco o negro y con texto, sin imágenes. Esta plataforma suele ser muy poco efectiva y,por lo tanto, poco recomendada para usar como sistema de publicidad principal.

    Como hemos visto en los puntos anteriores, muchas veces tenemos el problema de la faltade conexión a Internet o falta de disponibilidad de banners. Esto provoca que lapublicidad no se muestre en la aplicación y por lo tanto, no obtengamos ganancias deesta. Para evitar esto deberemos de implementar un "plan alternativo" que nos asegureque siempre se va a mostrar la publicidad.

    Tenemos dos opciones para implementar este plan alternativo: programarlo en nuestraaplicación nosotros mismos o utilizar una API que nos ayude a hacerlo. Esta últimaopción es la que vamos a analizar con un poco más de profundidad.

    Existen varios sistemas online que ofrecen un servicio de "rotación" de publicidad entredistintas plataformas, entre ellas destaca para móviles AdWhirl(https://www.adwhirl.com/). AdWhirl un sistema que se encarga dinámicamente y deforma totalmente automática de cambiar entre redes de publicidad según la preferenciaque indiquemos nosotros y la disponibilidad de estas.

    Servicios y herramientas en iOS

    23Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

    https://www.adwhirl.com/

  • Imagen

    AdWhirl además destaca porque podemos incorporar nuestros propios banners ydisponemos de toda la gestión de las plataformas de publicidad desde un mismo panel decontrol, lo que nos facilita enormemente la tarea de gestión de estas.

    En AdWhirl podemos añadir la inmensa mayoría de redes de publicidad, entre ellas están:iAd, AdMob, JumTab, Millennial Media, Quattro Wireless, Mobclix, AdSense, etc... Unavez registrados en el sistema (totalmente gratuito) deberemos escoger las redes quequeremos usar en nuestra aplicación y asignarles una preferencia. Esta preferencia setendrá en cuenta a la hora de mostrar la publicidad, si una red no tiene disponiblidad debanners pasará a la siguiente con más preferencia.

    Obviamente deberemos registrarnos previamente en aquellas plataformas (o redes) depublicidad que vayamos a utilizar en AdWhirl, y desde el panel de control añadiremos lasclaves de cada una.

    1.4. Micropagos: In-Apps

    Una vez visto el modelo de negocio de publicidad vamos a analizar en profundidad otromodelo bastante usado entre los desarrolladores de Apple: in-apps.

    Servicios y herramientas en iOS

    24Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • In-app

    Los in-apps o micropagos son compras que se realizan dentro de la aplicación. Unaaplicación de iOS puede tener tantos in-apps como quiera del desarrollador y cada uno deestos al precio que se desee (según las tarifas de Apple). Existen dos tipos de in-apps:consumibles y no consumibles.

    • Consumibles: Aquellos que el usuario puede comprar más de una vez, por ejemplo:dinero virtual en un juego social.

    • No consumibles: Aquellos que el usuairo sólo puede comprar una vez, por ejemplo:desbloquear un nivel en un juego.

    Lo más habitual es implementar el sistema de in-apps en aplicaciones gratuitas ya que deeste modo conseguiremos muchos más descargas y, por lo tanto, más clientes potencialesde in-apps.

    La implementación de in-apps en una aplicación iOS es algo compleja y requiere de unacuenta activa como desarrollador en Apple. En el siguiente apartado realizaremos unejemplo paso a paso de incorporación de un in-app en una aplicación para iPhone.

    1.4.1. Implementando los in-apps: App freemium

    En este apartado veremos en más detalle como incorporar los in-apps en nuestrasaplicaciones. Para ello realizaremos un ejemplo de una aplicación freemium o lo que es lomismo: aplicación reducida con opción a compra para desbloquear la versión completa).La aplicación la implementaremos paso a paso durante los cuales veremos como crear losin-apps dentro del portal de iTunes Connect y como programarlos en modo de test osandboxing en una aplicación sencilla. ¡Empezamos!

    Servicios y herramientas en iOS

    25Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • El ejemplo que vamos a realizar consistirá en una sencilla aplicación iPhone la cual estaráformada por dos vistas: una principal a la que todo el mundo tendrá acceso y otra a la quesólo se podrá acceder si hemos comprado un in-app que costará 0.79 euros, una pantalla"secreta". Este in-app será de tipo no consumible, es decir, sólo podremos comprarlo unavez y tendremos que tener en cuenta la compra para que cada vez que el usuario arranquela aplicación compruebe si ya ha comprado el in-app.

    1.4.1.1. Preparación: Apple Developer y iTunes Connect

    Antes de empezar con la programación de la aplicación en XCode vamos a crear un AppID para nuestra aplicación. El App ID es una cadena de texto única que identifica cadauna de nuestras aplicaciones, en este caso crearemos un App ID dentro del portal dedesarrolladores (https://developer.apple.com) con el nombre Ejemplo in app y elidentificador (Bundle ID) es.ua.jtech.ejemploinapp.

    Provisioning Portal

    Antes de empezar con la programación de la aplicación en XCode vamos a crear losin-apps dentro del portal iTunes Connect. Conviene recordar que para acceder a esteportal deberemos de tener una cuenta activa como desarrollador Apple. Accedemos alportal (https://itunesconnect.apple.com) usando nuestro Apple ID y contraseña.

    Una vez dentro entraremos dentro del apartado Manage Your Applications y creamosuna nueva aplicación pulsando en Add New App.

    Servicios y herramientas en iOS

    26Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

    https://developer.apple.comhttps://itunesconnect.apple.com

  • Manage Your Applications

    El formulario que nos aparece lo completamos según la siguiente imagen y pulsamos en"Continue".

    App Informaion

    Seguimos completando el resto de formularios básicos de creación de una aplicaciónnueva en iTunes Connect... Una vez hecho esto (nos llevará un tiempo ya que debemos deescribir una descripción, subir unas imágenes básicas, etc.) pasaremos a crear los in-apps.

    Una vez que hayamos guardado el formulario anterior pulsamos sobre el botón "ManageIn-App Purchases" para comenzar con la creación de los in-apps.

    Manage In-App Purchases

    Servicios y herramientas en iOS

    27Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • En el formulario que nos aparece ahora deberemos de escoger entre cuatro tipos distintosde in-apps, los dos primeros son los que hemos comentado anteriormente (consumibles yno consumibles) y los otros dos son exclusivos para aplicaciones del quiosco (Newstand).Nosotros escogeremos el segundo tipo, Non Consumable ya que una vez que el usuariocompre el in-app este se bloqueará y no tendrá que comprarlo más veces.

    In app

    Ahora deberemos de completar todos los campos del formulario sobre el in-app.Escribiremos un nombre único para identificarlo, una breve descripción en al menos unidioma, un precio (elegimos la primera tarifa, tier 1) y una imagen. Rellenaremos elformulario tal y como se muestra en la siguiente imagen:

    Servicios y herramientas en iOS

    28Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • In-App configuración

    Una vez completado el formulario anterior ya tenemos el in-app creado y configurado eniTunes Connect. Ahora deberemos de implementarlo en nuestra aplicación, pero antesvamos a diseñar toda la estructura básica.

    1.4.1.2. Implementación de toda la estructura básica

    Comenzamos creando un proyecto nuevo en XCode con la plantilla Single View

    Servicios y herramientas en iOS

    29Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • Application al que llamaremos serviciosios_sesion01_inapps y tendrá los siguientesdatos:

    • Product name: serviciosios_sesion01_inapps• Company Identifier: es.ua.jtech• Class prefix: UA• Device family: iPhone• Seleccionar sólo "Use Automatic Reference Counting", el resto de opciones las

    dejamos desmarcadas.

    Una vez creado el proyecto en XCode vamos a modificar la vista principalUAViewController.xib añadiendo una etiqueta de texto y dos botones, uno paracomprar el in-app y otro para abrir la pantalla "secreta":

    Servicios y herramientas en iOS

    30Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • Vista

    Ahora programamos la controladora principal de la aplicación. Abrimos el archivoUAViewController.h y lo dejamos de la siguiente manera:

    #import

    @interface UAViewController : UIViewController

    Servicios y herramientas en iOS

    31Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • @property (weak, nonatomic) IBOutlet UIButton *botonCompra;@property (weak, nonatomic) IBOutlet UIButton *botonAbreVentanaSecreta;

    -(IBAction)clickBotonCompra:(id)sender;-(IBAction)clickBotonVentanaSecreta:(id)sender;

    @end

    Ahora modificamos el archivo UAViewController.m añadiendo los @synthesize y lasacciones de los botones:

    //Debajo de @implementation@synthesize botonCompra = _botonCompra;

    @synthesize botonAbreVentanaSecreta = _botonAbreVentanaSecreta;

    // Añadimos los siguientes métodos-(IBAction)clickBotonCompra:(id)sender {

    NSLog(@"clickBotonCompra");

    // Código de lanzamiento del in-app}

    -(IBAction)clickBotonVentanaSecreta:(id)sender {NSLog(@"clickBotonVentanaSecreta");

    // Código para abrir la ventana secreta}

    Ahora vamos a diseñar la "ventana secreta", para ello vamos a crear un nuevo objeto detipo UIViewController Subclass que llamaremos VentanaSecretaViewController.Abrimos la vista y la editamos a nuestro gusto, por ejemplo:

    Servicios y herramientas en iOS

    32Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • VentanaSecretaViewController

    Una vez hecho esto ahora nos queda relacionar los Outlets y las acciones de la vistaprincipal, esto lo hacemos desde la propia vista, y completar la acción del botón que abrela ventana secreta:

    -(IBAction)clickBotonVentanaSecreta:(id)sender {

    Servicios y herramientas en iOS

    33Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • NSLog(@"clickBotonVentanaSecreta");

    VentanaSecretaViewController *ventanaSecreta =[[VentanaSecretaViewController alloc]

    initWithNibName:@"VentanaSecretaViewController" bundle:nil];

    [self presentModalViewController:ventanaSecreta animated:YES];}

    Comprobamos que la aplicación funciona correctamente.

    1.4.1.3. Implementación del in-app

    Una vez implementado el funcionamiento básico de la aplicación (sin in-apps) vamos aincorporar el in-app para desbloquear la ventana secreta. Comenzamos añadiendo elframework StoreKit al proyecto y modificando el fichero UAViewController.himportando la clase StoreKit y añadiendo el protocolo SKProductsRequestDelegateen la definición de la controladora para que esta implemente sus métodos delegados. Estesería el flujo de información entre la aplicación nuestra y la App Store que vamos a usar:

    Servicios y herramientas en iOS

    34Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • Flujo de información con la App Store

    El código que implementará el in-app quedaría como sigue:

    #import #import

    @interface UAViewController : UIViewController

    @property (weak, nonatomic) IBOutlet UIButton *botonCompra;

    Servicios y herramientas en iOS

    35Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • @property (weak, nonatomic) IBOutlet UIButton *botonAbreVentanaSecreta;

    @property(nonatomic, retain) NSMutableArray *productIdentifierList;@property(nonatomic, retain) NSMutableArray *productDetailsList;

    -(IBAction)clickBotonCompra:(id)sender;-(IBAction)clickBotonVentanaSecreta:(id)sender;

    @end

    Ahora tenemos que modificar el archivo UAViewController.m añadiendo las clasesdelegadas del protocolo SKProductsRequestDelegate y del observerSKPaymentTransactionObserver. El código final quedaría de la siguiente manera:

    #import "UAViewController.h"#import "VentanaSecretaViewController.h"

    @implementation UAViewController@synthesize botonCompra = _botonCompra;@synthesize botonAbreVentanaSecreta = _botonAbreVentanaSecreta;@synthesize productIdentifierList = _productIdentifierList;@synthesize productDetailsList = _productDetailsList;

    - (void)didReceiveMemoryWarning{

    [super didReceiveMemoryWarning];// Release any cached data, images, etc that aren't in use.

    }

    #pragma mark - View lifecycle

    - (void)viewDidLoad{

    self.productIdentifierList = [[NSMutableArray alloc] init];self.productDetailsList = [[NSMutableArray alloc] init];

    [self.productIdentifierList addObject:@"ejemplo3"];

    // Cargamos la lista de productosSKProductsRequest *request = [[SKProductsRequest alloc]initWithProductIdentifiers:[NSSet

    setWithArray:self.productIdentifierList]];request.delegate = self;[request start];

    // Comprobamos si hemos comprado antes el in-appif ([[NSUserDefaults standardUserDefaults]boolForKey:@"inappComprado"] == YES){

    self.botonAbreVentanaSecreta.hidden = NO;}else {

    self.botonAbreVentanaSecreta.hidden = YES;}

    // Reinicia cualquier transacción si esta se interrumpió[[SKPaymentQueue defaultQueue] addTransactionObserver:self];

    [super viewDidLoad];

    Servicios y herramientas en iOS

    36Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • }

    - (void)viewDidUnload{

    [super viewDidUnload];// Release any retained subviews of the main view.// e.g. self.myOutlet = nil;

    }

    - (void)viewWillAppear:(BOOL)animated{

    [super viewWillAppear:animated];}

    - (void)viewDidAppear:(BOOL)animated{

    [super viewDidAppear:animated];}

    - (void)viewWillDisappear:(BOOL)animated{

    [super viewWillDisappear:animated];}

    - (void)viewDidDisappear:(BOOL)animated{

    [super viewDidDisappear:animated];}

    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{

    // Return YES for supported orientationsreturn (interfaceOrientation !=

    UIInterfaceOrientationPortraitUpsideDown);}

    #pragma mark Acciones de los botones

    -(IBAction)clickBotonCompra:(id)sender {NSLog(@"clickBotonCompra");

    // Código de lanzamiento del in-appif ([self.productDetailsList count] > 0 && [SKPaymentQueue

    canMakePayments]){SKProduct *thisProduct = [self.productDetailsList

    objectAtIndex:0];

    SKPayment *payment = [SKPayment paymentWithProduct:thisProduct];[[SKPaymentQueue defaultQueue] addPayment:payment];

    NSLog(@"Comprando...");}else {

    NSLog(@"No existen productos");}

    }

    -(IBAction)clickBotonVentanaSecreta:(id)sender {NSLog(@"clickBotonVentanaSecreta");

    VentanaSecretaViewController *ventanaSecreta =[[VentanaSecretaViewController alloc]initWithNibName:@"VentanaSecretaViewController" bundle:nil];

    Servicios y herramientas en iOS

    37Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • [self presentModalViewController:ventanaSecreta animated:YES];}

    #pragma mark - InApps métodos

    /** METODO QUE SE ACTIVA CUANDO RECIBIMOS LOS PRODUCTOS QUE TENEMOS EN

    IN-APP*/

    -(void)productsRequest:(SKProductsRequest *)requestdidReceiveResponse:(SKProductsResponse *)response{

    NSLog(@"didReceiveResponse. Total productos: %d", [response.productscount]);

    [self.productDetailsList addObjectsFromArray: response.products];

    for (NSString *invalidProductId in response.invalidProductIdentifiers){

    NSLog(@"Producto invalido id: %@" , invalidProductId);}

    }

    /** CARGA DE PRODUCTOS TERMINADA*/

    -(void)requestDidFinish:(SKRequest *)request{

    }

    /** FALLO CON LA CARGA DE LOS PRODUCTOS*/

    -(void)request:(SKRequest *)request didFailWithError:(NSError *)error{

    NSLog(@"Failed to connect with error: %@", [errorlocalizedDescription]);}

    /** METODO QUE DESBLOQUEA EL BOTÓN*/

    - (void)desbloqueaVentanaSecreta {

    NSLog(@"Actualiza flag de in app comprado");[[NSUserDefaults standardUserDefaults] setBool:NO

    forKey:@"inappComprado"];[[NSUserDefaults standardUserDefaults] synchronize];

    // Activamos el botonself.botonAbreVentanaSecreta.hidden = NO;

    }

    /** METODO QUE SE ACTIVA CUANDO SE COMPLETA UNA COMPRA*/

    - (void)completeTransaction:(SKPaymentTransaction *)transaction {

    NSLog(@"completeTransaction...");

    [self desbloqueaVentanaSecreta];

    Servicios y herramientas en iOS

    38Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • [[SKPaymentQueue defaultQueue] finishTransaction: transaction];

    }

    /** METODO QUE SE ACTIVA CUANDO SE CONTINUA CON UNA COMPRA*/

    - (void)restoreTransaction:(SKPaymentTransaction *)transaction {

    NSLog(@"restoreTransaction...");

    [self desbloqueaVentanaSecreta];[[SKPaymentQueue defaultQueue] finishTransaction: transaction];

    }

    /** METODO QUE SE ACTIVA CUANDO UNA COMPRA FALLA*/

    - (void)failedTransaction:(SKPaymentTransaction *)transaction {

    if (transaction.error.code != SKErrorPaymentCancelled){

    NSLog(@"Transaction error: %@",transaction.error.localizedDescription);

    }

    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];

    }

    /** METODO QUE SE ACTIVA CUANDO REALIZAMOS UNA TRANSACCIÓN*/

    - (void)paymentQueue:(SKPaymentQueue *)queueupdatedTransactions:(NSArray *)transactions{

    NSLog(@"updatedTransactions...");

    for (SKPaymentTransaction *transaction in transactions){

    switch (transaction.transactionState){

    case SKPaymentTransactionStatePurchased:[self completeTransaction:transaction];break;

    case SKPaymentTransactionStateFailed:[self failedTransaction:transaction];break;

    case SKPaymentTransactionStateRestored:[self restoreTransaction:transaction];

    default:break;

    }}

    }

    @end

    Atención

    Servicios y herramientas en iOS

    39Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • El bundle ID de la aplicación en XCode debe de coincidir con el Bundle identifierque hemos especificado al crear la aplicación en iTunes Connect.

    Si ejecutamos el código nos debería de aparecer el botón de la ventana secretadesactivado. Cuando pulsemos sobre el botón de comprar in-app nos pedirá un nombre deusuario y contraseña, ahí tendremos que escribir nuestro usuario de pruebas quepreviamente hemos creado dentro de la sección Manage Users del portal iTunes Connect.

    En el momento de confirmar la compra se ejecutará el método updatedTransactions elcual activará, si todo ha ido bien, el botón para mostrar la ventana secreta.

    Servicios y herramientas en iOS

    40Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • Confirmación in-app

    Servicios y herramientas en iOS

    41Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • 2. iAd, AdMob e In Apps - Ejercicios

    2.1. Incorporando iAd a una aplicación iOS

    En este ejercicio vamos a crear una aplicación muy sencilla para iPhone que contenga laplataforma de publicidad iAd como modelo de negocio. La aplicación estará compuestapor una sola ventana que tendrá un objeto de tipo UILabel el cual informará del estado dela publicidad (visible o no visible). En el caso de que esta no esté visible mostraremos unaimagen de publicidad nuestra. De este modo siempre se mostrará publicidad en laaplicación. Para completar el ejercicio deberemos de realizar los siguientes pasos:

    1) Creamos el proyecto en XCode con los siguientes datos:

    • Product name: ejercicio_iad• Company Identifier: es.ua.jtech• Class prefix: UA• Device family: iPhone• Marcar sólo la opción Use Automatic Reference Counting. El resto dejarlas

    desmarcadas.

    2) Modificamos el fichero UAViewController.xib añadiendo un objeto de tipo Label yel objeto de tipo Ad BannerView (el banner iAd) en la parte superior de la pantalla y unobjeto de tipo Image View que será nuestro propio banner. Definimos los outletscorrespondientes en el fichero UAViewController.h, los syntesize necesarios en elfichero UAViewController.m y establecemos las relaciones desde la vista.

    Mi banner

    3) Importamos el framework de iAd (iAd.framework) al proyecto.

    4) Modificamos la definición de la controladora (fichero UAViewController.h) para queesta implemente el protocolo ADBannerViewDelegate.

    5) Añadimos los dos métodos necesarios del protocolo ADBannerViewDelegate en laclase UAViewController:

    //metodos de la clase delegada de ADBannerView#pragma mark ADBannerViewDelegate

    - (void)bannerViewDidLoadAd:(ADBannerView *)banner {// Completar: banner visible y actualizar label

    }

    - (void)bannerView:(ADBannerView *)bannerdidFailToReceiveAdWithError:(NSError *)error

    Servicios y herramientas en iOS

    42Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • {// Completar: iAd no visible, mostrar nuestro banner y actualizar

    label}

    6) Comprobar que funciona todo bien. ¿Qué pasa si rotamos el dispositivo?

    2.2. (*) Gestionando las orientaciones del dispositivo con iAd

    En este ejercicio vamos a tener en cuenta las distintas posiciones que puede adoptar eldispositivo (portrait y landscape). Cuando giremos el dispositivo el banner de iAd debede girar también, para ello modificaremos el ejercicio anterior implementando el métodowillRotateToInterfaceOrientation de manera que cuando este se ejecute secompruebe la orientación del dispositivo y el banner gire según esta.

    2.3. Incorporando AdMob a una aplicación iOS

    En este ejercicio, al igual que hemos hecho en el primero, vamos a incorporar AdMob auna aplicación de iPhone. En este caso, para evitar todo el proceso de registro en el sitiode AdMob (http://es.admob.com/) comenzaremos el ejercicio desde una plantilla quepodemos descargar desde aquí.

    Completar el archivo UAViewController.m con el código necesario para mostrar elbanner:

    • a) En la parte inferior de la pantalla.• b) En la parte superior de la pantalla.• c) Código para hacer las peticiones del banner en modo testing.

    ¿Qué ventajas y desventajas encuentras al usar la plataforma AdMob con respecto a iAdde Apple?

    2.4. Integrando in-apps: desbloquear pantalla secreta

    En este ejercicio vamos a usar los in-apps para desbloquear una pantalla secreta de unaaplicación. El ejercicio consistirá en programar parte de la controladora de una aplicaciónpara conseguir que funcione el in-app que desbloquea un botón que da acceso a unapantalla "secreta".

    Ya que para usar in-apps necesitamos disponer de una cuenta de desarrollador Apple ynosotros no la tenemos, usaremos una plantilla con todo el proceso previo de preparaciónde la aplicación en iTunes Connect, certificados, etc ya implementado. Lo único quedeberemos hacer será completar una serie de ejercicios necesarios para el funcionamientodel in-app.

    • a) Importar el framework StoreKit.framework necesario para el uso de la API de

    Servicios y herramientas en iOS

    43Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

    http://es.admob.com/

  • in-apps.• b) Completar el método restoreTransaction• c) Completar el método completeTransaction• d) Completar el método desbloqueaVentanaSecreta

    Podemos probar si funciona el in-app usando el siguiente usuario de test:

    • Nombre de usuario: [email protected]• Contraseña: usuariotest1A

    La plantilla del ejercicio se puede descargar desde aquí.

    AyudaPara almacenar en memoria el estado de in-app comprado o no comprado podemos hacerlousando el método de persistencia NSUserDefaults de la siguiente forma:[[NSUserDefaults standardUserDefaults] setBool:YESforKey:@"inappComprado"];

    Servicios y herramientas en iOS

    44Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • 3. iCloud y notifications push

    Con la llegada de la nueva revisión de iOS al mercado, el iOS 5, los desarrolladores sehan puesto manos a la obra para adaptar en la medida de lo posible todas sus aplicacionesa los nuevos requerimientos y especificaciones de Apple. A lo largo del curso hemoshablado de distintas novedades que nos trae iOS 5 como el nuevo sistema de ARC(Automatic Reference Counting), la integración de Twitter en el sistema operativo, losStoryboards para diseñar la estructura de las apps, etc. En esta sesión es el turno de hablarde una de los mayores novedades que nos proporciona esta nueva versión de iOS y esnada más y nada menos que iCloud.

    Con iCloud podremos, en resumen, gestionar todos los documentos, configuraciones eincluso bases de datos completas en la nube para de este modo tener acceso de formatotalmente transparente e instantánea para el usuario final a la misma información entodos los dispositivos iOS, Macs y PCs que tengamos asociados a nuestra cuenta. En elprimer apartado ampliaremos en profundidad este tema y veremos qué ventajas nos puedellegar a suponer el uso de este sistema en nuestras aplicaciones. También diseñaremosuna aplicación desde cero que implemente iCloud.

    Por otro lado hablaremos de las notificaciones push, las cuales podemos hacer uso en lasaplicaciones que desarrollemos para determinados casos y que, sin duda, ofrecerán unpunto a favor en cuanto a mejora en la experiencia del usuario y sobre todo, un granavance en temas de marketing. De las notificaciones push hablaremos en el segundoapartado de esta sesión y veremos también cómo implementarlas en nuestras aplicaciones.

    ¡Comenzamos!

    3.1. iCloud

    Seguro que en algún momento has oído hablar de iCloud, ya sea por la televisión, por laprensa escrita o por Internet, el caso es que desde Apple nos "venden" esta nuevacaracterística de iOS 5 como algo menos que "el mayor avance de todos los tiempos".Pero en realidad, ¿Qué supone para nosotros, los desarrolladores esta nuevafuncionalidad? A continuación explicaremos en qué casos podremos implementarla,cuales son los requerimientos y un ejemplo concreto desarrollado desde cero con el quepodremos comprobar cómo funciona iCloud en un entorno real. ¡Vamos para allá!

    3.1.1. Definición y características de iCloud

    iCloud es una nueva funcionalidad disponible a partir de iOS 5 en la que, mediante el usode una API, podremos almacenar todo tipo de documentos y propiedades de nuestrasaplicaciones en la nube. Todas las actualizaciones que se produzcan en iCloud setransmitirá de forma inalámbrica, automática y sincronizada a cualquier dispositivo que lo

    Servicios y herramientas en iOS

    45Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • soporte (iDevice con iOS 5 ó PC/Mac debidamente configurados).

    iCloud

    Cada usuario dispondrá de una cuenta que tendrá que configurar en su dispositivo y queserá normalmente la misma que iTunes. La configuración de iCloud en los dispositivoscon iOS se realiza desde la aplicación de Ajustes, dentro del apartado iCloud. Ahideberemos especificar nuestro nombre de usuario y contraseña en el caso quedispongamos de ello, sino deberemos de crear un nuevo usuario.

    El almacenamiento de iCloud es un conjunto de interfaces diseñadas para compartir datosa través de distintas instancias de la aplicación en distintos dispositivos. Los cambios quese realicen en estos datos se propagrán automáticamente por los distintos dispositivos queejecuten la misma aplicación. Entre los grandes beneficios que esto ofrece a losdesarrolladores están:

    • Ya no hará falta en la mayoría de casos contratar un servicio externo que haga lasfunciones de servidor ya que usaremos el propio de Apple ahorrando, por tantomuchisimos costes adicionales.

    • No hará falta escribir una API propia para el acceso a datos externos ya que la propiade iCloud nos ofrece todo lo que necesitamos tanto para la recepción de documentos

    Servicios y herramientas en iOS

    46Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • desde iCloud como para el envio. También existen varios métodos referentes a lasincronización de los datos para evitar inconsistencias, algo que trataremos en lossiguientes puntos.

    Existen también una serie de condiciones que deberemos de tener en cuenta a la hora deincorporar este servicio en nuestras aplicaciones:

    • Límite de capacidad: Cada usuario tiene como máximo en principio 5GB dealmacenamiento en su cuenta iCloud gratuita a repartir entre todas las aplicacionesque utilicen este servicio. En el caso que contrate una cuenta premium (de pago) estelímite se aumentará hasta llegar a los 50GB. Los desarrolladores tendremos que teneren cuenta este límite y optimizar en la medida de lo posible los datos y/o documentosque nuestra aplicación comparta en la nube.

    • Sincronizaciones: Las posibles incoherencias o conflictos que puedan aparecer ennuestra aplicación las debemos de gestionar nosotros de forma manual. La API deiCloud nos proporciona una serie de métodos que nos ayudan a esta gestión perodebemos ser nosotros mismos los que la implementemos en nuestras aplicaciones.

    • Autorizaciones (entitlements) necesarios: Para que iCloud funcione deberemos deconfigurar previamente dentro del portal de desarrollador las autorizacionesnecesarias y activar el servicio de iCloud para la aplicación que desarrollemos. Estodeberemos hacerlo también desde la configuración del proyecto en XCode, aunque lodetallaremos más adelante en el ejemplo que realicemos desde cero.

    • Funcionamiento sin iCloud: Nuestra aplicación deberá funcionar correctamente enel caso de que iCloud no esté configurado en el dispositivo en donde se estéejecutando. iCloud se debe tratar como una funcionalidad "extra" y nunca como"necesaria" para el funcionamiento correcto de nuestra aplicación, es por ello quedeberemos de comprobar en nuestro código si el usuario dispone de una cuenta deiCloud configurada en el dispositivo y en el caso de que no sea así no utilizaremosiCloud pero sí el resto de funcionalidades.

    Apple ha establecido dos formas de incorporar iCloud a nuestras aplicaciones, las cualesdeberemos de tener en cuenta a la hora de implementarlo, son estas:

    • Almacenamiento de documentos: Esta característica la utilizaremos para almacenardocumentos (ficheros) de distintos tipos en la cuenta iCloud. No existe límite dealmacenamiento (el máximo disponible en la cuenta del usuario).

    • Almacenamiento de datos tipo clave-valor: La utilizaremos para almacenarpequeñas cantidades de datos como configuraciones del usuario, datos de acceso a laaplicación, etc. El límite máximo de almacenamiento está en 64KB.

    Servicios y herramientas en iOS

    47Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • iCloud

    3.1.2. Ejemplos de casos de uso de iCloud

    iCloud es una funcionalidad que se puede incorporar en gran parte de las aplicaciones iOSque vemos en la actualidad, sin embargo hay muchas otras en la que su implementaciónno sería un acierto o simplemente no aportaría nada o casi nada a la mejora de laexperiencia de usuario. A continuación comentaremos distintos tipos de aplicaciones endonde iCloud puede ser de utilidad:

    • Aplicaciones de gestión documental: Para compartir documentos entre variosdispositivos.

    • Aplicaciones de fotografía: Para compartir fotografias que hagamos con el iPhone /iPad entre varios dispositivos.

    • Aplicaciones que hagan uso de un calendario: Compartir eventos del calendario.• Aplicaciones de gestión de tareas (ToDos): Compartir tareas entre varios

    dispositivos.• Aplicaciones con apartados de configuración: Compartir datos de la configuración

    de una aplicación entre dispositivos.• Juegos de distintos tipos: Compartir datos de niveles alcanzados, puntuaciones, etc.

    Como podemos ver existen muchos tipos de aplicaciones en la que usar el servicio deiCloud puede llegar a ser un acierto. A continuación veremos cómo implementar dichoservicio en nuestras aplicaciones iOS mediante un sencillo ejemplo.

    3.1.3. Desarrollando con iCloud: Preparaciones iniciales

    Una vez vistas las características principales del uso de iCloud así como distintosejemplos de uso vamos a desarrollar desde cero nuestra primera aplicación con iCloud.En el ejemplo que vamos a comentar implementaremos una sencilla aplicación en la queel usuario creará un documento de texto simple y este se gestionará a través de iCloud.

    Servicios y herramientas en iOS

    48Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • También almacenaremos los datos de acceso a la aplicación en la nube. Como se puedededucir, haremos uso de los dos métodos de almacenamiento comentados en el primerpunto: almacenamiento de documentos y almacenamiento de datos tipo clave-valor.

    Para empezar a desarrollar en iCloud deberemos de configurar previamente una serie dedatos y opciones en nuestra cuenta de desarrollador (http://developer.apple.com).Comenzaremos configurando una nueva aplicación, para ello deberemos acceder a portalde desarrolladores (http://developer.apple.com) utilizando nuestro nombre de usuario ycontraseña. Una vez dentro accederemos al Provisioning Portal y crearemos un nuevoApp ID que llamaremos, por ejemplo, ua.es.jtech.ejemploicloud.

    AtenciónTenemos que tener en cuenta que el App ID que creemos debe de coincidir plenamente con elBundle identifier que tendrá la aplicación que creemos posteriormente en XCode.

    Una vez creado el App ID nos aparecerá en la lista del Provisioning Portal tal y comoaparece en la imagen siguiente:

    Provisioning Portal: iCloud

    Como podemos ver, iCloud no está configurado aún, para configurarlo deberemos pulsarsobre configure. En la ventana que nos aparece marcamos para activar iCloud tal ycomo aparece en la imagen de a continuación:

    Servicios y herramientas en iOS

    49Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

    http://developer.apple.comhttp://developer.apple.com

  • Configuración app con iCloud

    Ahora abrimos la pestaña de Provisioning y creamos un nuevo provisioningprofile para la aplicación que contenga el App ID creado anteriormente, el certificadoque queramos usar y los dispositivos con los que queramos probar la aplicación. Ahoranos descargamos el provisioning profile que acabamos de crear y haremos doble clicksobre el para adjuntarlo a nuestra lista en XCode.

    Pruebas de iCloudPara poder probar iCloud deberemos de disponer de un dispositivo (iPhone , iPad o iPod Touch)debidamente configurado desde el provisioning portal y con iOS 5 instalado. iCloud nofuncionará en el simulador de XCode.

    Una vez que tenemos todos los preparativos previos para usar iCloud ya podemosempezar a programar nuestra aplicación.

    3.1.4. Desarrollando con iCloud: Configuración del proyecto

    En este apartado comprobaremos lo sencillo que es hacer una aplicación compatible coniCloud. Comenzaremos abriendo XCode y creando un nuevo proyecto de tipo SingleView Aplication que será Universal, que llamaremos ejemploicloud y tendrá comoCompany Identifier: ua.es.jtech. Pulsamos sobre Next y ya tenemos el proyecto deXCode creado.

    Configuración proyecto XCode

    Servicios y herramientas en iOS

    50Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • Abrimos las propiedades del proyecto y nos dirigimos al apartado de Entitlements quese encuentra dentro de la pestaña de Summary, en el último apartado. Ahi marcamos lacasilla de Enable Entitlements. Automáticamente nos aparecerá un nuevo archivo enel raiz del proyecto que se llamará ejemploidcloud.entitlements. Ahora deberemosmodificar los campos de iCloud Key-Value Store y iCloud Containers con elTeam-ID de los provisioning profile que hemos creado anteriormente. Para ver elTeam-ID debemos acceder de nuevo a la sección de Apps IDs del iOS Provisioning Portaly copiar la cadena de texto que aparece justo antes del nombre del profile, en nuestro casoes: 3S952AGH46.

    Ahora editamos los tres campos del apartado Entitlements del resumen del proyectoquedando de la siguiente manera:

    Entitlements

    Con esto último ya tenemos el proyecto debidamente configurado para usar iCloud.Ahora deberemos de implementarlo en nuestro código, ¡vamos a ello!

    3.1.5. Desarrollando con iCloud: Programación de ficheros

    Comenzaremos programando la gestión de documentos en iCloud, para ello deberemos decrear una clase que herede de UIDocument la cual personalizaremos e implementaremostoda la gestión dentro del AppDelegate. En la vista crearemos un cambo de tipoTextView que será el que contenga el texto que almacenaremos o cargaremos (segúnconvenga) en el fichero que creemos dentro del almacenamiento iCloud.

    NotaRealizar toda la implementación básica de gestión de iCloud del modelo dentro de la claseAppDelegate no es lo recomendado ya que no se cumpliría de forma estricta la estructuraMVC propuesta por Apple. Nosotros lo hemos realizado de esa manera para simplificar elejemplo.

    Comenzamos creando la clase que gestionará el documento de iCloud, para ello hacemosclick sobre New > New File, seleccionamos Objective-C class y lo llamamos

    Servicios y herramientas en iOS

    51Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • MiDocumento. Dentro del fichero MiDocumento.h escribimos lo siguiente:

    #import #import

    @interface MiDocumento : UIDocument {NSString *documentText;id delegate;

    }

    @property (nonatomic, retain) NSString *documentText;@property (nonatomic, assign) id delegate;

    @end

    Y en el fichero MiDocumento.m lo siguiente:

    #import "MiDocumento.h"

    @implementation MiDocumento

    @synthesize documentText = _text;@synthesize delegate = _delegate;

    // ** LECTURA **

    - (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeNameerror:(NSError **)outError{

    NSLog(@"UIDocument: loadFromContents: state = %d, typeName=%@",self.documentState, typeName);

    if ([contents length] > 0) {self.documentText = [[NSString alloc] initWithBytes:[contents

    bytes]length:[contents length] encoding:NSUTF8StringEncoding];

    }else {

    self.documentText = @"";}

    NSLog(@"UIDocument: Se ha cargado el siguiente texto desde iCloud:%@",

    self.documentText);

    return YES;

    }

    // ** ESCRITURA **

    -(id)contentsForType:(NSString *)typeNameerror:(NSError **)outError{

    if ([self.documentText length] == 0) {self.documentText = @"Nueva nota para el curso especialista de

    moviles";}

    Servicios y herramientas en iOS

    52Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • NSLog(@"UIDocument: Guardare el siguiente texto en iCloud: %@",self.documentText);

    return [NSData dataWithBytes:[self.documentText UTF8String]length:[self.documentText length]];

    }@end

    Como podemos ver, la clase MiDocumento hereda de UIDocument, una nueva clasedisponible en iOS 5, este tipo se encargará de encapsular todos los datos referidos a undocumento de texto convencional. En iCloud deberemos usar esta clase para gestionar losdocumentos que creemos. Dentro de nuestra clase MiDocumento hemos sobreescrito lapropiedad de text y la delegate. Ahora la propiedad documentText será la quecontenga el texto.

    Hemos sobreescrito dos métodos de la clase UIDocument:

    • loadFromContents: Realiza la lectura del documento. Convierte los datos recibidos enbytes a una cadena de texto NSString codificada en UTF8, la cual almacenaremosdentro de la propiedad documentText.

    • contentsForType: Realiza la escritura en el documento. Devuelve en forma de datosNSData la cadena de texto convertida a UTF8.

    Ahora abrimos el fichero AppDelegate.h y creamos las siguientes propiedades ymétodos al final de este. Estos métodos se explicarán más adelante:

    @property (strong, nonatomic) UIWindow *window;@property (strong, nonatomic) NSMetadataQuery *query;@property (strong, nonatomic) MiDocumento *documento;

    - (void)cargaDocumento;-(void) escribeEnDocumento:(NSString *)texto;

    Abrimos el AppDelegate y añadimos el siguiente código dentro del métododidFinishLaunchingWithOptions:

    // (1) Iniciamos iCloudNSURL *ubiq = [[NSFileManager defaultManager]

    URLForUbiquityContainerIdentifier:@"3S952AGH46.ua.es.jtech.ejemploicloud"];if (ubiq) {

    NSLog(@"AppDelegate: Entra en iCloud!");[self cargaDocumento];

    } else {NSLog(@"AppDelegate: No hay acceso a iCloud (puede que estés en elsimulador o que no esté configurado correctamente el

    dispositivo");}

    El el fragmento de código anterior generamos la dirección del contenedor de iCloudcorrespondiente al identificador de nuestra aplicación mediante el método

    Servicios y herramientas en iOS

    53Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • URLForUbiquityContainerIdentifier del singleton NSFileManager. En el caso queencuentre esa dirección de iCloud pasamos a cargar el documento, en caso contrariosignificará o que no existe ese contenedor de iCloud o que no podamos acceder a el porcualquier otro motivo (no disponemos de conexión a internet, estamos probando elproyecto sobre el simulador o que el dispositivo no esté bien configurado para aceptariCloud).

    Ahora creamos el método cargaDocumento que será el encargado de hacer la llamada aiCloud para comprobar que existe el fichero que queremos cargar, en nuestro caso serátext.txt:

    - (void)cargaDocumento {

    // (2) iCloud query: Busca a ver si hay un fichero llamado "text.txt"en iCloud.

    NSMetadataQuery *query = [[NSMetadataQuery alloc] init];_query = query;

    //Asignamos el scope[query setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];

    //Creamos un predicado y lo asignamos a la queryNSPredicate *pred = [NSPredicate predicateWithFormat: @"%K == %@",NSMetadataItemFSNameKey, @"text.txt"];[query setPredicate:pred];

    //Creamos una notificacion que se llame cuando la query haya terminado// (esta se ejecutará en segundo plano de forma asincrona)[[NSNotificationCenter defaultCenter] addObserver:selfselector:@selector(queryDidFinishGathering:)name:NSMetadataQueryDidFinishGatheringNotification object:query];[query startQuery];

    }

    - (void)queryDidFinishGathering:(NSNotification *)notification {

    // (3) Si la query ha terminado cargaremos los resultados de esta enel

    // siguiente metodo: cargaQuery

    NSMetadataQuery *query = [notification object];[query disableUpdates];[query stopQuery];

    [self cargaQuery:query];

    [[NSNotificationCenter defaultCenter] removeObserver:selfname:NSMetadataQueryDidFinishGatheringNotification object:query];_query = nil; // ya no lo necesitaremos mas

    }

    Ahora nos falta implementar el método encargado de gestionar la consistencia deldocumento. Comprobaremos que si existe dicho documento (la query devuelve unresultado) lo cargaremos en el campo de texto de la vista (esta la crearemos en el

    Servicios y herramientas en iOS

    54Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • siguiente paso). En el caso de que la query no devuelva ningún resultado crearemos unnuevo documento y lo almacenaremos en iCloud. Para hacer esto crearemos el siguientemétodo:

    - (void)cargaQuery:(NSMetadataQuery *)query {

    // (4) cargaQuery: Si el fichero existe lo abrimos y se lo asignamosal documento

    //de la clase. En caso contrario lo creamos, lo asignamos al documentode la clase.

    if ([query resultCount] == 1) {// Encontrado el archivo en iCloud

    NSMetadataItem *item = [query resultAtIndex:0];NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];

    MiDocumento *doc = [[MiDocumento alloc] initWithFileURL:url];_documento = doc;

    [doc openWithCompletionHandler:^(BOOL success) {if (success) {

    NSLog(@"AppDelegate: Abriendo documento existente deiCloud");

    NSLog(@"El documento contiene el texto: %@",doc.documentText);

    [[NSNotificationCenter defaultCenter]postNotificationName:@"cargaTextoiCloud"object:nil];

    } else {NSLog(@"AppDelegate: El documente existente en iCloud hafallado al abrirse");

    }}];

    } else {

    // No existe el documento en iCloud: lo creamos

    NSLog(@"AppDelegate: Documento no encontrado en iCloud");

    NSURL *ubiq = [[NSFileManager defaultManager]URLForUbiquityContainerIdentifier:@"639M4BK859.com.theclashsoft.icloudtest"];

    NSURL *ubiquitousPackage = [[ubiqURLByAppendingPathComponent:@"Documents"]

    URLByAppendingPathComponent:@"text.txt"];

    MiDocumento *doc = [[MiDocumento alloc]initWithFileURL:ubiquitousPackage];

    doc.documentText = @"Texto inicial del documento en iCloud...";

    _documento = doc;

    [doc saveToURL:[doc fileURL]forSaveOperation:UIDocumentSaveForCreating

    completionHandler:^(BOOL success) {NSLog(@"AppDelegate: new document save to iCloud");[doc openWithCompletionHandler:^(BOOL success) {

    NSLog(@"AppDelegate: Nuevo documento creado en iCloud");[[NSNotificationCenter defaultCenter]postNotificationName:@"cargaTextoiCloud" object:nil];

    Servicios y herramientas en iOS

    55Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • }];}];

    }

    }

    Como podemos ver en el método anterior enviamos un mensaje a una notificacióncargaTextoiCloud que aún no hemos definido, esta vamos a implementarla dentro de lavista ViewController:

    - (void)cargaTextoiCloud:(NSNotification *)notification {AppDelegate *delegate = [[UIApplication sharedApplication] delegate];self.textView.text = delegate.documento.documentText;

    }

    Ahora, dentro del fichero ViewController.m, en el método viewDidLoad definimos lanotificación que se usará para indicar que el fichero se ha cargado de iCloud y se puedemostrar su texto en el componente UITextView:

    - (void)viewDidLoad{

    [super viewDidLoad];// Do any additional setup after loading the view, typically from

    a nib.

    [[NSNotificationCenter defaultCenter] addObserver:selfselector:@selector(cargaTextoiCloud:) name:@"cargaTextoiCloud"

    object:nil];

    }

    En el fichero ViewController.h deberemos de crear un Outlet para el Text View y unAction para la acción del botón que guardará el nuevo fichero en iCloud.

    // Añadimos lo siguiente debajo de las definiciones@property (strong, nonatomic) IBOutlet UITextView *textView;

    -(IBAction)clickBoton:(id)sender;

    //Añadimos el @syntentize en ViewController.m@synthesize textView = _textView;

    //Creamos el siguiente método en ViewController.m que implementará laacción del botón-(IBAction)clickBoton:(id)sender {

    AppDelegate *delegate = [[UIApplication sharedApplication] delegate];[delegate escribeEnDocumento:self.textView.text];

    }

    Por último nos queda diseñar la vista, para ello abrimos el ficheroViewController_iPhone.xib y ViewController_iPad.xib y añadimos en ambos un

    Servicios y herramientas en iOS

    56Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • componente Text View y un Button. Nos queda enlazarlos con los Outlet de la clase yquedaría de la siguiente manera para iPhone:

    ViewController_iPhone.xib

    Servicios y herramientas en iOS

    57Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • Una vez hecho esto ya podemos ejecutar nuestra aplicación sin antes acordarnos deestablecer los provisioning profiles adecuados en la pestaña de summary del proyectopara poder arrancarla en nuestros dispositivos.

    3.1.6. Desarrollando con iCloud: Pruebas de funcionamiento de ficheros

    Las pruebas se deberian de hacer en varios dispositivos ejecutando la aplicación en estospara comprobar que iCloud funciona correctamente. Deberemos de comprobar que eldocumento recién creado se actualiza de forma automática en nuestros dispositivos.También podemos comprobar que dentro de los ajustes de iCloud del dispositivo apareceel fichero creado text.txt.

    La primera vez que arrancamos la aplicación nos debe de aparecer lo siguiente en laconsola de XCode:

    2011-11-02 13:22:01.644 icloudtest[3733:707] AppDelegate: Entra eniCloud!2011-11-02 13:22:02.255 icloudtest[3733:707] AppDelegate: Documento noencontrado eniCloud2011-11-02 13:22:02.419 icloudtest[3733:707] UIDocument: Guardare elsiguiente texto eniCloud: Texto inicial del documento en iCloud...[Switching to process 8195 thread 0x2003]2011-11-02 13:22:02.799 icloudtest[3733:707] AppDelegate: Nuevo documentocreado eniCloud2011-11-02 13:22:03.329 icloudtest[3733:707] UIDocument: loadFromContents:state = 0,typeName=public.plain-text2011-11-02 13:22:03.330 icloudtest[3733:707] UIDocument: Se ha cargado elsiguientetexto desdeiCloud: Nueva nota para el curso especialista de moviles2011-11-02 13:22:03.352 icloudtest[3733:707] AppDelegate: Abriendodocumento existentede iCloud

    Como podemos ver, al arrancar la aplicación por primera vez no se encuentra ningúndocumento en iCloud por lo que se crea uno y se muestra el contenido en el TextView.

    Si ahora borramos la aplicación del dispositivo y la volvemos a ejecutar deberá deencontrar el fichero de iCloud y cargar su contenido en el Text View. Aparecerá algosimilar a lo siguiente en la consola de XCode:

    2011-11-02 13:30:54.149 icloudtest[3766:707] AppDelegate: Entra eniCloud!2011-11-02 13:31:11.424 icloudtest[3766:707] UIDocument: loadFromContents:state = 1,typeName=public.plain-text2011-11-02 13:31:11.425 icloudtest[3766:707] UIDocument: Se ha cargado elsiguientetexto desde iCloud: Nueva nota para el curso especialista de moviles

    Servicios y herramientas en iOS

    58Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • [Switching to process 8451 thread 0x2103]2011-11-02 13:31:11.755 icloudtest[3766:707] AppDelegate: Abriendodocumento existentede iCloud2011-11-02 13:31:11.756 icloudtest[3766:707] El documento contiene eltexto: Nueva notapara el curso especialista de moviles

    Como podemos ver se ha cargado el documento generado desde iCloud de maneracorrecta. Para modificar el texto del documento simplemente deberemos escribirlo dentrodel Text View y pulsar sobre el botón Enviar a iCloud, si hacemos la prueba escribiendoel siguiente texto: Cambiando el texto del documento text.txt en iCloud...veremos que aparece lo siguiente en la consola:

    2011-11-02 13:34:11.999 icloudtest[3766:707] UIDocument: Guardare el siguiente textoen iCloud: Cambiando el texto del documento text.txt en iCloud... 2011-11-0213:34:12.079 icloudtest[3766:707] AppDelegate: Nuevo documento creado en iCloud2011-11-02 13:34:12.606 icloudtest[3766:707] UIDocument: loadFromContents: state =0, typeName=public.plain-text 2011-11-02 13:34:12.607 icloudtest[3766:707]UIDocument: Se ha cargado el siguiente texto desde iCloud: Cambiando el texto deldocumento text.txt en iCloud... 2011-11-02 13:34:12.629 icloudtest[3766:707]AppDelegate: Abriendo documento existente de iCloud

    Ahora podemos seguir realizando pruebas en distintos dispositivos seguir observando elproceso que realiza iCloud.

    3.1.7. Desarrollando con iCloud: Programación de clave-valor

    La implementación de iCloud para su uso en el modo clave-valor es mucho mássencillo que para ficheros. Lo único que debemos hacer es modificar el código dentro dela inicialización de iCloud del método didFinishLaunchingWithOptions de la claseAppDelegate:

    // Iniciamos iCloudNSURL *ubiq = [[NSFileManager defaultManager]

    URLForUbiquityContainerIdentifier:@"639M4BK859.com.theclashsoft.icloudtest"];if (ubiq) {

    NSLog(@"AppDelegate: iCloud access!");

    // inicio clave-valorNSUbiquitousKeyValueStore *cloudStore = [NSUbiquitousKeyValueStore

    defaultStore];[cloudStore setString:[ubiq absoluteString] forKey:@"iCloudURL"];[cloudStore synchronize]; // Sincroniza los datos locales con los

    de iCloud

    NSLog(@"Valor encontrado en iCloud: %@",[cloudStorestringForKey:@"iCloudURL"]);

    // fin de clave-valor

    [self cargaDocumento];} else {

    Servicios y herramientas en iOS

    59Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • NSLog(@"AppDelegate: No iCloud access (either you are usingsimulator or,

    if you are on your phone, you should check settings");}

    Como podemos ver, el método clave-valor de iCloud es muy similar usarNSUserDefaults para persistencia de datos dentro de un mismo dispositivo. En iCloud sealmacena un diccionario con todos los datos clave-valor que deseemos. En este casoúnicamente almacenamos una clave llamada iCloudURL que contendrá la dirección URLde almacenamiento de iCloud.

    Este método es muy útil para almacenar propiedades, configuraciones, datos de usuario,etc en la nube y tener acceso de este modo en todos nuestros dispositivos de manerainstantánea. Comentar que además de poder almacenar valores de tipo String se puedenalmacenar de otros tipos como numéricos e incluso objetos completos.

    3.2. Notificaciones push

    Las aplicaciones iOS no pueden realizar (o no deben al menos) muchos de sus procesosen segundo plano por cuestiones de bateria. Sabiendo esto, ¿cómo podemos hacer paraavisar al usuario de que algo interesante está sucediendo? Por ejemplo, imaginemonosque un usuario se descarga una aplicación de una bliblioteca en un momento dado y unmes después sale un libro a la venta que le puede interesar... ¿cómo podemos avisar a eseusuario que el libro x le puede interesar? Ahi es donde entran en acción las famosasnotificaciones push.

    Servicios y herramientas en iOS

    60Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • Notificación Push

    Para evitar tener uno o varios procesos corriendo en nuestro dispositivo que esténcomprobando cada cierto tiempo si algún evento aparece Apple ha creado lasnotificaciones push. Estas notificaciones necesitarán de una configuración en un servidorque correrá por nuestra cuenta y por muy poca programación en la aplicación.

    Servicios y herramientas en iOS

    61Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • Las notificaciones push pueden enviar los siguientes tipos de mensaje o una combinaciónde estos:

    • Mensajes de texto cortos• Reproducir un sonido• Mostrar un número en el icono de la aplicación (badge)

    Podremos enviar por ejemplo un mensaje de texto junto con un sonido para conseguir unamayor atención del usuario.

    Las notificaciones push son un muy buen método para realizar campañas de marketing yaque podremos avisar a todos nuestros usuarios de algún evento o producto en cualquiermomento y sin resultar ser demasiado intrusivos. Además todas las notificaciones quenuestros usuarios reciban tendrán la opción de ejecutar la aplicación en el caso de queesta se encuentre en segundo plano o cerrada. Conviene tener en cuenta que el usodesmesurado de notificaciones push por parte del desarrollador puede provocar el efectocontrario, que el usuario se borre la aplicación del dispositivo para dejar de recibir estetipo de avisos.

    3.2.1. Funcionamiento

    Como hemos comentado anteriormente, el uso de notificaciones push en nuestrasaplicaciones implica que tengamos que configurar un servidor que sea el que envie estasnotificaciones mediante mensajes con formato JSON al servidor de notificaciones deApple (APNS Server). Este servidor de Apple será el que envie la notificación aldispositivo del usuario. En el siguiente gráfico podemos ver cómo funciona el servicio denotificaciones push de una manera más clara:

    Servicios y herramientas en iOS

    62Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • Esquema funcionamiento push

    • 1. Registramos el ID del dispositivo en nuestro servidor. Al usuario le aparecerá unaventana de confirmación preguntando si desea que nuestra aplicación le puedaenviar notificaciones.

    • 2. Nuestro servidor almacenará el ID del dispositivo en una base de datos paraposteriormente usarlo para enviar notificaciones.

    • 3. Enviamos una notificación desde nuestro servidor al APNS (Servidor de Apple).Necesitaremos haber configurado previamente un certificado SSL junto con una claveprivada. La notificación será un mensaje con estructura JSON.

    • 4. El APNS enviará la notificación al usuario del dispositivo.

    Cuando el usuario recibe la notificación se mostrará una alerta, desde la cual podrá abrirla aplicación (importante tener en cuenta para temas de marketing). Las notificacionespush se mostrarán al usuario aunque la aplicación esté apagada o incluso el dispositivo enreposo.

    ¿Qué necesitaremos para poder implementar este sistema en mis aplicaciones?Necesitaremos lo siguiente:

    • Un dispositivo (iPhone o iPad). Las notificaciones push en el simulador de XCode nofuncionan.

    • Una cuenta activa de desarrollador Apple. Necesitaremos crear un App ID en el portalde Apple Developer y configurar las notificaciones push para este App ID. Tambiéntendremos que generar un certificado SSL especial.

    Servicios y herramientas en iOS

    63Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • • Un servidor conectado a Internet. Será en encargado de enviar las notificaciones pushal servidor de Apple (APNS). Problema: el servidor tendrá que ser capaz de ejecutarprocesos en segundo plano, instalar certificados SSL y hacer conexiones TLS aciertos puertos, por lo que necesitaremos contratar un servidor privado (VPS) o buscarsoluciones alternativas de pago.

    El tercer requerimiento es algo complicado de solucionar ya que necesitaríamos contratarun servidor privado virtual o, en cualquier caso, implementarlo nosotros configurandouna serie de procesos, instalar un certificado, etc. Para simplificar este punto vamos a usarun servicio online complementario el cual nos proporcionará todo lo necesario paraincoporar notificaciones push a nuestras aplicaciones sin preocuparnos por el servidor:Urban Airship (http://urbanairship.com/).

    Urban Airship es un sitio online para desarrolladores de plataformas móviles (iOS,Android, Blackberry, etc) que ofrece distintos servicios para estas plataformas entre losque se encuentran el de notificaciones push e in-apps entre otros. El servicio denotificaciones push es bastante bueno y funciona muy bien. Empresas como Fox,Accenture, Macworld, Tapulous, Warner Bros o Yahoo lo utilizan en sus aplicaciones.

    Urban Airship

    Urban Airship ofrece distintas tarifas según nuestras necesidades. Por suerte disponen deuna tarifa gratuita con limitaciones, nosotros escogeremos esa tarifa para realizar unaaplicación de ejemplo.

    3.2.2. Registro en Urban Airship y configuración en iOS Provisioning Portal

    Antes de empezar a implementar nuestra aplicación de ejemplo vamos a registrarnos en el

    Servicios y herramientas en iOS

    64Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

    http://urbanairship.com/

  • site de Urban Airship, para ello abrimos un navegador y entramos enhttps://go.urbanairship.com/accounts/register/. Una vez dentro deberemos rellenar todoslos campos del formulario para abrir una cuenta básica (gratuita) la cual nos permitiráenviar hasta un millón de mensajes push al mes (después veremos algunas limitaciones).

    Una vez que nos hayamos registrado y confirmado la cuenta podremos acceder al panelde control desde donde podremos revisar todos los datos de nuestra cuenta, el tipo decuenta (básica), el número de mensajes push enviados en total, etc. Ahora deberemoscrear una nueva app, pero antes tendremos que generar el certificado SSL de Apple quepermitirá a Urban Airship enviar las notificaciones push a los dispositivos.

    Datos app en Urban Airship

    Para crear el certificado SSL de Apple accederemos al portal de desarrolladores usandonuestro nombre de usuario y contraseña.(https://developer.apple.com/ios/manage/overview/index.action). Una vez dentro abrimosla pestaña de Apps IDs y crearemos una nueva App ID para la aplicación de ejemplo quevamos a desarrollar. Completaremos el formulario con los datos que se muestran en lasiguiente captura:

    Servicios y herramientas en iOS

    65Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

    https://go.urbanairship.com/accounts/register/https://developer.apple.com/ios/manage/overview/index.action

  • Create App ID

    Una vez creado el App ID lo configuramos para activar las notificaciones push, para ellopulsamos sobre el link de "configure" y marcamos la casilla Enable for Apple PushNotification service tal y como se muestra a continuación:

    Configuración para push

    Ahora pulsamos sobre el botón que pone Configure en el certificado SSL de desarrollo(Development Push SSL Certificate). Al pulsar sobre el botón nos aparecerá un

    Servicios y herramientas en iOS

    66Copyright © 2011-12 Dept. Ciencia de la Computación e IA All rights reserved.

  • asistente que tenemos que seguir para generar el certificado, el cual después utilizaremospara el servidor, o en nuestro caso, Urban Airship. Por tanto simplemente seguimos lospasos que nos indica el asistente...

    Certificado SSL

    Una vez que nos hayamos descargado el certificado SSL generado en el asistente(aps_development.cer) lo agregamos a nuestro llavero simplemente pulsando sobre el.Una vez hecho est