sábado, 8 de octubre de 2016

Como crear una libreria con cocoapods

Creando una libreria con CocoaPods


Luego de terminar mi libreria JKAlertView decidí ajustarla para ser usada por cualquier persona de la manera mas fácil, a través del muy conocido gestor de librerías para iOS llamado cocoapods.

Commence leyendo la documentación directamente de la pagina oficial de cocoapods, pero me encontré con una serie largos de problemas de los cuales no halle solución en la documentación oficial.

Así es que después de varias horas de búsqueda en la web logre solucionarlos.

En esta guia se asume que tenemos un proyecto (.xcodeproj) ya creado con nuestra librería.


Importante: antes que nada debemos asegurarnos que tenemos instalado cocoa pods 1.1.0.rc-2. Para saber que version tenemos ejecutamos en una consola pod --verison. Si no tenemos esta version podemos desinstalarla e instalar la version indicada.

gem uninstall cocoapods
gem install cocoapods -v 1.1.0.rc-2


Creando tu repositorio privado para cocoapods

En este caso vamos a usar GitHub pero puedes usar cualquier otro servidor git.

Primero vamos a crear un repositorio que llamaremos MyLibSpecs



guardamos la dirección de nuestro repositorio donde publicaremos nuestro archivo .podspec git@github.com:kakashysen/MyLibSpecs.git

Ahora podemos agregar nuestro repositorio anteriormente crea a nuestro cocoapods privado.

pod repo add MyLibSpecs git@github.com:kakashysen/MyLibSpecs.git
con eso nos creara el repositorio dentro de ~/.cocoapods/repos/MyLibSpecs


Agregar podspec a nuestro proyecto


Dentro de nuestro proyecto Xcode en la raíz creamos nuestro archivo .podspec

pod spec create MyLib

receda que al usar pod spec create <Proyecto> debes crearlo con el nombre de tu libreria.

luego de ejecutar este comando se creara un nuevo archivo llamado MyLib.podspec el cual contiene la información necesaria para crear nuestro pod

puedes abrir este archivo con el comando open -a xcode MyLib.podspec, en este archivo severas ajustar los siguientes valores :


s.version debe ser el numero de version que tengas en tu proyecto, que corresponde al tag que este disponible o que hayas creado en GitHub.

s.description debes escribir una descripción de tu libreria esta descripción debe estar entre los textos <<-DESC   ....  DESC.

s.homepage debes indicar la url de tu repositorio en este caso estamos usando GitHub https://github.com/kakashysen/MyLib

s.license debes indicar la licencia que estas usando para tu proyecto e indicar el nombre del archivo que la contiene por ejemplo MIT

s.license = { :type => "MIT", :file => "LICENSE" }

s.source debes indicar el ubicación de tu repositorio en git https://github.com/kakashysen/MyLib.git

s.source_files indica el directorio donde se encuentran tus clases principales que serán publicadas dentro de tu librería.


guarda los cambios y antes de publicar este archivo en nuestro repositorio vamos a verificar que todo este bien en nuestro archivo .podspec

pod spec lint MyLib.podspec 
Debes revisar que todo esta ok, si genera algún tipo de error nos indicara donde esta el problema para que lo ajustemos y lo validemos nuevamente. 

Una vez validado podemos enviarlo a nuestro repositorio

pod repo push MyLibSpecs MyLib.podspec

con esto ya quedaria instalado en nuestro repositorio privado de cocoapods. 
para usarlo ya que esta local usamos dentro de nuestro Podfile lo siguiente 

pod 'MyLib', :path => '~/Documents/Libraries/MyLib'

si queremos publicarlo en el repositorio de cocoapods podemos ejecutar el siguiente comando 

pod trunk push MyLib.podspec

ya con esto podemos usarlo como cualquier otro pod

pod 'MyLib'


miércoles, 7 de septiembre de 2016

Localized info.plist

