<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>ZButton</title>
	<atom:link href="http://zbutton.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://zbutton.wordpress.com</link>
	<description>Technology and Development blog</description>
	<lastBuildDate>Sat, 21 Jan 2012 16:21:21 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='zbutton.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>ZButton</title>
		<link>http://zbutton.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://zbutton.wordpress.com/osd.xml" title="ZButton" />
	<atom:link rel='hub' href='http://zbutton.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Copiar la ruta del fichero seleccionado en Finder usando Ruby</title>
		<link>http://zbutton.wordpress.com/2011/09/11/copiar-la-ruta-del-fichero-seleccionado-en-finder-usando-ruby/</link>
		<comments>http://zbutton.wordpress.com/2011/09/11/copiar-la-ruta-del-fichero-seleccionado-en-finder-usando-ruby/#comments</comments>
		<pubDate>Sun, 11 Sep 2011 14:24:40 +0000</pubDate>
		<dc:creator>robjperez</dc:creator>
				<category><![CDATA[mac]]></category>
		<category><![CDATA[programacion]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[scriptingbridge]]></category>

		<guid isPermaLink="false">http://zbutton.wordpress.com/?p=544</guid>
		<description><![CDATA[Tras hablar sobre varios temas, en la última @nscoder_mad acabamos hablando del famoso lenguaje AppleScript. Personalmente es un lenguaje que he intentado varias veces aprender, pero nunca acaba de gustarme. Una de las conclusiones a las que llegamos es que es un lenguaje para no programadores. Quizás uno de los aspectos que no me gusta [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=zbutton.wordpress.com&amp;blog=8076436&amp;post=544&amp;subd=zbutton&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://zbutton.files.wordpress.com/2010/08/logo.png"><img src="http://zbutton.files.wordpress.com/2010/08/logo.png?w=150&#038;h=150" alt="" title="logo" width="150" height="150" class="alignleft size-medium wp-image-366" /></a>
<p style="text-align:justify;">Tras hablar sobre varios temas, en la última <a href="http://twitter.com/nscoder_mad" target="_blank">@nscoder_mad</a> acabamos hablando del famoso lenguaje AppleScript. Personalmente es un lenguaje que he intentado varias veces aprender, pero nunca acaba de gustarme. Una de las conclusiones a las que llegamos es que es un lenguaje para no programadores. Quizás uno de los aspectos que no me gusta del lenguaje es que no veo a primera vista los diferentes elementos que conforman el código escrito con otros lenguajes como por ejemplo las palabras reservadas o incluso las propias sentencias en si mismo.</p>
<p style="text-align:justify;">Un ejemplo de Applescript podría ser algo así:</p>
<p><pre class="brush: objc;">
tell application &quot;Finder&quot;
	set theFolder to make new folder at desktop
end tell
</pre></p>
<p style="text-align:justify;">Sin duda algo que no se puede negar es su &#8220;verbosidad&#8221;, cualquiera que lo lea, mas o menos sabe lo que hace este mini-script. Pero, desde mi punto de vista, aunque muy literario, no me resulta cómodo leer código escrito de esta manera.</p>
<p style="text-align:justify;">Pese a que a priori, puede parecer una opción muy asequible para gente que no ha programado en otros lenguajes, lo cierto es que incluso para ellos, crear algo nuevo en Applescript no es tan sencillo, en el fondo es un lenguaje de programación, y no entiende cualquier frase inglesa que podamos escribir.</p>
<p style="text-align:justify;">Sin duda uno de los grandes beneficios de Applescript es su integración dentro de OSX, y como es capaz de interactuar con el sistema y el resto de aplicaciones de una forma muy sencilla.</p>
<p style="text-align:justify;">De hecho, <a href="http://twitter.com/j4n0" target="_blank">@j4n0</a> me comentaba que el tenía un script para copiar al portapapeles la ruta del fichero seleccionado en la ventana del Finder, cosa que es bastante útil.</p>
<p style="text-align:justify;">Según lo expuesto hasta ahora, nuestra situación es que pese a que Applescript no parece un lenguaje muy atractivo pero es una &#8220;joya&#8221; a la hora de interactuar con el sistema operativo.</p>
<p style="text-align:justify;">Por suerte hay una alternativa, gracias al ScriptingBridge, y como hablamos <a href="http://zbutton.wordpress.com/2011/01/02/manejando-safari-desde-objetive-c/" target="_blank">aquí</a> y <a href="http://zbutton.wordpress.com/2010/04/28/otra-manera-de-programar-en-cocoa-ruby-y-python/" target="_blank">aquí</a>, podemos usar otros lenguajes de programación como Ruby o Python para acceder a los mismos recursos que Applescript.</p>
<p style="text-align:justify;">Actualmente mi situación es, me gustaría aprender Applescript por curiosidad, pero ¿para qué?. Lo mismo se puede hacer con Ruby, y es un lenguaje que ya conozco <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p style="text-align:justify;">Continuando con el caso anterior, el código en Ruby para copiar al portapapeles el fichero seleccionado en el Finder sería algo como:</p>
<p><pre class="brush: ruby;">
require 'osx/cocoa'
include OSX
OSX.require_framework 'ScriptingBridge'

finder = SBApplication.applicationWithBundleIdentifier_ &quot;com.apple.finder&quot;
fileURL = NSURL.URLWithString_ finder.selection.get[0].URL
system &quot;echo #{fileURL.path} | pbcopy&quot;
</pre></p>
<p style="text-align:justify;">Seguramente el código en Applescript ocupa menos lineas, pero al menos para mi, la versión en Ruby es mucho mas clara.</p>
<p style="text-align:justify;">Como breve resumen al código, con la función applicationWithBundleIdentifier_ obtenemos la referencia al objeto &#8220;Finder&#8221; y usando el comando de consola pbcopy introducimos los datos al clipboard.</p>
<p style="text-align:justify;">Pese a que funciona sin problemas desde la linea de comandos, este script es sobre todo útil cuando lo tenemos en la propia ventana del finder, para ello necesitamos encapsular el script en un bundle de Aplicación que OSX sepa como ejecutar.</p>
<p style="text-align:justify;">Para ello, y aunque podamos hacerlo a mano, existe una utilidad llamada <a href="http://www.sveinbjorn.org/platypus" target="_blank">Platypus</a> que nos automatizará el proceso. Una vez que tengamos el bundle solo nos queda arrastrarlo a la barra superior del finder y usarlo siempre que queramos.</p>
<p><a href="http://zbutton.files.wordpress.com/2011/09/screen-shot-2011-09-11-at-4-22-45-pm.png"><img src="http://zbutton.files.wordpress.com/2011/09/screen-shot-2011-09-11-at-4-22-45-pm.png?w=300&#038;h=167" alt="" title="Screen Shot 2011-09-11 at 4.22.45 PM" width="300" height="167" class="aligncenter size-medium wp-image-549" /></a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/zbutton.wordpress.com/544/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/zbutton.wordpress.com/544/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/zbutton.wordpress.com/544/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/zbutton.wordpress.com/544/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/zbutton.wordpress.com/544/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/zbutton.wordpress.com/544/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/zbutton.wordpress.com/544/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/zbutton.wordpress.com/544/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/zbutton.wordpress.com/544/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/zbutton.wordpress.com/544/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/zbutton.wordpress.com/544/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/zbutton.wordpress.com/544/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/zbutton.wordpress.com/544/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/zbutton.wordpress.com/544/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=zbutton.wordpress.com&amp;blog=8076436&amp;post=544&amp;subd=zbutton&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://zbutton.wordpress.com/2011/09/11/copiar-la-ruta-del-fichero-seleccionado-en-finder-usando-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b5e8b84400b6903e4436e0489905e051?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">robjperez</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2010/08/logo.png?w=299" medium="image">
			<media:title type="html">logo</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2011/09/screen-shot-2011-09-11-at-4-22-45-pm.png?w=300" medium="image">
			<media:title type="html">Screen Shot 2011-09-11 at 4.22.45 PM</media:title>
		</media:content>
	</item>
		<item>
		<title>Mandando SMS o Correos desde nuestra App</title>
		<link>http://zbutton.wordpress.com/2011/07/20/mandando-sms-o-correos-desde-nuestra-app/</link>
		<comments>http://zbutton.wordpress.com/2011/07/20/mandando-sms-o-correos-desde-nuestra-app/#comments</comments>
		<pubDate>Tue, 19 Jul 2011 22:36:27 +0000</pubDate>
		<dc:creator>robjperez</dc:creator>
				<category><![CDATA[iphone]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[programacion]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[messaging]]></category>

		<guid isPermaLink="false">http://zbutton.wordpress.com/?p=532</guid>
		<description><![CDATA[Seguramente en muchas ocasiones se nos habrá presentado la necesidad de mandar información desde nuestra aplicación al &#8220;exterior&#8221;. Para mandar esa información tenemos varias alternativas, sin duda una de las mas sencillas es utilizar los propios mecanismos del móvil para hacerlo. Estos mecanismos son básicamente dos, mandar un correo electrónico o mandar un mensaje corto. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=zbutton.wordpress.com&amp;blog=8076436&amp;post=532&amp;subd=zbutton&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://zbutton.files.wordpress.com/2011/04/mail.png"><img class="alignleft size-full wp-image-498" title="mail" src="http://zbutton.files.wordpress.com/2011/04/mail.png?w=450" alt=""   /></a></p>
<p style="text-align:justify;">Seguramente en muchas ocasiones se nos habrá presentado la necesidad de mandar información desde nuestra aplicación al &#8220;exterior&#8221;. Para mandar esa información tenemos varias alternativas, sin duda una de las mas sencillas es utilizar los propios mecanismos del móvil para hacerlo. Estos mecanismos son básicamente dos, mandar un correo electrónico o mandar un mensaje corto.</p>
<p style="text-align:justify;">iOS nos proporciona un framework para realizar esta tareas, el nombre es Message UI. Este framework, nos va a proporcionar ViewControllers que podremos invocar desde nuestra aplicación y de esta manera, enviar el mensaje de correo o SMS sin tener que abandonarla.</p>
<p style="text-align:justify;">Junto con los ViewControllers, el framework proporciona dos protocolos que representan los delegados de dichos controladores, de tal manera que podemos recibir información de como ha sido el proceso de envío.</p>
<p style="text-align:justify;">Las clases de los controladores son MFMailComposeViewController y MFMessageComposeViewController.</p>
<p style="text-align:justify;">Antes de empezar a experimentar con las clases, es importante que añadamos el framework a nuestro proyecto, ya que por defecto no lo tendremos. Para ello lo hacemos desde la siguiente ventana de XCode.</p>
<p><a href="http://zbutton.files.wordpress.com/2011/07/screen-shot-2011-07-19-at-23-48-02.png"><img class="aligncenter size-full wp-image-536" title="Add Framwork" src="http://zbutton.files.wordpress.com/2011/07/screen-shot-2011-07-19-at-23-48-02.png?w=450&#038;h=267" alt="" width="450" height="267" /></a></p>
<p style="text-align:justify;">Empezando por la del correo electrónico, la clase nos proporciona diversos métodos para prefijar los contenidos, como &#8220;setSubject:&#8221; &#8220;setToRecipients:&#8221; o &#8220;setMessageBody:isHTML:&#8221;. Pese a que al ser un viewcontroller cualquiera, podemos usar cualquier técnica para mostrarlo, se recomienda usar el mensaje &#8220;presentModalViewController:animated:&#8221; de UIViewController.</p>
<p style="text-align:justify;">Es importante notar que una vez que el controlador esta en primer plano, nuestra aplicación no puede cambiar el contenido del correo. Esto es así para prevenir aplicaciones &#8220;maliciosas&#8221; que podrían mostrar una cosa y luego enviar otra.</p>
<p style="text-align:justify;"><a href="http://zbutton.files.wordpress.com/2011/07/photo-1.png"><img class="aligncenter size-medium wp-image-538" title="Sending Mail" src="http://zbutton.files.wordpress.com/2011/07/photo-1.png?w=200&#038;h=300" alt="" width="200" height="300" /></a></p>
<p style="text-align:justify;">De esta manera el código para mostrar la pantalla de envío de correo seria:</p>
<p><pre class="brush: objc;">
MFMailComposeViewController *mailcontroller = [[MFMailComposeViewController alloc] init];
[mailcontroller setSubject:subjectText.text];
[mailcontroller setMessageBody:bodyText.text isHTML:NO];
mailcontroller.mailComposeDelegate = self;
[self presentModalViewController:mailcontroller animated:YES];
</pre></p>
<p style="text-align:justify;">Como vemos en el código, previamente tenemos que establecer una instancia como delegado del controlador, cuando el usuario interactue con el controlador, se nos enviara un mensaje del tipo: &#8220;mailComposeController:didFinishWithResult:error:&#8221;. Este paso es importante pues nosotros somos los encargados de ocultar el viewcontroller cuando el usuario haya acabado, y esto lo hacemos llamando a &#8220;dismissModalViewControllerAnimated:&#8221; en el código del delegado.</p>
<p><pre class="brush: objc;">
- (void)mailComposeController:(MFMailComposeViewController *)controller
          didFinishWithResult:(MFMailComposeResult)result
                        error:(NSError *)error
{
    [controller dismissModalViewControllerAnimated:YES];
}
</pre></p>
<p style="text-align:justify;">El caso del controlador de mensajes cortos es muy similar al del correo. La clase es MFMessageComposeViewController, y las propiedades que controlan el contenido son &#8220;recipients&#8221; y &#8220;body&#8221;, de la misma manera el controlador se muestra con el mensaje &#8220;presetModalViewController:animated&#8221; y el delegado, en este caso una clase que implemente el protocolo &#8220;MFMessageComposeViewControllerDelegate&#8221; y el método &#8220;messageComposeViewController:didFinishWithResult:&#8221; deberá ocultar el controlador una vez que el mensaje haya sido enviado.</p>
<p style="text-align:justify;"><a href="http://zbutton.files.wordpress.com/2011/07/photo.png"><img class="aligncenter size-medium wp-image-539" title="Sending SMS" src="http://zbutton.files.wordpress.com/2011/07/photo.png?w=200&#038;h=300" alt="" width="200" height="300" /></a></p>
<p><pre class="brush: objc;">
MFMessageComposeViewController *smscontroller = [[MFMessageComposeViewController alloc] init];
smscontroller.body = bodyText.text;
smscontroller.messageComposeDelegate = self;
[self presentModalViewController:smscontroller animated:YES];

...

- (void)messageComposeViewController:(MFMessageComposeViewController *)controller
                 didFinishWithResult:(MessageComposeResult)result
{
    [controller dismissModalViewControllerAnimated:YES];
}
</pre></p>
<p style="text-align:justify;">Ambos controladores poseen un mensaje estático que nos permite comprobar la disponibilidad de estos métodos. Dichos mensajes son &#8220;canSendText&#8221; y &#8220;canSendMail&#8221;. Así si estamos en un iPod Touch sin posibilidad de enviar SMS, podemos comprobarlo antes de intentar utilizar esta funcionalidad.</p>
<p style="text-align:justify;">Como veis, el mecanismo para realizar este tipo de tareas es bastante sencillo a la vez que útil.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/zbutton.wordpress.com/532/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/zbutton.wordpress.com/532/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/zbutton.wordpress.com/532/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/zbutton.wordpress.com/532/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/zbutton.wordpress.com/532/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/zbutton.wordpress.com/532/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/zbutton.wordpress.com/532/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/zbutton.wordpress.com/532/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/zbutton.wordpress.com/532/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/zbutton.wordpress.com/532/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/zbutton.wordpress.com/532/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/zbutton.wordpress.com/532/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/zbutton.wordpress.com/532/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/zbutton.wordpress.com/532/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=zbutton.wordpress.com&amp;blog=8076436&amp;post=532&amp;subd=zbutton&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://zbutton.wordpress.com/2011/07/20/mandando-sms-o-correos-desde-nuestra-app/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b5e8b84400b6903e4436e0489905e051?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">robjperez</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2011/04/mail.png" medium="image">
			<media:title type="html">mail</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2011/07/screen-shot-2011-07-19-at-23-48-02.png" medium="image">
			<media:title type="html">Add Framwork</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2011/07/photo-1.png?w=200" medium="image">
			<media:title type="html">Sending Mail</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2011/07/photo.png?w=200" medium="image">
			<media:title type="html">Sending SMS</media:title>
		</media:content>
	</item>
		<item>
		<title>Barras de búsqueda en iOS</title>
		<link>http://zbutton.wordpress.com/2011/06/12/barras-de-busqueda-en-ios/</link>
		<comments>http://zbutton.wordpress.com/2011/06/12/barras-de-busqueda-en-ios/#comments</comments>
		<pubDate>Sat, 11 Jun 2011 23:30:47 +0000</pubDate>
		<dc:creator>robjperez</dc:creator>
				<category><![CDATA[iphone]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[programacion]]></category>
		<category><![CDATA[iOS]]></category>

		<guid isPermaLink="false">http://zbutton.wordpress.com/?p=518</guid>
		<description><![CDATA[Seguramente en muchas de nuestras aplicaciones de iOS hemos tenido que mostrar una tabla de datos con un montón de entradas. Desde el punto de vista del usuario, es bastante molesto tener que buscar el elemento que quiere entre todos los elementos. Para mejorar la usabilidad, se plantean varias alternativas. Podemos separar los datos en [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=zbutton.wordpress.com&amp;blog=8076436&amp;post=518&amp;subd=zbutton&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://zbutton.files.wordpress.com/2011/06/sherlock175.jpg"><img src="http://zbutton.files.wordpress.com/2011/06/sherlock175.jpg?w=450" alt="" title="sherlock175"   class="alignleft size-full wp-image-527" /></a>
<p style="text-align:justify;">Seguramente en muchas de nuestras aplicaciones de iOS hemos tenido que mostrar una tabla de datos con un montón de entradas. Desde el punto de vista del usuario, es bastante molesto tener que buscar el elemento que quiere entre todos los elementos.</p>
<p style="text-align:justify;">Para mejorar la usabilidad, se plantean varias alternativas. Podemos separar los datos en varios niveles, de tal manera que dividamos los datos en varios bloques, sin embargo, esta solución tiene como inconveniente que obligamos a navegar por varias pantallas.</p>
<p style="text-align:justify;">Concretamente en iOS tenemos varias alternativas para &#8220;ordenar&#8221; nuestros datos a nivel visual. Podemos crear listas por secciones e incluso incluir un indice para saltar entre los diferentes datos al mas puro estilo iTunes o la aplicación que muestra los Contactos.</p>
<p><a href="http://zbutton.files.wordpress.com/2011/06/photo-11-06-11-23-45-27.png"><img src="http://zbutton.files.wordpress.com/2011/06/photo-11-06-11-23-45-27.png?w=200&#038;h=300" alt="" title="iTunes Navigation example" width="200" height="300" class="aligncenter size-medium wp-image-521" /></a></p>
<p style="text-align:justify;">Sin embargo, aunque ayuda, no acaba de solucionar el problema de tener que buscar la entrada que queremos en nuestra tabla. </p>
<p style="text-align:justify;">Aquí es donde entra el campo de búsqueda que seguro habéis visto en numerosas aplicaciones de iOS como Facebook, Twitter o iTunes. En esta entrada vamos a ver como añadir una barra de búsqueda a nuestra aplicación.</p>
<p><a href="http://zbutton.files.wordpress.com/2011/06/screen-shot-2011-06-11-at-23-47-01.png"><img src="http://zbutton.files.wordpress.com/2011/06/screen-shot-2011-06-11-at-23-47-01.png?w=300&#038;h=41" alt="" title="Search Bar" width="300" height="41" class="aligncenter size-medium wp-image-522" /></a></p>
<p style="text-align:justify;">Dentro del conjunto de controles estándar de iOS, tenemos la clase UISearchBar, que representa el cuadro de texto con esquinas redondeadas y la lupa a la que estamos acostumbrados. Sin embargo, este elemento es solo la parte gráfica del sistema de búsqueda. Además de esta clase, vamos a necesitar tratar con la clase UISearchDisplayController, que será la que enlazada a los ViewControllers habituales, nos van a proporcionar todo el sistema de búsqueda que hemos visto en las aplicaciones antes comentadas.</p>
<p style="text-align:justify;">Esta instancia de UISearchDisplayController no vive sola, la mayoría de nuestras vistas, están gestionadas por una clase &#8220;Controller&#8221; que hereda de UIViewController, en esta clase esta definida una propiedad llamada searchDisplayController, a la que podemos asignar nuestra clase controladora del campo de búsqueda. Haciendo esto ganamos bastante funcionalidad.</p>
<p style="text-align:justify;">Si hemos visto el funcionamiento de la barra de búsqueda, hemos visto como al tocar para introducir texto, esta barra se coloca en la parte superior de forma animada, sombreando además la vista entera, además, en algunos casos salen unos botones debajo de la barra de búsqueda, que indican donde se esta realizando la búsqueda. Pues bien, todo este comportamiento esta &#8220;de propina&#8221; si asignamos la propiedad del ViewController a nuestro SearchController.</p>
<p><a href="http://zbutton.files.wordpress.com/2011/06/photo-11-06-11-23-50-07.png"><img src="http://zbutton.files.wordpress.com/2011/06/photo-11-06-11-23-50-07.png?w=200&#038;h=300" alt="" title="Searching" width="200" height="300" class="aligncenter size-medium wp-image-524" /></a></p>
<p style="text-align:justify;">Para llevar esto a la práctica, suponiendo que tenemos un proyecto con un NavigationController, tenemos que ir a la vista que se carga como contenido del navigation controller y añadir el SearchViewController.</p>
<p><a href="http://zbutton.files.wordpress.com/2011/06/screen-shot-2011-06-11-at-23-52-40.png"><img src="http://zbutton.files.wordpress.com/2011/06/screen-shot-2011-06-11-at-23-52-40.png?w=300&#038;h=246" alt="" title="Search Outlets" width="300" height="246" class="aligncenter size-medium wp-image-525" /></a></p>
<p style="text-align:justify;">Automáticamente XCode asigna los outlets, pero para saber como funciona, no es mala idea cotillearlos un poco. XCode establece el outlet del UINavigationController llamado searchDisplayController al SearchDisplayController que acabamos de añadir a la vista. Normalmente el NavigationController será el File&#8217;s Owner del fichero, y así lo vemos en la captura de un poco más arriba.</p>
<p>Hasta ahora, solo hemos hablado de la parte visual, pero después de crear el SearchDisplayController y asignarlo a la propiedad en el ViewController, si introducimos texto, vemos como no pasa nada. El siguiente paso consiste en decir como vamos a mostrar los datos de la búsqueda.</p>
<p style="text-align:justify;">Para mostrar los datos, una de nuestras clases tiene que implementar varios protocolos habituales de una UITableView, como son UITableViewDataSource y UITableViewDelegate. Como veis, al fin y al cabo el proceso se reduce a mostrar una vista reducida de nuestros datos, filtrada por la condición de búsqueda.</p>
<p style="text-align:justify;">Como vemos en la captura anterior, los outlets del SearchDisplay controller respecto al origen de los datos, esta establecidos al File&#8217;s Owner.</p>
<p style="text-align:justify;">En cuanto a la estrategia de implementación, se pueden seguir varias aproximaciones. Por un lado se puede hacer que la misma clase sea DataSource de ambas tablas, es decir, la tabla con todos los datos y la tabla con los datos de la búsqueda, sin embargo esta solución tiene el problema que los mismos métodos tienen que devolver cosas diferentes. Personalmente no me gusta nada esta solución.</p>
<p style="text-align:justify;">Por otro lado, se pueden tener dos clases diferentes, sin embargo hay que tener en cuenta que el modelo de datos a la que acceden ambas clases, es compartido, ya que la búsqueda se realiza sobre los datos que esta mostrando el ViewController de turno.</p>
<p style="text-align:justify;">Estas dos alternativas están pensadas a cuando la búsqueda se realiza sobre una tabla de datos, sin embargo, no tiene por que ser siempre así, la búsqueda podemos hacerla sobre cualquier vista que queramos. En tal caso no habrá mucho problema en unir en la misma clase que gestiona la vista, los métodos de gestión de la tabla de los resultados de la búsqueda.</p>
<p style="text-align:justify;">A continuación os pongo el código de una implementación, el código no pretende ser eficiente, si no mostrar el funcionamiento <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><pre class="brush: objc;">
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    [filteredData release];
    filteredData = [[NSMutableArray alloc] init];
    for ( NSString* name in tableData )
    {
        if ([[name lowercaseString] rangeOfString:[searchText lowercaseString]].location != NSNotFound )
            [filteredData addObject:name];
    }
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [filteredData count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@&quot;Cell&quot;];
    if ( cell == nil )
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@&quot;Cell&quot;];
    
    cell.textLabel.text = [filteredData objectAtIndex:indexPath.row];
    return cell;
}
</pre></p>
<p style="text-align:justify;">Ya que mucha parte del funcionamiento, esta embebido en los ficheros de Interface Builder, he subido <a href="https://github.com/robjperez/IOSTestSearchBar" target="_blank">el proyecto de prueba a github</a>, por si alguien quiere echarle un ojo.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/zbutton.wordpress.com/518/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/zbutton.wordpress.com/518/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/zbutton.wordpress.com/518/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/zbutton.wordpress.com/518/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/zbutton.wordpress.com/518/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/zbutton.wordpress.com/518/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/zbutton.wordpress.com/518/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/zbutton.wordpress.com/518/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/zbutton.wordpress.com/518/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/zbutton.wordpress.com/518/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/zbutton.wordpress.com/518/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/zbutton.wordpress.com/518/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/zbutton.wordpress.com/518/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/zbutton.wordpress.com/518/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=zbutton.wordpress.com&amp;blog=8076436&amp;post=518&amp;subd=zbutton&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://zbutton.wordpress.com/2011/06/12/barras-de-busqueda-en-ios/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b5e8b84400b6903e4436e0489905e051?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">robjperez</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2011/06/sherlock175.jpg" medium="image">
			<media:title type="html">sherlock175</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2011/06/photo-11-06-11-23-45-27.png?w=200" medium="image">
			<media:title type="html">iTunes Navigation example</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2011/06/screen-shot-2011-06-11-at-23-47-01.png?w=300" medium="image">
			<media:title type="html">Search Bar</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2011/06/photo-11-06-11-23-50-07.png?w=200" medium="image">
			<media:title type="html">Searching</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2011/06/screen-shot-2011-06-11-at-23-52-40.png?w=300" medium="image">
			<media:title type="html">Search Outlets</media:title>
		</media:content>
	</item>
		<item>
		<title>La configuración de nuestra aplicación en el menu general</title>
		<link>http://zbutton.wordpress.com/2011/04/26/la-configuracion-de-nuestra-aplicacion-en-el-menu-general/</link>
		<comments>http://zbutton.wordpress.com/2011/04/26/la-configuracion-de-nuestra-aplicacion-en-el-menu-general/#comments</comments>
		<pubDate>Tue, 26 Apr 2011 21:51:02 +0000</pubDate>
		<dc:creator>robjperez</dc:creator>
				<category><![CDATA[iphone]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[programacion]]></category>
		<category><![CDATA[settings]]></category>

		<guid isPermaLink="false">http://zbutton.wordpress.com/?p=505</guid>
		<description><![CDATA[Seguro que en múltiples ocasiones al entrar en la configuración de nuestro teléfono hemos visto listadas un montón de aplicaciones en la parte inferior de la pantalla. Esto es así porque a la hora de proporcionar un punto para configurar nuestra aplicación tenemos dos opciones, una es meterla dentro de la propia aplicación y la [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=zbutton.wordpress.com&amp;blog=8076436&amp;post=505&amp;subd=zbutton&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://zbutton.files.wordpress.com/2011/04/iphone-settings.jpg"><img src="http://zbutton.files.wordpress.com/2011/04/iphone-settings.jpg?w=180&#038;h=180" alt="" title="iphone-Settings" width="180" height="180" class="alignleft size-medium wp-image-510" /></a>
<p style="text-align:justify;">Seguro que en múltiples ocasiones al entrar en la configuración de nuestro teléfono hemos visto listadas un montón de aplicaciones en la parte inferior de la pantalla. Esto es así porque a la hora de proporcionar un punto para configurar nuestra aplicación tenemos dos opciones, una es meterla dentro de la propia aplicación y la otra es integrarla en el menú de configuración del sistema.</p>
<p style="text-align:justify;">Sin duda la opción de hacerlo nosotros en la aplicación puede parecer a priori la mas fácil, pues no tenemos que aprender una nueva forma de hacer las cosas, pero como veremos en esta entrada, integrarse en el menú global de configuración es sencillo y de esta manera nos quitaremos el gestionar una pantalla mas dentro de nuestro programa.</p>
<p style="text-align:justify;">La única limitación que se nos impone es que las opciones que queramos configurar se adapten a los controles que el sistema nos ofrece. Aunque sinceramente, la mayoría de las opciones suelen ser cajas de texto, sliders o booleanos de ON/OFF.</p>
<p style="text-align:justify;">El primer paso para añadir nuestro programa al menú de configuración, es incorporar a nuestro proyecto un bundle de tipo &#8220;settings&#8221;, dicho bundle va a tener uno o varios ficheros de tipo plist donde vamos a especificar los elementos de configuración de nuestra aplicación.</p>
<p><a href="http://zbutton.files.wordpress.com/2011/04/screen-shot-2011-04-26-at-23-23-20.png"><img src="http://zbutton.files.wordpress.com/2011/04/screen-shot-2011-04-26-at-23-23-20.png?w=450&#038;h=299" alt="" title="Screen shot 2011-04-26 at 23.23.20" width="450" height="299" class="aligncenter size-full wp-image-506" /></a></p>
<p style="text-align:justify;">Normalmente la opción mas sencilla será usar el editor de ficheros plist integrado que viene en el xcode, pues en el caso de los settings, automáticamente nos detectará el tipo de elemento y nos mostrará las opciones disponibles.</p>
<p><a href="http://zbutton.files.wordpress.com/2011/04/screen-shot-2011-04-26-at-23-32-43.png"><img src="http://zbutton.files.wordpress.com/2011/04/screen-shot-2011-04-26-at-23-32-43.png?w=450&#038;h=257" alt="" title="Screen shot 2011-04-26 at 23.32.43" width="450" height="257" class="aligncenter size-full wp-image-507" /></a></p>
<p style="text-align:justify;">Aún así, si nos gusta mirar el código de las cosas <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  como seguro que es el caso, podemos ver el XML que se genera y tocar ahí mismo los valores de configuración de cada componente. Como podemos ver en la siguiente captura.</p>
<p><a href="http://zbutton.files.wordpress.com/2011/04/screen-shot-2011-04-26-at-23-32-59.png"><img src="http://zbutton.files.wordpress.com/2011/04/screen-shot-2011-04-26-at-23-32-59.png?w=450&#038;h=241" alt="" title="Screen shot 2011-04-26 at 23.32.59" width="450" height="241" class="aligncenter size-full wp-image-508" /></a></p>
<p style="text-align:justify;">Para mas información sobre las propiedades de cada elemento, podemos visitar la <a href="http://developer.apple.com/library/ios/#documentation/PreferenceSettings/Conceptual/SettingsApplicationSchemaReference/Introduction/Introduction.html#//apple_ref/doc/uid/TP40007071" target="_blank">documentación oficial de Apple</a>, donde se describen todas posibilidades a la hora de describir la interfaz de configuración.</p>
<p style="text-align:justify;">Una de las cosas mas interesantes es que no estamos limitados a una sola pantalla de configuración, podemos añadir una estructura jerárquica de pantallas de configuración.</p>
<p style="text-align:justify;">Para ello, uno de los elementos del fichero plist, es &#8220;PSGroupSpecifier&#8221;, que nos permite especificar otro fichero plist que será el que contenga la pantalla en el siguiente nivel de jerarquía, así podemos crear la configuración tan compleja como la necesitemos</p>
<p style="text-align:justify;">Una vez que tenemos nuestro bundle listo, el siguiente paso es recuperar esos valores en nuestro código. Una vez mas, este proceso es bastante sencillo gracias a la clase NSUserDefaults. Este método tiene los típicos getters y setters para obtener y configurar los valores de la configuración, así por ejemplo el código para recuperar el valor del campo de configuración que describimos en el plist seria:</p>
<p><pre class="brush: objc;">
NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];
NSLog(@&quot;Players: %@&quot;,[settings integerForKey:@&quot;players&quot;]];
NSLog(@&quot;Active Push Notifications: %@&quot;, [settings boolForKey:@&quot;enable_push&quot;]
</pre></p>
<p style="text-align:justify;">Como hemos visto, integrar nuestra aplicación en el menú global de configuración es tremendamente sencillo, y gracias a su potencia a la hora de describir nuestros parámetros de configuración, nos va a ahorrar el hacer dichas pantallas dentro de nuestra aplicación.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/zbutton.wordpress.com/505/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/zbutton.wordpress.com/505/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/zbutton.wordpress.com/505/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/zbutton.wordpress.com/505/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/zbutton.wordpress.com/505/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/zbutton.wordpress.com/505/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/zbutton.wordpress.com/505/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/zbutton.wordpress.com/505/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/zbutton.wordpress.com/505/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/zbutton.wordpress.com/505/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/zbutton.wordpress.com/505/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/zbutton.wordpress.com/505/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/zbutton.wordpress.com/505/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/zbutton.wordpress.com/505/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=zbutton.wordpress.com&amp;blog=8076436&amp;post=505&amp;subd=zbutton&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://zbutton.wordpress.com/2011/04/26/la-configuracion-de-nuestra-aplicacion-en-el-menu-general/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b5e8b84400b6903e4436e0489905e051?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">robjperez</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2011/04/iphone-settings.jpg?w=298" medium="image">
			<media:title type="html">iphone-Settings</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2011/04/screen-shot-2011-04-26-at-23-23-20.png" medium="image">
			<media:title type="html">Screen shot 2011-04-26 at 23.23.20</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2011/04/screen-shot-2011-04-26-at-23-32-43.png" medium="image">
			<media:title type="html">Screen shot 2011-04-26 at 23.32.43</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2011/04/screen-shot-2011-04-26-at-23-32-59.png" medium="image">
			<media:title type="html">Screen shot 2011-04-26 at 23.32.59</media:title>
		</media:content>
	</item>
		<item>
		<title>Mensajes entre clases usando NSNotificationCenter</title>
		<link>http://zbutton.wordpress.com/2011/04/03/mensajes-entre-clases-usando-nsnotificationcenter/</link>
		<comments>http://zbutton.wordpress.com/2011/04/03/mensajes-entre-clases-usando-nsnotificationcenter/#comments</comments>
		<pubDate>Sun, 03 Apr 2011 21:22:45 +0000</pubDate>
		<dc:creator>robjperez</dc:creator>
				<category><![CDATA[mac]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[programacion]]></category>
		<category><![CDATA[notificationcenter]]></category>

		<guid isPermaLink="false">http://zbutton.wordpress.com/?p=496</guid>
		<description><![CDATA[La orientación a objetos de los lenguajes actuales hace que nuestros programas estén hechos de clases, clases que se comunican entre ellas mediante mensajes. Estos mensajes según el lenguaje se manifiestan en llamadas a métodos y en otros casos, como es el de ObjetiveC, como realmente mensajes. Seguramente en muchas ocasiones, nos hemos encontrado con [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=zbutton.wordpress.com&amp;blog=8076436&amp;post=496&amp;subd=zbutton&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://zbutton.files.wordpress.com/2011/04/mail.png"><img class="alignleft size-full wp-image-498" title="mail" src="http://zbutton.files.wordpress.com/2011/04/mail.png?w=450" alt=""   /></a></p>
<p style="text-align:justify;">La orientación a objetos de los lenguajes actuales hace que nuestros programas estén hechos de clases, clases que se comunican entre ellas mediante mensajes. Estos mensajes según el lenguaje se manifiestan en llamadas a métodos y en otros casos, como es el de ObjetiveC, como realmente mensajes.</p>
<p style="text-align:justify;">Seguramente en muchas ocasiones, nos hemos encontrado con el caso de que queremos recibir un mensaje, pero el objeto que lo envía, no necesariamente tiene que tener una referencia nuestra, o visto desde el otro lado, queremos enviar un mensaje y no sabemos quien estaría interesado en recibirlo, e incluso, ese alguien no guarda ninguna relación con nuestra clase, por lo que no seria correcto que tuviera una instancia nuestra.</p>
<p style="text-align:justify;">Pongamos un ejemplo, tenemos una clase que se encarga de gestionar una comunicación, y por otro lado, en la parte de la vista que muestra la información que viene de esa comunicación, tenemos una tabla que muestra datos. Cada vez que se recibe un mensaje nuevo, la tabla tiene que repintar los datos.</p>
<p style="text-align:justify;">Podríamos tener una instancia de la clase de comunicación en nuestra vista, pero estaría ligando dos clases que excepto por ese detalle, no tienen nada mas en común.</p>
<p style="text-align:justify;">Una solución seria utilizar una capa intermedia, que podría ser el Modelo que propagara las notificaciones de inserción de datos a todos los niveles. Esta solución sería la que actualmente implementaríamos en muchos sistemas, pero requiere meter eventos y orientar nuestro diseño hacia este tipo de dependencias entre las clases.</p>
<p style="text-align:justify;">La solución a la que se puede llegar con las notificaciones es desacoplar totalmente todas las clases del ejemplo. Usando este modelo, la clase de la vista se registraría en la cola de notificaciones diciendo que le interesa escuchar cuando llega un nuevo mensaje. Por su parte la clase que se encarga de controlar la comunicación, &#8220;posteará&#8221; un mensaje cuando reciba un mensaje.</p>
<p style="text-align:justify;">De esta forma, todos los elementos están completamente desacoplados, y en el fondo, nadie necesita tener una instancia de otras clases. Incluso, si en algún momento una de ellas dejaría de existir, las otras clases podrían seguir funcionando sin problemas.</p>
<p style="text-align:justify;">Después de todo este rollo <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> , vamos a ver como es de fácil hacerlo en Cocoa y la cantidad de ventajas que aporta este enfoque en el diseño de nuestras clases.</p>
<p style="text-align:justify;">En Cocoa y Cocoa Touch, existe una clase llamada NSNotificationCenter, dicha clase se va a encargar de gestionar un &#8220;centro&#8221; de notificaciones que es accesible desde todas las clases de nuestro programa, e incluso desde clases de diferentes programas.</p>
<p style="text-align:justify;">El runtime creará el centro de notificaciones por nosotros, y por lo tanto accederemos a la clase usando un método estático.</p>
<p style="text-align:justify;">Básicamente hay dos formas de interacción con el centro de notificaciones, por un lado, los &#8220;observers&#8221; se añaden como receptores de la notificación usando un nombre determinado. Por otro lado, los notificadores, notifican a los observadores usando ese nombre como clave.</p>
<p style="text-align:justify;">Hay varios métodos para registrarse como observador, por ejemplo el método, addObserver:selector:name:object:, especifica la instancia, el selector de la clase que se ejecutará, el nombre de la notificación y opcionalmente la instancia que será capaz de enviar la notificación, si este parametro lo dejamos en &#8220;nil&#8221; no filtraremos por el objeto que envia la notificación. El otro método para añadirse como observador es: addObserverForName:object:queue:usingBlock:, donde en lugar de indicar un selector, se pasa un bloque de código que se ejecutará cuando se reciba una notificación. En este último método vemos el parámetro &#8220;queue&#8221;, que trataremos mas adelante.</p>
<p style="text-align:justify;">Por otro lado, para &#8220;postear&#8221; una notificación, podemos usar dos métodos, postNotificationName:object:, donde indicamos el nombre de la notificación que estamos &#8220;levantando&#8221;, o bien, podemos usar el método, postNotification:, donde agrupamos la misma información en un objeto de tipo NSNotification.</p>
<p style="text-align:justify;">Finalmente, los observers deben quitarse del centro de notificaciones cuando ya no quieren recibir más. Para ello se puede usar el método removeObserver: o removeObserver:name:object:.</p>
<p style="text-align:justify;">Vamos a ver un ejemplo completo en acción.</p>
<p><pre class="brush: objc;">
/* Código de un UIViewController que ademas es un UITableViewDataSource */

- (id) viewDidLoad
{
  // ...
  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
  [center addObserver:self selector:@selector(logOn:) name:@&quot;logged on&quot; object:nil];

  // ...
}

- (void) logOn: (NSNotification*) theNotification
{
    // La clase encargada de la comunicación nos ha notificado de que
    // se ha producido la entrada al sistema
}

- (void)viewDidUnload
{
  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
  [center removeObserver:self];
}

/* Codigo de la clase que se encarga de gestionar la comunicación */

// ...
  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
  [center postNotificationName:@&quot;loggedon&quot; object:nil];
  // En este momento ya se habra ejecutado el codigo del ViewController que estaba
  // apuntado para recibir notificaciones.
// ...
</pre></p>
<p style="text-align:justify;">Una duda que nos puede surgir es, como se ejecuta el código asociado a la notificación cuando el notificador postea un mensaje.</p>
<p style="text-align:justify;">Realmente el código se ejecuta de forma síncrona y en el contexto de la instancia que se pasa cuando un observador se registra en el NotificationCenter, de esta manera, cuando el notificador postea el mensaje usando una de las variaciones del postNotification, se bloquea hasta que todos los métodos de los obsevers se ejecutan. Sin embargo, por si queda alguna duda, el método addObserver no bloque a la clase que se llama, el único momento de sincronismo se produce por parte de la clase que envía la notificacion.</p>
<p style="text-align:justify;">Para que esta ejecución sea asíncrona, debemos usar colas de notificación, y si volvemos atrás, el parámetro  queue del método postNotification es el que gestiona este detalle.</p>
<p style="text-align:justify;">Así que os dejo con la intriga <img src='http://s0.wp.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> , y para dos futuros posts hablaremos de las notificaciones asíncronas usando colas de notificaciones y como enviar notificaciones entre procesos usando el NSDistributedNotificationCenter.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/zbutton.wordpress.com/496/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/zbutton.wordpress.com/496/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/zbutton.wordpress.com/496/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/zbutton.wordpress.com/496/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/zbutton.wordpress.com/496/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/zbutton.wordpress.com/496/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/zbutton.wordpress.com/496/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/zbutton.wordpress.com/496/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/zbutton.wordpress.com/496/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/zbutton.wordpress.com/496/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/zbutton.wordpress.com/496/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/zbutton.wordpress.com/496/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/zbutton.wordpress.com/496/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/zbutton.wordpress.com/496/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=zbutton.wordpress.com&amp;blog=8076436&amp;post=496&amp;subd=zbutton&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://zbutton.wordpress.com/2011/04/03/mensajes-entre-clases-usando-nsnotificationcenter/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b5e8b84400b6903e4436e0489905e051?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">robjperez</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2011/04/mail.png" medium="image">
			<media:title type="html">mail</media:title>
		</media:content>
	</item>
		<item>
		<title>Desmitificando Core Data para iOS</title>
		<link>http://zbutton.wordpress.com/2011/03/06/desmitificando-core-data-para-ios/</link>
		<comments>http://zbutton.wordpress.com/2011/03/06/desmitificando-core-data-para-ios/#comments</comments>
		<pubDate>Sun, 06 Mar 2011 19:41:39 +0000</pubDate>
		<dc:creator>robjperez</dc:creator>
				<category><![CDATA[iphone]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[programacion]]></category>
		<category><![CDATA[coredata]]></category>
		<category><![CDATA[iOS]]></category>

		<guid isPermaLink="false">http://zbutton.wordpress.com/?p=483</guid>
		<description><![CDATA[Seguro que en muchas ocasiones hemos leido el nombre de Core Data, y puede que en esas ocasiones nos haya parecido que seria una librería compleja de utilizar. Si hay algo constante en la gran mayoría de las aplicaciones es, su necesidad de guardar datos en el medio de almacenamiento que el dispositivo ofrezca. Esta [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=zbutton.wordpress.com&amp;blog=8076436&amp;post=483&amp;subd=zbutton&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://zbutton.files.wordpress.com/2011/03/macosx_data_coredata_20090925.png"><img src="http://zbutton.files.wordpress.com/2011/03/macosx_data_coredata_20090925.png?w=450" alt="" title="macosx_data_coredata_20090925"   class="alignleft size-full wp-image-489" /></a>
<p style="text-align:justify;">Seguro que en muchas ocasiones hemos leido el nombre de Core Data, y puede que en esas ocasiones nos haya parecido que seria una librería compleja de utilizar.</p>
<p style="text-align:justify;">Si hay algo constante en la gran mayoría de las aplicaciones es, su necesidad de guardar datos en el medio de almacenamiento que el dispositivo ofrezca. Esta necesidad es la que vamos a poder salvar con Core Data, y de una manera bastante sencilla.</p>
<p style="text-align:justify;">Concretamente, en esta entrada vamos a hablar de la versión para iPhone de Core Data, que en sus funcionalidades básicas, poco tiene que envidiar a su hermana mayor de OS X.</p>
<p style="text-align:justify;">A diferencia de algunos tutoriales que andan por ahí, que empiezan desde una aplicación vacía, aquí vamos a ver como incorporar Core Data a nuestra aplicación ya empezada.</p>
<p style="text-align:justify;">Personalmente, Core Data me ha sorprendido, pensaba que sería mucho mas compleja y complicada de incorporar a una aplicación, pero siguiendo la linea de muchas cosas de Apple, la librería es muy sencilla de utilizar. Pero, no adelantemos acontecimientos <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p style="text-align:justify;">El primer paso es entender como funciona Core Data. Para ello, nos vamos a ayudar del siguiente gráfico:</p>
<p><a href="http://zbutton.files.wordpress.com/2011/03/diagrama_coredata.png"><img src="http://zbutton.files.wordpress.com/2011/03/diagrama_coredata.png?w=277&#038;h=300" alt="" title="diagrama_coredata" width="277" height="300" class="aligncenter size-medium wp-image-487" /></a></p>
<p style="text-align:justify;">Como vemos, hay tres niveles, arriba del todo están nuestros objetos, que o bien son instancias de NSManagedObject, o bien heredan de él. Como en la vida real <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> , nuestros objetos viven en un contexto, aquí esta representado por el NSManagedObjectContext. Este contexto va a ser el que alojara nuestros objetos dotándoles de los mecanismos de persistencia que Core Data proporciona. Por ejemplo, si queremos crear un objeto, en lugar de construirlo por nuestra cuenta, le pediremos al contexto que nos genere uno. Y de la misma manera cuando queramos guardar el objeto a disco, le diremos al contexto que lo guarde.</p>
<p style="text-align:justify;">En la parte mas baja, se encuentra el Persistent Store Coordinator, que, como su nombre indica, es el encargado de coordinar la escritura en el almacenamiento. Realmente nosotros, salvo para indicarle donde esta el almacenamiento, no vamos a trabajar mucho mas con él.</p>
<p style="text-align:justify;">Finalmente, el ultimo elemento del gráfico es el modelo que describe como son nuestros objetos. Eso es lo que se conoce como el Managed Object Model, y que esta representado por el fichero xcdatamodeld y que podremos editar de una forma bastante cómoda usando xcode.</p>
<p style="text-align:justify;">Una vez visto (de forma breve y resumida) la arquitectura de Core Data, vamos a ponernos manos a la obra y vamos a dotar de persistencia a nuestra aplicación.</p>
<p style="text-align:justify;">Para ello, el primer paso es incluir dentro de nuestros frameworks, el de Core Data. </p>
<p style="text-align:justify;">El siguiente paso es crear el modelo de los objetos que vamos a utilizar, para ello, añadimos un nuevo fichero de tipo Core Data Model a nuestro proyecto, lo que creara un fichero de tipo xcdatamodeld.</p>
<p style="text-align:justify;">Si abrimos dicho fichero, xcode nos mostrará un cómodo editor para crear nuestras entidades, por ejemplo vamos a crear una clase que represente a un coche.</p>
<p style="text-align:justify;">Ahora vamos al código de verdad. Para guardar objetos en el contexto, necesitamos acceder al propio contexto, y lo vamos a necesitar desde múltiples sitios, por ello, lo mejor es crearnos una clase que sea accesible desde todos los sitios y que &#8220;guarde&#8221; la instancia del contexto. Cogiendo el código que Apple pone de ejemplo cuando creamos una aplicación que use code data, dicha clase sería algo como:</p>
<p><pre class="brush: objc;">

@interface CoreDataManager : NSObject {
    
}

@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;

- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;

+ (CoreDataManager*) sharedInstance;

@end

@implementation CoreDataManager

@synthesize managedObjectContext=__managedObjectContext;
@synthesize managedObjectModel=__managedObjectModel;
@synthesize persistentStoreCoordinator=__persistentStoreCoordinator;

static CoreDataManager* _sharedInstance;

+ (CoreDataManager*) sharedInstance
{
    if ( ! _sharedInstance )
        _sharedInstance = [[CoreDataManager alloc] init];
    
    return _sharedInstance;
}

- (id)init 
{
    self = [super init];
    if (self) {
        _sharedInstance = self;
    }
    return self;
}

- (void) dealloc 
{
    [__managedObjectContext release];
    [__managedObjectModel release];
    [__persistentStoreCoordinator release];
    [super dealloc];
}
- (void)saveContext
{
    NSError *error = nil;
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    if (managedObjectContext != nil)
    {
        if ([managedObjectContext hasChanges] &amp;&amp; ![managedObjectContext save:&amp;error])
        {
            NSLog(@&quot;Unresolved error %@, %@&quot;, error, [error userInfo]);
            abort();
        } 
    }
}

#pragma mark - Core Data stack

- (NSManagedObjectContext *)managedObjectContext
{
    if (__managedObjectContext != nil)
    {
        return __managedObjectContext;
    }
    
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil)
    {
        __managedObjectContext = [[NSManagedObjectContext alloc] init];
        [__managedObjectContext setPersistentStoreCoordinator:coordinator];
    }
    return __managedObjectContext;
}

- (NSManagedObjectModel *)managedObjectModel
{
    if (__managedObjectModel != nil)
    {
        return __managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@&quot;PruebaCoreData&quot; withExtension:@&quot;momd&quot;];
    __managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];    
    return __managedObjectModel;
}

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (__persistentStoreCoordinator != nil)
    {
        return __persistentStoreCoordinator;
    }
    
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@&quot;PruebaCoreData.sqlite&quot;];
    
    NSError *error = nil;
    __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&amp;error])
    {
        NSLog(@&quot;Unresolved error %@, %@&quot;, error, [error userInfo]);
        abort();
    }    
    
    return __persistentStoreCoordinator;
}

#pragma mark - Application's Documents directory
- (NSURL *)applicationDocumentsDirectory
{
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
@end
</pre></p>
<p style="text-align:justify;">Una vez que el contexto es accesible desde otros puntos del nuestro programa, el siguiente paso es guardar un objeto en el almacenamiento, para ello le pedimos al contexto que nos de una nueva instancia de la clase, la rellenamos con los datos y le decimos al contexto que la guarde. El código que lo hace sería así:</p>
<p><pre class="brush: objc;">
NSManagedObject* myCoche = [NSEntityDescription insertNewObjectForEntityForName:@&quot;Coche&quot; inManagedObjectContext:[CoreDataManager sharedInstance].managedObjectContext];
[myCoche setValue:@&quot;Ford&quot; forKey:@&quot;Fabricante&quot;];
[myCoche setValue:@&quot;Crown Victoria&quot; forKey:@&quot;Modelo&quot;];
[myCoche setValue:[NSNumber numberWithInt:12000] forKey:@&quot;Precio&quot;];
[[CoreDataManager sharedInstance] saveContext];
</pre></p>
<p style="text-align:justify;">Como veis, el funcionamiento no podía ser mas fácil. Con muy poco código, tenemos persistido nuestro objeto en un almacén de datos.</p>
<p style="text-align:justify;">Finalmente, el último paso seria recuperar los objetos que hay en el almacén, para ello necesitamos una nueva clase, llamada NSFetchRequest. En esta entrada nos vamos a quedar en un nivel básico, ya que el propósito es ver que componentes entran en juego cuando usamos Core Data, por lo que vamos únicamente a recuperar todos nuestros objetos, sin poner ningún tipo de filtro. </p>
<p style="text-align:justify;">Es evidente que vamos a necesitar un mejor control de como recuperamos nuestros objetos, para ello lo mejor es acudir directamente a la documentación sobre esta clase y quizás a una futura entrada que explique en detalle como se recuperan objetos usando esta clase <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p style="text-align:justify;">Volviendo a la recuperación de datos, el proceso consta de crear el FetchRequest, especificar el tipo de entidad que vamos a recuperar, en nuestro caso, un Coche, y ejecutar el request, obteniendo así un array con los objetos que estaban en el almacén. </p>
<p><pre class="brush: objc;">
NSFetchRequest *req = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@&quot;Coche&quot; inManagedObjectContext:[CoreDataManager sharedInstance].managedObjectContext];
    [req setEntity:entity];
    NSError *error;
    NSArray *objects = [[CoreDataManager sharedInstance].managedObjectContext executeFetchRequest:req error:&amp;error];
</pre></p>
<p style="text-align:justify;">Como se suele decir, lo difícil es empezar, y espero que con esta entrada ese paso este dado. Queda mucho Core Data por explorar, cosas como las relaciones entre entidades, o los filtros en los request son cosas muy comunes y que vamos a necesitar usar. Sin duda, son materia para futuras entradas <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/zbutton.wordpress.com/483/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/zbutton.wordpress.com/483/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/zbutton.wordpress.com/483/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/zbutton.wordpress.com/483/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/zbutton.wordpress.com/483/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/zbutton.wordpress.com/483/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/zbutton.wordpress.com/483/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/zbutton.wordpress.com/483/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/zbutton.wordpress.com/483/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/zbutton.wordpress.com/483/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/zbutton.wordpress.com/483/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/zbutton.wordpress.com/483/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/zbutton.wordpress.com/483/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/zbutton.wordpress.com/483/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=zbutton.wordpress.com&amp;blog=8076436&amp;post=483&amp;subd=zbutton&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://zbutton.wordpress.com/2011/03/06/desmitificando-core-data-para-ios/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b5e8b84400b6903e4436e0489905e051?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">robjperez</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2011/03/macosx_data_coredata_20090925.png" medium="image">
			<media:title type="html">macosx_data_coredata_20090925</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2011/03/diagrama_coredata.png?w=277" medium="image">
			<media:title type="html">diagrama_coredata</media:title>
		</media:content>
	</item>
		<item>
		<title>Probando clases ObjetiveC usando MacRuby</title>
		<link>http://zbutton.wordpress.com/2011/02/12/probando-clases-objetivec-usando-macruby/</link>
		<comments>http://zbutton.wordpress.com/2011/02/12/probando-clases-objetivec-usando-macruby/#comments</comments>
		<pubDate>Fri, 11 Feb 2011 23:41:49 +0000</pubDate>
		<dc:creator>robjperez</dc:creator>
				<category><![CDATA[mac]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[programacion]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://zbutton.wordpress.com/?p=474</guid>
		<description><![CDATA[Sin duda una de las cosas que siempre me ha gustado tener a mano es una manera de probar código sin tener que crear todo un proyecto para ello. Hace mucho tiempo, cuando usaba Java como mi principal lenguaje de programación, usaba Beanshell, que ademas de ser un lenguaje de scripting ofrece una consola que [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=zbutton.wordpress.com&amp;blog=8076436&amp;post=474&amp;subd=zbutton&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://zbutton.files.wordpress.com/2010/08/logo.png"><img src="http://zbutton.files.wordpress.com/2010/08/logo.png?w=150&#038;h=150" alt="" title="logo" width="150" height="150" class="alignleft size-medium wp-image-366" /></a>
<p style="text-align:justify;">Sin duda una de las cosas que siempre me ha gustado tener a mano es una manera de probar código sin tener que crear todo un proyecto para ello. Hace mucho tiempo, cuando usaba Java como mi principal lenguaje de programación, usaba <a href="http://www.beanshell.org/">Beanshell</a>, que ademas de ser un lenguaje de scripting ofrece una consola que interpreta código en java en tiempo real. </p>
<p style="text-align:justify;">Por aquel tiempo, si quería probar, por ejemplo, como sacar una subcadena a partir de un carácter dado, podía ir probando con las diferentes combinaciones en la consola de Beanshell. La alternativa era construirse todo un proyecto solo para probar como deberías hacer el substring correcto, proyecto que había que compilar y ejecutar para ver los resultados. Sin duda el hecho de usar una consola que te daba los resultados inmediatos era una gran ventaja.</p>
<p style="text-align:justify;">Mas adelante, y con algunas aventuras en python o ruby, la existencia de la consola para probar código venia de serie con la plataforma. Así si queremos probar un pequeño fragmento de código Ruby, podemos arrancar el irb y escribirlo tal cual.</p>
<p style="text-align:justify;">Hoy en día, en mis aventuras por Objetive-C, echaba de menos esta funcionalidad. Esta claro que al ser Objective-C un lenguaje compilado, a priori es complicado tener un programa que haga esto, pero es aquí donde encaja esa maravilla llamada MacRuby <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p style="text-align:justify;">Dado a que, usando MacRuby, podemos acceder a todas las clases definidas en los frameworks de OSX sin importar en que lenguaje estén definidas, vamos a poder usar el irb para poder probar esas clases de Cocoa que usamos habitualmente.</p>
<p style="text-align:justify;">Vamos a ver un ejemplo:</p>
<p style="text-align:justify;">Supongamos que tenemos una cadena de la forma &#8220;clave=valor;clave2=valor2&#8243;&#8221; y queremos transformarla en un diccionario que almacene esta información.</p>
<p style="text-align:justify;">Para ello, necesitamos manipular la clase NSString, sin duda una alternativa sería escribir el código (siempre después de los test, claro <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ), e ir probando. Pero siempre surgen algunas dudas, como por ejemplo, el IndexOf de NSString, ¿esta basado en 0?, si hago un substring con inicio en la posición 3, ¿incluye el tercer carácter?</p>
<p style="text-align:justify;">Estas dudas, harán posiblemente que el código que escribamos la primera vez, falle.</p>
<p style="text-align:justify;">La alternativa es arrancar macirb, y jugar directamente con la clase NSString. Por ejemplo si ejecutamos lo siguiente:</p>
<p><pre class="brush: ruby;">
irb(main):010:0&gt; &quot;clave=valor;clave2=valor2&quot;.componentsSeparatedByString(&quot;;&quot;)
=&gt; [&quot;clave=valor&quot;, &quot;clave2=valor2&quot;]
</pre></p>
<p style="text-align:justify;">Veremos que el mensaje &#8220;componentsSeparatedByString&#8221;, funciona como esperábamos. Pero no solo eso, vemos que también podíamos aplicar lo mismo a cada elemento para obtener cada clave y cada valor:</p>
<p><pre class="brush: ruby;">
irb(main):012:0&gt; &quot;clave=valor;clave2=valor2&quot;.componentsSeparatedByString(&quot;;&quot;).each { |x| p x.componentsSeparatedByString(&quot;=&quot;) }
[&quot;clave&quot;, &quot;valor&quot;]
[&quot;clave2&quot;, &quot;valor2&quot;]
=&gt; [&quot;clave=valor&quot;, &quot;clave2=valor2&quot;]
</pre></p>
<p><a href="http://zbutton.files.wordpress.com/2011/02/screen-shot-2011-02-12-at-00-38-10.png"><img src="http://zbutton.files.wordpress.com/2011/02/screen-shot-2011-02-12-at-00-38-10.png?w=450&#038;h=73" alt="" title="Screen shot 2011-02-12 at 00.38.10" width="450" height="73" class="aligncenter size-full wp-image-478" /></a></p>
<p style="text-align:justify;">Como vemos, la comodidad que ofrece el probar código solo con teclearlo directamente en la consola es tremendamente util para reducir muchos ciclos de compilar (o ejecutar test) y ver como vuelve a fallar.</p>
<p style="text-align:justify;">La &#8220;magia&#8221; de MacRuby no acaba aquí, como hemos dicho antes, podemos llamar a cualquier clase de Cocoa, por lo que si probamos el siguiente código:</p>
<p><pre class="brush: ruby;">
irb(main):006:0&gt; framework 'Cocoa'
irb(main):007:0&gt; sp = NSSpeechSynthesizer.alloc.initWithVoice nil
=&gt; #&lt;NSSpeechSynthesizer:0x2005293e0&gt;
irb(main):008:0&gt; sp.startSpeakingString &quot;hello from macruby. This is so cool!&quot;
=&gt; true
</pre></p>
<p style="text-align:justify;">Nuestro mac empezará a hablar. <img src='http://s0.wp.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p style="text-align:justify;">Como veis, la única regla a seguir es en vez de utilizar la sintaxis típica de objetive c para enviar mensajes, debemos utilizar la notación habitual con el &#8220;.&#8221;. Aunque si esto nos incomoda, siempre podemos seguir usando mensajes gracias al método &#8220;send&#8221; de Ruby, y de esta manera ejecutar el anterior código como:</p>
<p><pre class="brush: ruby;">
irb(main):010:0&gt; sp.send :startSpeakingString, &quot;hello from macruby. This is so cool!&quot;
</pre></p>
<p style="text-align:justify;">La interoperabilidad Ruby  Cocoa abre todo un mundo de posibilidades, ¿Alguien ha dicho algo sobre RSpec para probar clases hechas en ObjectiveC?. En cualquier caso, son unos interesantes temas para otras entradas del blog.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/zbutton.wordpress.com/474/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/zbutton.wordpress.com/474/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/zbutton.wordpress.com/474/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/zbutton.wordpress.com/474/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/zbutton.wordpress.com/474/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/zbutton.wordpress.com/474/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/zbutton.wordpress.com/474/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/zbutton.wordpress.com/474/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/zbutton.wordpress.com/474/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/zbutton.wordpress.com/474/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/zbutton.wordpress.com/474/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/zbutton.wordpress.com/474/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/zbutton.wordpress.com/474/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/zbutton.wordpress.com/474/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=zbutton.wordpress.com&amp;blog=8076436&amp;post=474&amp;subd=zbutton&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://zbutton.wordpress.com/2011/02/12/probando-clases-objetivec-usando-macruby/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b5e8b84400b6903e4436e0489905e051?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">robjperez</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2010/08/logo.png?w=" medium="image">
			<media:title type="html">logo</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2011/02/screen-shot-2011-02-12-at-00-38-10.png" medium="image">
			<media:title type="html">Screen shot 2011-02-12 at 00.38.10</media:title>
		</media:content>
	</item>
		<item>
		<title>Construyendo un Servicio en OSX</title>
		<link>http://zbutton.wordpress.com/2011/01/16/construyendo-un-servicio-en-osx/</link>
		<comments>http://zbutton.wordpress.com/2011/01/16/construyendo-un-servicio-en-osx/#comments</comments>
		<pubDate>Sun, 16 Jan 2011 00:31:33 +0000</pubDate>
		<dc:creator>robjperez</dc:creator>
				<category><![CDATA[mac]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[programacion]]></category>
		<category><![CDATA[osx]]></category>

		<guid isPermaLink="false">http://zbutton.wordpress.com/?p=466</guid>
		<description><![CDATA[Uno de los aspectos que pasan mas desapercibidos en OSX son los &#8220;Servicios&#8221;. Seguramente por el nombre pensareis que es un programa que se ejecuta de fondo en nuestro ordenador. Si bien ese pensamiento no es del todo incorrecto, los servicios en OSX es algo mas. Con servicios me refiero a los elementos del menú [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=zbutton.wordpress.com&amp;blog=8076436&amp;post=466&amp;subd=zbutton&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://zbutton.files.wordpress.com/2011/01/screen-shot-2011-01-07-at-22-51-05.png"><img src="http://zbutton.files.wordpress.com/2011/01/screen-shot-2011-01-07-at-22-51-05.png?w=450&#038;h=199" alt="" title="OSX Services" width="450" height="199" class="aligncenter size-full wp-image-469" /></a></p>
<p style="text-align:justify;">Uno de los aspectos que pasan mas desapercibidos en OSX son los &#8220;Servicios&#8221;. Seguramente por el nombre pensareis que es un programa que se ejecuta de fondo en nuestro ordenador.</p>
<p style="text-align:justify;">Si bien ese pensamiento no es del todo incorrecto, los servicios en OSX es algo mas. Con servicios me refiero a los elementos del menú que sale cuando pinchamos sobre el nombre del programa activo en la barra de menús.</p>
<p style="text-align:justify;">La localización de dicho menú ha ido cambiando con el tiempo, en versiones anteriores ocupaban una posición mas destacada, pero poco a poco han ido pasando a un plano mas &#8220;oculto&#8221;. </p>
<p style="text-align:justify;">Sin embargo, la posición de esta funcionalidad no nos tiene que despistar, ya que la utilidad que prestan es bastante buena.</p>
<p style="text-align:justify;">Para comprobar su funcionamiento, solo tenemos que seleccionar algo de texto, e ir al menú Servicios. Desde dicho menú se nos dará la opción de hacer diversas cosas, como por ejemplo, crear una nota. Además no solo los servicios están accesibles desde este menú, si no que podremos acceder usando atajos de teclado. Por ejemplo, si pulsamos SHIFT+ ⌘+Y, crearemos la nota al instante.</p>
<p style="text-align:justify;">Una de las grandes ventajas de los servicios es que están disponibles para todo el sistema, esto es, independientemente de la aplicación donde seleccionemos el texto, si pulsamos el atajo de teclado, crearemos una nota con el texto seleccionado.</p>
<p style="text-align:justify;">Como podemos leer en la propia documentación de Apple, posibles servicios serian, reconocedores de texto en una imagen, cifrado de texto o incluso, aunque no venga en la guía de Apple, sería útil un servicio para  insertar una cita de Chuck Norris en el documento actual <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p style="text-align:justify;">Desde el punto de vista de la programación, se pueden distinguir dos elementos, por un lado el propio servicio, y por otro la aplicación que interactua con él. La pieza que intercomunica ambas partes es el clipboard. Cuando pinchamos en un servicio, la aplicación pone los datos necesarios en el clipboard, e invoca al servicio. El servicio por su parte, recoge dichos datos, los procesa y los vuelve a poner en el clipboard. Finalmente, la aplicación recoge lo que haya en el clipboard y hace lo que considere oportuno con dichos datos.</p>
<p style="text-align:justify;">En la entrada vamos a crear un servicio, que seleccionado texto, lo consulte en la wikipedia usando Safari.</p>
<p style="text-align:justify;">El código que atiende al servicio, es sencillo, a grandes rasgos, los pasos que hay que dar son por un lado, crear el método al que se llamará, y por otro, registrar el servicio en el sistema.</p>
<p style="text-align:justify;">Desafortunadamente, xcode no tiene plantillas para crear los servicios, por lo que tendremos que empezar desde un proyecto vacío que cree un ejecutable.</p>
<p style="text-align:justify;">Una vez que tenemos el proyecto creado en el XCode, debemos añadir (si no lo estaba antes), el framework de Cocoa y Foundation, y añadir la clase que implementará el método que atiende el servicio.</p>
<p style="text-align:justify;">En nuestro caso, dicha clase es WikipediaService</p>
<p><pre class="brush: objc;">

==== WikipediaService.h

#import &lt;Cocoa/Cocoa.h&gt;


@interface WikipediaService : NSObject {

}

- (void) wikipediaSearch: (NSPasteboard*) pboard 
				userData:(NSString*) theUserData 
				   error:(NSString**) theError;

@end

==== WikipediaService.m

@implementation WikipediaService

- (void) wikipediaSearch: (NSPasteboard*) pboard userData:(NSString*) theUserData error:(NSString**) theError
{
	// Test for strings on the pasteboard.
	NSArray *classes = [NSArray arrayWithObject:[NSString class]];
	NSDictionary *options = [NSDictionary dictionary];
	
	if (![pboard canReadObjectForClasses:classes options:options]) {
		*theError = NSLocalizedString(@&quot;Error recuperando datos del pboard&quot;, 
									  @&quot;pboard couldn't give string.&quot;);
		return;
	}
	
	// Get and encrypt the string.
	NSString *pboardString = [pboard stringForType:NSPasteboardTypeString];
	NSString *wikipediaString = [NSString stringWithFormat:@&quot;http://en.wikipedia.org/wiki/%@&quot;, pboardString];
	NSURL *url = [[NSURL alloc] initWithString: wikipediaString];
	[[NSWorkspace sharedWorkspace] openURL:url];
	
	[pboard clearContents];
}

@end
</pre></p>
<p style="text-align:justify;">Como vemos, el clipboard es la parte que comunica ambos procesos. Con el mensaje canReadObjectForClasses primero comprobamos si el clipboard contiene datos de tipo cadena, y luego con el mensaje stringForType del &#8220;pasteboard&#8221; obtenemos dicha cadena.</p>
<p style="text-align:justify;">Por otro lado, en nuestro punto de entrada de la aplicación, debemos situar el código que registra el servicio en el sistema.</p>
<p><pre class="brush: objc;">
int main(int argc, char *argv[])
{

	NSRegisterServicesProvider([WikipediaService new], @&quot;WikipediaService&quot;);
	NSUpdateDynamicServices();
	[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
	return 0;
}
</pre></p>
<p style="text-align:justify;">Antes de ejecutar y probar nuestro servicio, nos queda una parte muy importante. En el fichero plist de la aplicación, debemos indicar los datos referentes al servicio. Que indicará al sistema como llamar y como mostrar la información asociada.</p>
<p><pre class="brush: xml;">
	&lt;key&gt;NSServices&lt;/key&gt;
	&lt;array&gt;
		&lt;dict&gt;
			&lt;key&gt;NSMenuItem&lt;/key&gt;
			&lt;dict&gt;
				&lt;key&gt;default&lt;/key&gt;
				&lt;string&gt;Wikipedia Search&lt;/string&gt;
			&lt;/dict&gt;
			
			&lt;key&gt;NSKeyEquivalent&lt;/key&gt;
            &lt;dict&gt;
                &lt;key&gt;default&lt;/key&gt;
                &lt;string&gt;R&lt;/string&gt;
            &lt;/dict&gt;
			
			&lt;key&gt;NSMessage&lt;/key&gt;
			&lt;string&gt;wikipediaSearch&lt;/string&gt;
			
			&lt;key&gt;NSPortName&lt;/key&gt;
			&lt;string&gt;WikipediaService&lt;/string&gt;
			
			&lt;key&gt;NSSendTypes&lt;/key&gt;
			&lt;array&gt;
				&lt;string&gt;NSStringPboardType&lt;/string&gt;
				&lt;string&gt;NSPasteboardTypeString&lt;/string&gt;
			&lt;/array&gt;			
		&lt;/dict&gt;
	&lt;/array&gt;
</pre></p>
<p style="text-align:justify;">Si os fijáis, en el campo, NSKeyEquivalent, podemos asignar una tecla, que sumada a Command, sera el shortcut para llamar a nuestro servicio. Si dicha letra esta en mayúsculas, ademas necesitaremos pulsar Shift.</p>
<p style="text-align:justify;">Con todo ya terminado, solo nos queda instalarlo, para ello debemos copiar el &#8220;Bundle&#8221; que ha generado nuestro proyecto en XCode a ~/Library/Services. Para que el servicio sea reconocido, debemos cerrar sesion y volverla a inciar, pero existe una forma manual para forzar al sistema para que reconstruya el indice de servicios.</p>
<p style="text-align:justify;">Esto es ejecutando el siguiente comando: /System/Library/CoreServices/pbs</p>
<p style="text-align:justify;">Una vez que tenemos nuestro servicio instalado, solo tenemos que seleccionar cualquier texto para buscarlo en la wikipedia.</p>
<p><a href="http://zbutton.files.wordpress.com/2011/01/screen-shot-2011-01-16-at-01-14-33.png"><img src="http://zbutton.files.wordpress.com/2011/01/screen-shot-2011-01-16-at-01-14-33.png?w=450&#038;h=243" alt="" title="Wikipedia Service" width="450" height="243" class="aligncenter size-full wp-image-470" /></a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/zbutton.wordpress.com/466/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/zbutton.wordpress.com/466/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/zbutton.wordpress.com/466/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/zbutton.wordpress.com/466/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/zbutton.wordpress.com/466/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/zbutton.wordpress.com/466/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/zbutton.wordpress.com/466/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/zbutton.wordpress.com/466/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/zbutton.wordpress.com/466/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/zbutton.wordpress.com/466/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/zbutton.wordpress.com/466/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/zbutton.wordpress.com/466/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/zbutton.wordpress.com/466/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/zbutton.wordpress.com/466/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=zbutton.wordpress.com&amp;blog=8076436&amp;post=466&amp;subd=zbutton&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://zbutton.wordpress.com/2011/01/16/construyendo-un-servicio-en-osx/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b5e8b84400b6903e4436e0489905e051?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">robjperez</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2011/01/screen-shot-2011-01-07-at-22-51-05.png" medium="image">
			<media:title type="html">OSX Services</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2011/01/screen-shot-2011-01-16-at-01-14-33.png" medium="image">
			<media:title type="html">Wikipedia Service</media:title>
		</media:content>
	</item>
		<item>
		<title>Manejando Safari desde Objetive-C</title>
		<link>http://zbutton.wordpress.com/2011/01/02/manejando-safari-desde-objetive-c/</link>
		<comments>http://zbutton.wordpress.com/2011/01/02/manejando-safari-desde-objetive-c/#comments</comments>
		<pubDate>Sun, 02 Jan 2011 19:52:08 +0000</pubDate>
		<dc:creator>robjperez</dc:creator>
				<category><![CDATA[mac]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[programacion]]></category>
		<category><![CDATA[ipc]]></category>
		<category><![CDATA[safari]]></category>

		<guid isPermaLink="false">http://zbutton.wordpress.com/?p=456</guid>
		<description><![CDATA[Recientemente me surgió la necesidad de controlar remotamente un explorador web en Windows. En el sistema operativo de Microsoft, gracias a los objetos COM, es posible &#8220;instanciar&#8221; un objeto InternetExplorer y controlarlo desde código fuente. Gracias a .NET y la Interoperabilidad con los objetos COM, la tarea inicialmente no parece ser para nada complicada, aunque [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=zbutton.wordpress.com&amp;blog=8076436&amp;post=456&amp;subd=zbutton&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://zbutton.files.wordpress.com/2010/06/safari-logo1.png"><img src="http://zbutton.files.wordpress.com/2010/06/safari-logo1.png?w=450" alt="" title="Safari Logo"   class="alignleft size-full wp-image-327" /></a>
<p style="text-align:justify;">Recientemente me surgió la necesidad de controlar remotamente un explorador web en Windows. En el sistema operativo de Microsoft, gracias a los objetos COM, es posible &#8220;instanciar&#8221; un objeto InternetExplorer y controlarlo desde código fuente. Gracias a .NET y la Interoperabilidad con los objetos COM, la tarea inicialmente no parece ser para nada complicada, aunque como la compañía de Redmond nos tiene acostumbrados, lidiar con los detalles será una tarea que nos llevará bastante tiempo.</p>
<p style="text-align:justify;">En OSX por su parte este objetivo también esta cubierto, y como pasa habitualmente, de una forma bastante más elegante <img src='http://s0.wp.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> .</p>
<p style="text-align:justify;">La idea es poder controlar, y crear instancias de una aplicación que esta ejecutandose, o que vamos a iniciar. Para ello, como requisito imprescindible, la aplicación debe estar preparada para ser manejada.</p>
<p style="text-align:justify;">El componente clave para que todo esto se pueda realizar son los denominados &#8220;Apple Event&#8221;, que son paquetes de información que se envían en forma de mensaje entre las diferente aplicaciones que se están ejecutando en el Sistema Operativo.</p>
<p style="text-align:justify;">Por ejemplo, si queremos que el Safari en ejecución navegue a una URL, y eso lo queremos hacer desde nuestra aplicación, deberemos enviar un Apple Event que contenga los datos necesarios para llevar a cabo esa acción.</p>
<p style="text-align:justify;">Originalmente, solo era posible enviar eventos usando AppleScript, de hecho, el lenguaje se creo alrededor de dichos eventos. Pero hoy en día se puede utilizar multitud de lenguajes para enviar &#8220;Apple Events&#8221; como Python, C#, Ruby o Javascript.</p>
<p style="text-align:justify;">Lo que hace posible esta interoperabilidad de lenguajes es lo que se conoce como el Scripting Bridge, como ya hablamos en el blog cuando queríamos <a href="http://zbutton.wordpress.com/2010/04/28/otra-manera-de-programar-en-cocoa-ruby-y-python/" target="_blank">usar Python para controlar el iTunes.</a></p>
<p style="text-align:justify;">A diferencia de la entrada anterior, en esta entrada, vamos a usar Objecitve-C para controlar el Navegador Web, dado que ObjC es un lenguaje compilado, necesitamos tener una referencia de lo que podemos hacer con el &#8220;objeto&#8221; Safari, de tal manera que podamos compilar nuestro código.</p>
<p style="text-align:justify;">Para ello usamos el comando sdp, que generará un fichero .h y que usaremos para compilar nuestro código. La entrada del comando sdp son los ficheros .sdef, que contienen, en forma de XML, una descripción sobre lo que se puede hacer con el objeto en cuestión.</p>
<p style="text-align:justify;">A nivel de controlar el Navegador, una de las cosas mas utiles es que podemos ejecutar código javascript, con lo que tenemos acceso a todo el documento web que estamos visualizando.</p>
<p style="text-align:justify;">A continuación os dejo un fragmento de código que navega a google, realiza una busqueda usando javascript y muestra el numero de resultados encontrados.</p>
<p><pre class="brush: objc;">
SafariApplication* safari = [SBApplication 
  applicationWithBundleIdentifier:@&quot;com.apple.Safari&quot;];
	
SBElementArray* windows = [safari windows];
SafariTab* currentTab = [[windows objectAtIndex: 0] currentTab];
	
[currentTab setURL:@&quot;http://www.google.com&quot;];
[safari doJavaScript: 
 @&quot;document.getElementsByName('q')[0].value = 'Safari'&quot; 
				  in:currentTab];
[safari doJavaScript: @&quot;document.forms[0].submit()&quot; 
				  in: currentTab];
id result = [safari 
   doJavaScript:@&quot;document.getElementById('resultStats').firstChild.data&quot;
           in:currentTab];
NSLog(@&quot;Results: %@&quot;, (NSString*)result);
</pre></p>
<p style="text-align:justify;">Un uso en el que esta técnica es útil es cuando queremos hacer pruebas automatizadas de alguna web que estemos realizando. Aunque para estas tareas existe <a href="http://seleniumhq.org/">selenium</a>, que si utilizamos firefox, seguramente cubra nuestras necesidades.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/zbutton.wordpress.com/456/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/zbutton.wordpress.com/456/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/zbutton.wordpress.com/456/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/zbutton.wordpress.com/456/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/zbutton.wordpress.com/456/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/zbutton.wordpress.com/456/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/zbutton.wordpress.com/456/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/zbutton.wordpress.com/456/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/zbutton.wordpress.com/456/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/zbutton.wordpress.com/456/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/zbutton.wordpress.com/456/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/zbutton.wordpress.com/456/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/zbutton.wordpress.com/456/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/zbutton.wordpress.com/456/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=zbutton.wordpress.com&amp;blog=8076436&amp;post=456&amp;subd=zbutton&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://zbutton.wordpress.com/2011/01/02/manejando-safari-desde-objetive-c/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b5e8b84400b6903e4436e0489905e051?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">robjperez</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2010/06/safari-logo1.png" medium="image">
			<media:title type="html">Safari Logo</media:title>
		</media:content>
	</item>
		<item>
		<title>Anillo de Mensajes en Erlang</title>
		<link>http://zbutton.wordpress.com/2010/12/24/anillo-de-mensajes-en-erlang/</link>
		<comments>http://zbutton.wordpress.com/2010/12/24/anillo-de-mensajes-en-erlang/#comments</comments>
		<pubDate>Fri, 24 Dec 2010 15:51:24 +0000</pubDate>
		<dc:creator>robjperez</dc:creator>
				<category><![CDATA[erlang]]></category>
		<category><![CDATA[funcional]]></category>

		<guid isPermaLink="false">http://zbutton.wordpress.com/?p=443</guid>
		<description><![CDATA[Desde hace algún tiempo, llevo investigando el mundo de la programación funcional. Después de probar varios lenguajes como F#, o Clojure, finalmente me decanté por Erlang. La verdad es que estoy pasandomelo bien recordando los viejos tiempos de Lisp o Prolog , y sobre todo aprendiendo una forma diferente de afrontar los problemas. Para el [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=zbutton.wordpress.com&amp;blog=8076436&amp;post=443&amp;subd=zbutton&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://zbutton.files.wordpress.com/2010/12/erlang-logo.png"><img src="http://zbutton.files.wordpress.com/2010/12/erlang-logo.png?w=450" alt="" title="erlang-logo"   class="alignleft size-full wp-image-453" /></a></p>
<p style="text-align:justify;">Desde hace algún tiempo, llevo investigando el mundo de la programación funcional. Después de probar varios lenguajes como F#, o Clojure, finalmente me decanté por Erlang.</p>
<p style="text-align:justify;">La verdad es que estoy pasandomelo bien recordando los viejos tiempos de Lisp o Prolog <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> , y sobre todo aprendiendo una forma diferente de afrontar los problemas.</p>
<p style="text-align:justify;">Para el aprendizaje, mi libro de cabecera es <a href="http://www.pragprog.com/titles/jaerlang/programming-erlang">Programming Erlang</a> de la editorial Pragmatic Bookshelf. Libro que me esta gustando bastante, ya que asume que no tienes ni idea de programación funcional, como era mi caso.</p>
<p style="text-align:justify;">Quizás para otro post os pueda contar algo de los beneficios que tiene la programación funcional, como por ejemplo, lo bien que escalan en entornos multiprocesador y lo robustos que son para entornos multihilo, gracias a la eliminación de los &#8220;side-effects&#8221;.</p>
<p style="text-align:justify;">En dicho libro se plantea un ejercio en el que se pide que se cree un &#8220;anillo&#8221; de M procesos, de tal manera que enviando un mensaje a uno de esos procesos, dicho mensaje circule por el anillo N veces.</p>
<p style="text-align:justify;">Una vez que se tiene la estructura, se pide que se mida el tiempo que tarda en circular los M*N mensajes, se compare con lo mismo hecho en otro lenguaje de programación (preferiblemente no funcional) y después que se publique en un blog.</p>
<p style="text-align:justify;">Así que obediente de mi, aqui os dejo la primera parte, el ejercicio hecho en Erlang. Para otra entrada dejo la comparación con lo mismo hecho en otro lenguaje <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><pre class="brush: erlang;">
-module(ring).
-export([ringtest/2, ringNode/1]).

ringNode(PPid) -&gt;
	receive
		{exit} -&gt;
			PPid!{exit},
			true;
		{0} -&gt;
			PPid!{exit},
			true;
		{N} -&gt;
			PPid!{(N-1)},
			ringNode(PPid)
	end.

ringtest(N, M) -&gt;
	ringtest(N-2, self(), N*(M-1)).

ringtest(0, ThisPid, M) -&gt;
	Pid = spawn(ring, ringNode, [ThisPid]),
	Pid!{M},
	ringNode(Pid);
ringtest(N, ThisPid, M) -&gt;
	Pid = spawn(ring, ringNode, [ThisPid]),
	ringtest(N-1, Pid, M).
</pre></p>
<p><a href="http://zbutton.files.wordpress.com/2010/12/erlang.png"><img src="http://zbutton.files.wordpress.com/2010/12/erlang.png?w=450&#038;h=138" alt="" title="erlang" width="450" height="138" class="aligncenter size-full wp-image-450" /></a></p>
<p style="text-align:justify;">Analizando los tiempos (que están en microsegundos), lo cierto es que erlang es bastante rápido, tanto en crear procesos como en enviar mensajes entre ellos. El ordenador que ejecuto el programa era un ATOM  D525 de 1.8Ghz y en crear 5000 procesos, y enviar el mensaje 100 veces alrededor del anillo, sólo tardó 1,2 segundos. Sin duda, una cifra bastante interesante.</p>
<p style="text-align:justify;">Despueés de ver estos números, esta claro que no es casulidad que sea una de las plataformas preferidas a la hora de desarrollar aplicaciones que se muevan en estos tipos de entornos.</p>
<p style="text-align:justify;">No soy ningun experto de Erlang, de hecho aun estoy aprendiendo, así que alguien lo lee y tiene algún comentario, serán bienvenidos!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/zbutton.wordpress.com/443/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/zbutton.wordpress.com/443/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/zbutton.wordpress.com/443/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/zbutton.wordpress.com/443/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/zbutton.wordpress.com/443/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/zbutton.wordpress.com/443/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/zbutton.wordpress.com/443/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/zbutton.wordpress.com/443/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/zbutton.wordpress.com/443/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/zbutton.wordpress.com/443/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/zbutton.wordpress.com/443/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/zbutton.wordpress.com/443/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/zbutton.wordpress.com/443/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/zbutton.wordpress.com/443/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=zbutton.wordpress.com&amp;blog=8076436&amp;post=443&amp;subd=zbutton&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://zbutton.wordpress.com/2010/12/24/anillo-de-mensajes-en-erlang/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b5e8b84400b6903e4436e0489905e051?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">robjperez</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2010/12/erlang-logo.png" medium="image">
			<media:title type="html">erlang-logo</media:title>
		</media:content>

		<media:content url="http://zbutton.files.wordpress.com/2010/12/erlang.png" medium="image">
			<media:title type="html">erlang</media:title>
		</media:content>
	</item>
	</channel>
</rss>
