Intercomunicación de aplicaciones en IOS
0. Índice de contenidos.
1. Entorno
Este tutorial está escrito usando el siguiente entorno:
- Hardware: Portátil Mac Book Pro 17″ (2,6 Ghz Intel Core i7, 8 GB DDR3)
- Sistema Operativo: Mac OS X Snow Leopard 10.6.4
- Xcode 5.0.2
- InterAppComunication 1.0
2. Introducción
Algo que cada vez resulta más común en el desarrollo con IOS es la necesidad de que unas aplicaciones interactuen con otras
pasándose información. Esto en IOS se puede conseguir gracias a la especificación x-callback-url.
Cada día más aplicaciones en el Apple Store publican sus openUrls para que nuestras aplicaciones puedan interactuar con ellas. Aquí tenéis un web donde
podéis encontrar un listado actualizado con este tipo de aplicaciones: handleopenurl.com
Nosotros vamos a ver cómo se hace esta interacción con dos aplicaciones propias para que podáis ver todo el código necesario.
3. Vamos al lío
Vamos a crear dos aplicaciones sencillas basadas en el «HolaMundo» que vimos en este
tutorial. La primera de ellas
invocará a la segunda pasándole un texto que será mostrado por pantalla.
Para realizar la interacción nos vamos a basar en la librería InterAppCommunication que nos proporciona un API sencillo
para trabajar con el estándar x-callback-url.
La librería la podemos encontrar aquí y tenemos dos formas de
incorporarla a nuestros proyectos: copiando directamente los fuentes o vía CocoaPods; por simplicidad en este tutorial vamos a copiar
directamente los fuentes.
Ahora vamos a crear la aplicación que va a llamar a la otra pasándole el texto y que la vamos a conocer como «App1».
Creamos un nuevo proyecto llamado «App1» y creamos un ViewControler llamado «App1ViewController» con un xib donde vamos a añadir
un botón y un cuadro de texto donde poder introducir el texto que queremos transmitir a la otra aplicación. La pantalla quedaría así:
Creamos un «Action» para cuando pulsamos en el botón llamado «CallApp2Onclick» con el siguiente código:
- (IBAction)callApp2Onclick:(id)sender { BOOL canOpenURL = [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@://Test", @"app2"]]]; if (canOpenURL){ IACClient *client = [IACClient clientWithURLScheme:@"app2"]; [client performAction:@"pasarTexto" parameters:@{@"texto": textoAPasar.text} onSuccess:^(NSDictionary *resultParams){ NSLog(@"La app respondio: %@", resultParams); } onFailure:^(NSError *error){ NSLog(@"ERROR: %@", [error localizedDescription]); } ]; NSLog(@"Llamada a app2 realizada"); }else{ NSLog(@"App2 no está instalada en este dispositivo"); } }
Este código lo que hace es comprobar si se puede realizar la llamada a la otra aplicación. En caso contrario significa que la
otra aplicación no está presente en el dispositivo y por tanto mostramos un texto advirtiéndolo.
En caso de que si esté instalada la invocamos con la acción «pasarTexto» y el texto que escribimos que se mostrará por pantalla como
veremos un poco más adelante.
En este punto tenemos que conocer la URLScheme de la aplicación a la que queremos llamar, en nuestro caso va a ser «app2».
Ahora vamos a crear la «App2». Para ello creamos un nuevo proyecto llamado «App2». Una vez tenemos la estructura
del proyecto tenemos que añadir la configuración necesaria para exponer nuestro servicio de «pasarTexto». No olvidar copiar los fuentes
de la librería InterAppCommunication, como hicimos en la «App1».
Lo primero es definir el scheme de nuestra aplicación para que pueda ser localizada por la otra. Para ello abrimos el fichero
nombreAplicacion-Info.plist, en este caso, App2-Info.plist. En este fichero pulsamos con el botón derecho y seleccionamos «Add Row» y
«URL Types».
Rellenamos la información «Url Types» -> «Item 0» -> «URL identifier» con el texto que queramos aunque por convenio se suele
poner el mismo identicador que la aplicación, en nuestro caso, com.autentia.App2
Ahora desde «Url identifier» pulsamos en «+» añadiendo la opción «URL Schemes» y dándole el valor «app2» al item0, como se muestra
en la imagen:
Es muy importante que el nombre del item0 de «URL Schemes» coincida exactamente con el nombre que hemos establecido en el URLScheme
de la app1.
Ahora vamos implementar la interfaz con la que se va a conectar la app1. Editamos el fichero AppDelegate.m de la aplicación «App2»
añadiendo el siguiente método:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { return [[IACManager sharedManager] handleOpenURL:url]; }
Dentro del método didFinishLaunchingWithOptions vamos a establecer el URLScheme y el handle de la operación «pasarTexto».
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [IACManager sharedManager].callbackURLScheme = @"app2"; [[IACManager sharedManager] handleAction:@"pasarTexto" withBlock:^(NSDictionary *inputParameters, IACSuccessBlock success, IACFailureBlock failure) { App2ViewController *app2 = [[App2ViewController alloc] initWithNibName:@"App2ViewController" bundle:nil]; app2.texto = inputParameters[@"texto"]; self.window.rootViewController = app2; }]; self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; return YES; }
Llegados a este punto solo queda probar la interacción. Para ello tenemos que arrancar primero la app2 que mostrará inicialmente una
pantalla en blanco, paramos el simulador y arrancamos la app1.
Que mostrará esta pantalla:
Si todo es correcto al pulsar el botón de la pantalla de la app1 veremos como se carga la app2 con la pantalla que muestra el texto que le hemos pasado.
4. Conclusiones
Cada vez más los desarrolladores en IOS adoptan x-callback-url para dar soporte a otras aplicaciones, con este tutorial ya sabéis
como aprovechar la intercomunicación de aplicaciones en IOS.
Cualquier duda o sugerencia en la zona de comentarios.
Saludos.
Una duda, que pasa si 2 apps tienen el mismo x-callback-url?
Saludos
Hola diegoveloper,
En el caso que planteas supongo que el sistema eligirá la primera ocurrencia, aunque no te lo puedo garantizar porque no lo he probado. Por eso una buena práctica podría ser poner el id de la aplicación como schema url.
Saludos
Hola de nuevo,
Me ha picado la curiosidad y he hecho una pequeña prueba creando un proyecto app3 clon de app2 y el resultado ha sido que cuando app1 llama a app2 o a app3 de forma independiente, es decir, teniendo solo dos apps todo funciona correctamente. Pero cuando ejecutas la llamada desde la app1 estando las otras dos instaladas en el dispositivo siempre me abre app2 independientemente de cual se instaló antes en el dispositivo. Supongo que la solución puede ser la de hacer una pantalla de selección de una aplicación u otra, pero es algo que no te da por defecto.