Tengo que revisar porque me esta saliendo el siguiente mensaje de error cuando envío la version de mi app a TestFlight "Invalid Siri Suport -No example provided for INGetRideStatusIntent in the en-CO language"....

He agregado las posibles traducciones a mi archivo de internacionalización de mi app pero esto no ha dado resultado tender que seguir revisando...

Creo que encontre la solución, debo agregar las traducciones dentro del archivo infoPlist.string, este es el archivo que maneja las internacionalización para cualquier testo dentro del archivo info.plist.

Lo anterior funciona unicamente para el archivo info.plist, para el archivo AppIntentVocabulary.plist debo crear la localización propia por medio del botón Localized que existen en el panel Inspector de Xcode, con esto agrego todos los lenguajes que necesito y asigno las posibles traducciones.


Solucionado! ^_^ 

martes, 6 de septiembre de 2016

iOS 10 - Integrando SiriKit

Integrando SiriKit



Inicie leyendo la documentación publicada en el sitio de desarrolladores de apple sobre SiriKit y me encontré con muchas dudas al respecto.


En el inicio explican que Siri funciona con un grupo restringido de domains (dominios) los cuales hace que Siri solo funcione para ciertos tipos de peticiones o integración con aplicaciones que funcionan de manera especifica.  Los únicos domains que están disponibles por el momento son los siguientes:

  • VoIP calling
  • Messaging
  • Payments
  • Photo
  • Workouts
  • Ride booking
  • CarPlay (automotive vendors only)
  • Restaurant reservations (requires additional support from Apple)

En este caso realicé la integración con el domain Ride booking.


Cada uno de estos domains utiliza el mismo flujo el cual esta definido en tres pasos, resolve, confirm y handle.

Primero tengo que crear un nuevo Target para Siri, afortunadamente la nueva version de Xcode soluciona el problema de forma automática de crear provisioning profiles y la firma de certificado de este nuevo Target lo cual me quita un problema de encima. 


Ahora debo configurar los Intents que soportare dentro de mi app, en este caso serán solo dos correspondientes al domain Ride booking que serán

Debo agregar estos dos Intent al archivo .plist de mi nuevo Target para Siri dentro del diccionario NSExtension->NSExtensionsAttributes->IntentsSupported

INRequestRideIntent -> con este puedo manejar las peticiones de solicitud de taxis
INGetRideStatusIntent -> con este manejare las consultas del estado de taxis

Ahora debo empezar con la implementación de la lógica necesaria para que mi app responda a las peticiones que llegue desde Siri


Cuando cree el nuevo Target para Siri se creo una clase llamada IntentHandler la cual es el punto de entrada de las peticiones.

Debo crear dos clases mas y redireccionar el flujo a cada una según corresponda, esto lo puedo hacer desde el método -(void)handlerForIntent: que tiene la clase IntentHandler.

La primera clase que voy a crear sera RequestRideBookingHandler la cual implementará los métodos necesarios del protocolo INRequestRideIntentHandling

Ahora necesitare implementar primero el método -(void)resolvePickupLocationForRequestRide: en este realizaré la validación de la posición del usuario también consultare el reverse geocode para obtener los datos de la dirección y pasarlos dentro del objeto CLPlacemark, en dado caso que no pueda obtener una ubicación del usuario valida tender que devolver uno de los posible resultados de error que me provee el api de SiriKit que seria [INPlacemarkResolutionResult needsValue].

Listo con esto ya tengo validad la primera parte de la petición (resolve), me he dado cuenta que este método se invoca cuando el usuario le pregunta a Siri "Pideme un auto con <App>".

por el momento no veo necesario utilizar la segunda parte del flujo que seria el "confirm".

Ahora si puedo empezar a implementar la parte de handle.  Para esto voy a implementar el método -(void)handleRequestRide: este método recibe un objeto de tipo INRequestRideIntent con el cual puedo obtener la posición de recogida del usuario por medio de la propiedad pickupLocation el cual es un objeto de tipo CLPlacemark al cual le agregue información sobre el reverse geocode en el método de resolve anteriormente.