<?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/"
	>

<channel>
	<title>NSCoders Barcelona</title>
	<atom:link href="http://bcn.nscoders.org/feed" rel="self" type="application/rss+xml" />
	<link>http://bcn.nscoders.org</link>
	<description>El BLog de los NSCoders de la Ciudad Condal</description>
	<lastBuildDate>Fri, 19 Oct 2012 04:32:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>Trabajando con el Social Framework de iOS 6: SLRequest, publicar en Twitter y obtener el Timeline</title>
		<link>http://bcn.nscoders.org/2012/10/16/trabajando-con-el-social-framework-de-ios-6-slrequest-publicar-en-twitter-y-obtener-el-timeline.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=trabajando-con-el-social-framework-de-ios-6-slrequest-publicar-en-twitter-y-obtener-el-timeline</link>
		<comments>http://bcn.nscoders.org/2012/10/16/trabajando-con-el-social-framework-de-ios-6-slrequest-publicar-en-twitter-y-obtener-el-timeline.html#comments</comments>
		<pubDate>Tue, 16 Oct 2012 18:07:47 +0000</pubDate>
		<dc:creator>ThXou</dc:creator>
				<category><![CDATA[IOs]]></category>
		<category><![CDATA[NSBlog]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[XCode]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iOS 6]]></category>
		<category><![CDATA[SLRequest]]></category>
		<category><![CDATA[Social Framework]]></category>
		<category><![CDATA[ThXou]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://bcn.nscoders.org/?p=289</guid>
		<description><![CDATA[Aquí traigo un tutorial de iOS 6, hoy toca Twittear (o como se escriba) y mostrar nuestro timeline de Twitter en una aplicación. Antes cuando queríamos comunicarnos con Twitter y obtener datos y actualizarlos había que hacer una conexión a través de OAuth con unos tokens y secret-keys, esto normalmente se hacía más digerible usando algún [...]]]></description>
			<content:encoded><![CDATA[<p>Aquí traigo un tutorial de <strong>iOS 6</strong>, hoy toca Twittear (o como se escriba) y mostrar nuestro timeline de Twitter en una aplicación.</p>
<p>Antes cuando queríamos comunicarnos con Twitter y obtener datos y actualizarlos había que hacer una conexión a través de OAuth con unos tokens y secret-keys, esto normalmente se hacía más digerible usando algún framework o clase externa que servía de interfaz de conexión entre el cliente y el servicio. Desde la llegada del framework de Twitter y la integración con iOS 5 las cosas se pusieron extraordinariamente más fáciles, esto nos permitió el intercambio de datos con Twitter en tan solo pocos pasos.</p>
<p>En el Social Framework tenemos una clase llamada <code>SLRequest</code>, muy similar a <code>TWRequest</code> del framework de twitter. Esta clase encapsula las propiedades de una petición HTTP en métodos fáciles de utilizar, con los cuales enviamos peticiones a Twitter para poder obtener y actualizar datos de nuestras cuentas configuradas en el dispositivo.</p>
<p>Básicamente enviamos una petición HTTP con unos parámetros que configuran lo que queremos llevar a cabo en el servicio, si Twitter dice que no pasa nada, recibimos una respuesta con unos datos que tenemos que manipular y mostrar al usuario, caso contrario recibimos una información de error.</p>
<h2>Autenticando la petición</h2>
<p>Como les decía párrafos atrás, antes había que usar tokens y secret-keys para autenticarnos en Twitter y así poder validar nuestras peticiones. Con el Social Framework hacemos lo mismo pero de forma automática, más transparente al usuario, y en cierta forma al desarrollador, ya que en ningún momento tenemos que manipular tokens.</p>
<p>Desde iOS 5 tenemos el Accounts Framework, el cual provee un sistema centralizado de cuentas de usuario. A través de el se almacenan todas las cuentas de Twitter (Y de otros servicios) configuradas en el dispositivo: información de usuario y contraseña y demás, esto nos permite saltarnos esa típica ventana de inicio de sesión sin tener que preocuparnos por proveer un sistema para almacenar nosotros mismos las credenciales.</p>
<p>Hay pocas cosas que podemos hacer sin autenticación de usuario, y obtener el timeline es una de ellas. No obstante para hacer que esto funcione con cualquier cuenta, centralizaremos todas las peticiones en las cuentas obtenidas de la base de datos de cuentas del dispositivo. Empecemos:</p>
<p>Lo primero será importar los frameworks:</p>
<pre>#import &lt;Accounts/Accounts.h&gt;
#import &lt;Social/Social.h&gt;</pre>
<p>Luego hacemos la mágia de obtener las cuentas del dispositivo con el Accounts Framework:</p>
<pre>ACAccountStore *accountStore = [[ACAccountStore alloc] init];

// creamos un objeto accountType especificando que solo queremos obtener
// las cuentas de Twitter
ACAccountType *accountType = [accountStore
              accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];

[accountStore requestAccessToAccountsWithType:accountType
                                      options:nil
                                   completion:^(BOOL granted, NSError *error)
{
    if (granted)
    {
        // guardamos las cuentas de twitter en un array
        NSArray *accountsArray = [accountStore accountsWithAccountType:accountType];
        // armamos la petición aquí
    }
    else {
        NSLog(@"Error no se pudo acceder a las cuentas");
    }
}];</pre>
<p>Lo que hacemos aquí es crear una instancia de la base de datos de cuentas. Luego a través de la clase <code>ACAccountType</code> decimos que solo queremos las cuentas de Twitter, pasándole la constante  <code>ACAccountTypeIdentifierTwitter</code> como argumento en la inicialización. Acto seguido pedimos acceso a las cuentas con el método <code>requestAccessToAccountsWithType:options:completion:</code>. Este método tiene como argumento el bloque <code>completion:</code>, el cual es un handler (Un objeto &#8220;manipulador&#8221; por así decirlo) en cuyos parámetros es devuelta la respuesta del método. Si todo va bien almacenamos todas las cuentas obtenidas en el array <code>accountsArray</code> o mostramos un error en caso contrario. Simple.</p>
<p>Recueda esta dinámica de ejecutar un método y recibir una respuesta para ser manipulada en un bloque, porque lo verás muy a menudo desde ahora.</p>
<h2>Contruyendo la petición para obtener el timeline</h2>
<p>Con el Social Framework es definitivamente mucho más fácil construir una petición HTTP. Sabemos que está compuesta por:</p>
<ol>
<li>Una URL que identifica la operación que queremos realizar en el servicio.</li>
<li>Un método de petición, que puede ser GET, POST o DELETE.</li>
<li>Y unos parámetros de configuración.</li>
</ol>
<p>El método <code>requestForServiceType:requestMethod:URL:parameters:</code> pasa todos estos datos como sus argumentos y esto nos permite crear la petición en tan solo una línea de código si así lo deseamos.</p>
<p>Lo que nosotros queremos es obtener el timeline, por lo tanto necesitamos ir a la <a title="Versión 1.1 de la API de Twitter" href="http://securelink.thxou.com/?https://dev.twitter.com/docs/api/1.1" target="_blank">documentación oficial</a> para ver lo que tenemos que usar. Al entrar en el enlace y seleccionar la operación de la que queremos ver los detalles (en este caso es: <code>GET</code> <code>statuses/home_timeline</code>), veremos en el apartado <strong>Resourse Information</strong> cierta información muy importante:</p>
<p style="text-align: center"><img class="size-full wp-image-2326 aligncenter" src="http://www.thxou.com/wp-content/uploads/2012/09/Screen-Shot-2012-09-11-at-17.08.28.png" alt="" width="249" height="392" /></p>
<p>Tenemos el método de la petición (GET), el formato de respuesta (JSON) y el objeto de respuesta (Tweets). Luego está el apartado <strong>Resource URL</strong> que es la URL que le pasaremos y el apartado <strong>Parameters</strong>, que contiene los parámetros para configurarla. Usando esta información construimos la petición:</p>
<pre>// guardamos la cuenta
ACAccount *twitterAccount = [accountsArray objectAtIndex:0];
self.cuenta = twitterAccount;

// creamos la petición
NSURL *url = [NSURL URLWithString:
                    @"https://api.twitter.com/1.1/statuses/home_timeline.json"];

NSDictionary *parametros = [NSDictionary dictionaryWithObjectsAndKeys:
                                @"25", @"count", nil];

SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter
                                        requestMethod:SLRequestMethodGET
                                                  URL:url
                                           parameters:parametros];

// asociamos la cuenta a la petición
[request setAccount:twitterAccount];</pre>
<p>Por motivos de brevedad tan solo utilizaremos la primera cuenta de las que hay en el array.</p>
<p>He creado la propiedad <code>cuenta</code> de tipo <code>ACAccount</code>, en ella almacenamos esta cuenta para posteriormente poder enviarla al controlador desde el que publicaremos un mensaje de estado (lo que es un Tweet) a nuestro timeline, esto más adelante.</p>
<p>Como pueden ver tenemos un diccionario para los parámetros. El mío solo tiene una key: <code>count</code>, esta nos permite limitar la cantidad de tweets que nos va a devolver el timeline que por defecto es 20, pero yo la he puesto a 25. En la documentación de la API están todos los parámetros que podemos usar para configurar la petición.</p>
<p>Lo siguiente es asignarle a la propiedad <code>account</code> de nuestra petición, la cuenta que hemos elegido del array y con la que queremos trabajar para mostrar el timeline y demás cosas.</p>
<h2>Enviando la petición y manipulando los resultados</h2>
<p>Una vez construida la petición procedemos a enviarla. Para esto usamos el método <code>performRequestWithHandler:</code> que envía la petición y recoge los resultados en su único argumento. Este es a su vez un bloque, el cual es ejecutado una vez están disponibles los datos de la respuesta.</p>
<pre>// realizamos la petición especificando un método para manipular la respuesta
[request performRequestWithHandler:
^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error)
{
    if (responseData != nil)
    {
        self.tweets = [NSJSONSerialization JSONObjectWithData:responseData
                                                      options:kNilOptions
                                                        error:&amp;error];
    }
}];</pre>
<p>Este bloque tiene 3 parámetros, el más importante es <code>responseData</code>, porque es el que va a contener los tweets. Estos tweets están en formato JSON como vimos antes, por lo tanto necesitamos parsearlos y así pasarlos a un formato manipulable en Objective-c. Para hacer esto existe la clase <code>NSJSONSerialization</code>, que coge los datos en <code>NSData</code> (en este caso <code>responseData</code>), los parsea y devuelve. Estos datos devueltos los almacenamos en el array <code>tweets</code>, que a continuación usaremos para mostrarlos al usuario.</p>
<h2>Mostrando los resultados</h2>
<p>Bien, ya tenemos hecho casi todo el trabajo, ahora solo nos queda mostrar los resultados, y para esto tenemos el objeto <code>tweetsTableView</code>. Debido a que ya tenemos todos los Tweets en un array, es relativamente sencillo mostrarlos en el tableView, por eso vamos directamente a implementar los métodos convenientes:</p>
<pre>- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView
                                  numberOfRowsInSection:(NSInteger)section
{
    return [self.tweets count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView
            cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
                                                      CellIdentifier];
    if (cell == nil)
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
                                                    reuseIdentifier:CellIdentifier] autorelease];
    }

    NSDictionary *tweet = [self.tweets objectAtIndex:indexPath.row];

    cell.textLabel.text = [tweet objectForKey:@"text"];
    cell.detailTextLabel.text = [[tweet objectForKey:@"user"]
                           objectForKey:@"screen_name"];

    // cargamos las imágenes de los que envían el tweet de forma asíncrona
    dispatch_queue_t queue = dispatch_queue_create("com.thxou.totweet", NULL);
    dispatch_queue_t main = dispatch_get_main_queue();

    dispatch_async(queue, ^{
        NSURL *imageURL = [NSURL URLWithString:[[tweet objectForKey:@"user"]
                                            objectForKey:@"profile_image_url"]];
        NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
        dispatch_async(main, ^{
            cell.imageView.image = [UIImage imageWithData:imageData];
        });
    });
    dispatch_release(queue);

    return cell;
}</pre>
<p>Aquí hay algunas líneas que les sonarán a chino, no obstante explicaré un poco por encima que está sucediendo.</p>
<p>Al parsearse los datos estos son almacenados en el array tweets, pero los tweets dentro de el son almacenados en forma de diccionarios, fácilmente recuperables usando la clase <code>NSDictionary</code>. Entonces recuperamos cada campo de ese array en un diccionario que yo he llamado <code>tweet</code> para hacerlo más identificable (en realidad eso es lo que representa). Como ya saben, accedemos a los valores de un diccionario a través de <em>keys</em>, pero cuales son estas keys?, nos vamos a la <a href="https://dev.twitter.com/docs/platform-objects/tweets">documentación oficial</a> y lo miramos allí. Lo que hacemos es simplemente mostrar el texto del tweet como título y el nombre &#8220;del que tweetea&#8221; como subtitulo en cada celda.</p>
<p>Para mostrar la imagen lo que hacemos es usar el <strong>GCD</strong> (Grand Central Dispatch) de Apple. A grandes rasgos explicarles que la descarga de datos de la red siempre debería de ser de forma asíncrona, esto es porque es un proceso que tarda un poco en llevarse a cabo y por lo tanto no puede hacerse en el mismo thread (hilo) ya que podemos bloquearlo, y esto dejaría inutilizable la interfaz de usuario hasta que se complete el proceso, cosa que por el bien de nuestros usuarios, no queremos. Pues este problema lo soluciona el <strong>GCD</strong>, haciendo que ciertos métodos se ejecuten de forma asíncrona (en otro hilo o thread), de esta forma evitamos bloquear la interfaz de usuario.</p>
<p><a href="http://www.thxou.com/wp-content/uploads/2012/09/Screen-Shot-2012-09-20-at-14.23.29.png"><img class="aligncenter" src="http://www.thxou.com/wp-content/uploads/2012/09/Screen-Shot-2012-09-20-at-14.23.29.png" alt="" width="319" height="479" /></a></p>
<h2>Enviando un tweet</h2>
<p>Pues hacer esto es un poco más de lo mismo. Yo he creado un nuevo controlador para hacer esto llamado <code>EnviarTweetViewController</code>, el cual se muestra en una ventana modal y tiene un TextView y dos botones: uno para enviar el tweet y otro para cancelar la operación.</p>
<p>El de enviar el tweet ejecuta el método <code>enviarTweet:</code>:</p>
<pre>- (IBAction)enviarTweet:(id)sender
{
    // comprobamos si el campo para escrbir el tweet no está vacío
    if (![self.tweet.text isEqualToString:@""])
    {
        NSURL *url = [NSURL URLWithString:
                           @"https://api.twitter.com/1.1/statuses/update.json"];

        NSDictionary *parametros = [NSDictionary dictionaryWithObjectsAndKeys:
                                    self.tweet.text, @"status", nil];

        SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter
                                                requestMethod:SLRequestMethodPOST
                                                          URL:url
                                                   parameters:parametros];

        // Set the account used to post the tweet.
        [request setAccount:self.cuenta];

        // Perform the request created above and create a handler block
        //to handle the response.
        [request performRequestWithHandler:
        ^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error)
         {
             NSDictionary *resultado = [NSJSONSerialization
                                       JSONObjectWithData:responseData
                                                           options:kNilOptions
                                                             error:&amp;error];
         }];

        [self cancelar:nil];
    }
}</pre>
<p>Como podéis observar se hace exactamente lo mismo. Tan solo cambian los parámetros, la URL y el método de la petición, y todo esto lo podemos encontrar en la documentación oficial.</p>
<p>A diferencia del anterior, aquí no accedemos a todas las cuentas del dispositivo, sino que simplemente pasamos a este controlador la cuenta que hemos obtenido antes, así nos aseguramos de que la cuenta que está seleccionada es desde la que se envía el tweet y sobre la que se hacen las operaciones solicitadas. No hay misterio.</p>
<h2>Conclusión</h2>
<p>El procedimiento para llevar a cabo todas estas acciones en Twitter llevan la misma estructura. Tan solo varían los parámetros, la URL y el método de la petición. Por lo que, si queremos hacer cualquier cosa,  tenemos que ir a la documentación y mirar lo que necesitamos. Luego reemplazar los datos que hemos visto antes con los nuevos, enviar la petición y mostrar al usuario los datos obtenidos. Así de fácil es trabajar con el Social Framework.</p>
<p>Ahora puedes pasarte por la <a href="http://securelink.thxou.com/?https://developer.apple.com/library/ios/documentation/Social/Reference/SLRequest_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40012234">documentación de Apple</a> sobre este tema y también visitar <a href="http://www.thxou.com/2012/09/11/parsear-y-crear-ficheros-en-formato-json-en-ios/">este tutorial </a>sobre como parsear y manipular ficheros JSON de forma nativa y así extender un poco más tus conocimientos.</p>
<p style="text-align: center"><em>Descarga los archivos del tutorial <a href="https://www.box.com/s/c0bb4xgyatv10t5nhvll">haciendo click aquí</a>.</em></p>
<p style="text-align: right">Fuente | <a href="http://www.thxou.com/2012/09/20/trabajando-con-el-social-framework-de-ios-6-publicar-en-twitter-y-obtener-el-timeline/">ThXou.com</a></p>
]]></content:encoded>
			<wfw:commentRss>http://bcn.nscoders.org/2012/10/16/trabajando-con-el-social-framework-de-ios-6-slrequest-publicar-en-twitter-y-obtener-el-timeline.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reconocimiento facial en iOS 5 con Core Image</title>
		<link>http://bcn.nscoders.org/2012/06/10/reconocimiento-facial-en-ios-5-con-core-image.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=reconocimiento-facial-en-ios-5-con-core-image</link>
		<comments>http://bcn.nscoders.org/2012/06/10/reconocimiento-facial-en-ios-5-con-core-image.html#comments</comments>
		<pubDate>Sun, 10 Jun 2012 20:44:25 +0000</pubDate>
		<dc:creator>rais38</dc:creator>
				<category><![CDATA[IOs]]></category>
		<category><![CDATA[NSBlog]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[XCode]]></category>
		<category><![CDATA[Core]]></category>
		<category><![CDATA[facial]]></category>
		<category><![CDATA[Image]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[reconocimiento]]></category>
		<category><![CDATA[UIKit]]></category>

		<guid isPermaLink="false">http://bcn.nscoders.org/?p=261</guid>
		<description><![CDATA[En 2010, Apple compró una empresa especializada en algoritmos de reconocimiento facial (Polar Rose &#8211; Suecia). Gracias a esta adquisición y a partir de iOS 5, Apple hizo pública una API incluida en Core Image donde podremos hacer cosas como esta &#8220;recognizr&#8221;. Así que vamos a entrar en materia y veremos como poder implantarlo en nuestro [...]]]></description>
			<content:encoded><![CDATA[<p>En 2010, Apple compró una empresa especializada en algoritmos de reconocimiento facial (<a href="http://9to5mac.com/2010/09/20/apple-buys-swedish-face-recognition-company-polar-rose/" target="_blank">Polar Rose &#8211; Suecia</a>). Gracias a esta adquisición y a partir de <strong>iOS 5</strong>, Apple hizo pública una API incluida en Core Image donde podremos hacer cosas como esta <a href="http://www.youtube.com/embed/0QBLKBYrgvk">&#8220;recognizr&#8221;</a>.</p>
<p>Así que vamos a entrar en materia y veremos como poder implantarlo en nuestro propio proyecto (<em>Talk is cheap, SHOW ME THE CODE!</em>).</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="text-decoration: underline;"><em>Empezamos</em></span></p>
<p>&nbsp;</p>
<p>- Vamos a crear un nuevo proyecto en Xcode, para este ejemplo he utilizado<em> &#8220;Single View Application&#8221; </em>(DetectorCaras)</p>
<p>- Importamos los frameworks<em> Core Image y QuartzCore </em>al fichero de implementación de ViewController (ViewController.m)</p>
<p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://www.ingens-networks.com/blog/image.axd?picture=2012%2f4%2fcapt1.jpg" alt="" /></p>
<pre class="brush: objc;">#import &lt;CoreImage/CoreImage.h&gt;
#import &lt;QuartzCore/QuartzCore.h&gt;</pre>
<p style="text-align: center;">&nbsp;</p>
<p>- Añadimos al proyecto una imagen en la cual deberá aparecer mínimo una cara.</p>
<p>- Incluimos el método <em>faceDetector</em> (lo podéis llamar como queráis) para añadir la imagen,seleccionada anteriormente, a la pantalla.</p>
<p>&nbsp;</p>
<pre class="brush: objc;">-(void)faceDetector
{
    // Carga la imagen de la cara
    UIImageView *imagen = [[UIImageView alloc]
initWithImage:[UIImage imageNamed:@"megan.jpg"]];

    // La añadimos a nuestra vista
    [self.view addSubview:imagen];

    // Llamamos al método markFaces para poder detectar los rostros y
    // sí los detecta pintarlos en pantalla
    [self markFaces:imagen];
}</pre>
<p>- Ahora vamos a añadir el método <em>markFaces:</em> con el que detectaremos si existen caras en la imagen.</p>
<pre class="brush: objc;">-(void)markFaces:(UIImageView *)imagenCara
{
    CIImage *imagen = [CIImage imageWithCGImage:imagenCara.image.CGImage];
    // Para el detector, utilizamos la constante "CIDetectorAccuracyHigh" la cual
    // nos proporciona una precisión mejor pero requiere más tiempo de procesado
    // Más info en http://goo.gl/ahfoU
    CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeFace
    context:nil options:[NSDictionary dictionaryWithObject:CIDetectorAccuracyHigh
    forKey:CIDetectorAccuracy]];

    // Creamos un array con todas las caras detectadas en la imagen
    NSArray *features = [detector featuresInImage:imagen];

    // Hacemos un bucle por si detecta más de un rostro en la imagen
    for (CIFaceFeature *faceFeature in features) {
        // Obtener el ancho de la cara
        CGFloat faceWidth = faceFeature.bounds.size.width;

        // UIView usando las dimensiones de la cara detectada
        UIView *faceView = [[UIView alloc] initWithFrame:faceFeature.bounds];

        // Añadimos un borde alrededor del UIView
        faceView.layer.borderWidth = 1;
        faceView.layer.borderColor = [[UIColor blueColor] CGColor];

        [self.view addSubview:faceView];

        // Ojo derecho
        if (faceFeature.hasRightEyePosition) {
            // Creamos una UIView con el tamaño del ojo derecho
            UIView *rightEye = [[UIView alloc] initWithFrame:CGRectMake
            (faceFeature.rightEyePosition.x - faceWidth * 0.15,
            faceFeature.rightEyePosition.y -
            faceWidth * 0.15, faceWidth * 0.3, faceWidth * 0.3)];

            rightEye.backgroundColor = [[UIColor redColor]
            colorWithAlphaComponent:0.4];
            rightEye.center = faceFeature.rightEyePosition;

            rightEye.layer.cornerRadius = faceWidth * 0.15;
            [self.view addSubview:rightEye];
        }

        // Ojo izquierdo
        if (faceFeature.hasLeftEyePosition) {
            // Creamos una UIView con el tamaño del ojo izquierdo
            UIView *leftEye = [[UIView alloc] initWithFrame:CGRectMake
            (faceFeature.leftEyePosition.x - faceWidth * 0.15,
            faceFeature.leftEyePosition.y -
            faceWidth * 0.15, faceWidth * 0.3, faceWidth * 0.3)];

            leftEye.backgroundColor = [[UIColor redColor] colorWithAlphaComponent:0.4];
            leftEye.center = faceFeature.leftEyePosition;

            leftEye.layer.cornerRadius = faceWidth * 0.15;
            [self.view addSubview:leftEye];
        }

        // Boca
        if (faceFeature.hasMouthPosition) {
            // Creamos una UIView con el tamaño de la boca
            UIView *mouth = [[UIView alloc] initWithFrame:CGRectMake
            (faceFeature.mouthPosition.x - faceWidth * 0.20,
            faceFeature.mouthPosition.y -
            faceWidth * 0.20, faceWidth * 0.40, faceWidth * 0.40)];

            mouth.backgroundColor = [[UIColor greenColor]
            colorWithAlphaComponent:0.4];
            mouth.center = faceFeature.mouthPosition;

            mouth.layer.cornerRadius = faceWidth * 0.20;
            [self.view addSubview:mouth];
        }
    }
}</pre>
<p>- El último paso sería llamar al método <em>faceDetector</em> desde <em>viewDidLoad</em> y ejecutar nuestro código para ver el resultado</p>
<pre class="brush: objc;">- (void)viewDidLoad
{
    [super viewDidLoad];

    [self faceDetector];
}</pre>
<p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://www.ingens-networks.com/blog/image.axd?picture=2012%2f4%2fIMG_0070.PNG" alt="" /></p>
<p><strong><br />
</strong></p>
<p><strong>ALGO VA MAL&#8230;</strong></p>
<p>Como se puede apreciar parece que algo ha salido mal y el problema está en que las coordenadas que utiliza UIKit y CoreImage (OS X) son diferentes. El origen del sistema de coordenadas de CoreImage están en la esquina inferior izquierda y el de UIKit está en la esquina superior izquierda. Por eso necesitamos invertir las posiciones antes de pintarlas por pantalla. Como la mayoría de nuestro código tendrá las coordenadas de UIKit, será más fácil traducir CoreImage a UIKit. Para ello tendremos que realizar una serie de modificaciones en nuestros métodos:</p>
<p>- <em>faceDetector</em></p>
<pre class="brush: objc;">-(void)faceDetector
{
    // Carga la imagen de la cara
    UIImageView *imagen = [[UIImageView alloc] initWithImage:
    [UIImage imageNamed:@"megan.jpg"]];

    [self.view addSubview:imagen];

    // El origen del sistema de coordenadas de CoreImage están en la esquina
    // inferior izquierda
    // y el de UIKit está en la esquina superior izquierda. Por eso necesitamos
    // invertir las posiciones
    // antes de pintarlas por pantalla.
    CGAffineTransform transform = CGAffineTransformMakeScale(1, -1);
    transform = CGAffineTransformTranslate(transform,
                                           0,-imagen.bounds.size.height);

    [self markFaces:imagen withTransform:transform];
}</pre>
<p>- <em>markFaces: </em>pasa a llamarse <em>markfaces:withTransform: </em>ya que vamos a pasarle un parámetro de tipo CGAffineTransform</p>
<pre class="brush: objc;">-(void)markFaces:(UIImageView *)imagenCara withTransform:(CGAffineTransform) transform
{
    CIImage *imagen = [CIImage imageWithCGImage:imagenCara.image.CGImage];
    // Para el detector, utilizamos la constante "CIDetectorAccuracyHigh"
    // la cual nos proporciona una precisión mejor pero requiere más
    // tiempo de procesado
    // Más info en http://goo.gl/ahfoU
    CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeFace context:nil
    options:[NSDictionary dictionaryWithObject:CIDetectorAccuracyHigh
    forKey:CIDetectorAccuracy]];

    // Creamos un array con todas las caras detectadas en la imagen
    NSArray *features = [detector featuresInImage:imagen];

    // Hacemos un bucle por si detecta más de un rostro en la imagen
    for (CIFaceFeature *faceFeature in features) {

        // Convertir coordenadas CoreImage a UIKit
        CGRect faceRect = CGRectApplyAffineTransform(faceFeature.bounds, transform);
        // Obtener el ancho de la cara
        CGFloat faceWidth = faceFeature.bounds.size.width;

        // UIView usando las dimensiones de la cara detectada
        UIView *faceView = [[UIView alloc] initWithFrame:faceRect];

        // Añadimos un borde alrededor del UIView
        faceView.layer.borderWidth = 1;
        faceView.layer.borderColor = [[UIColor blueColor] CGColor];

        [self.view addSubview:faceView];

        // Ojo derecho
        if (faceFeature.hasRightEyePosition) {

            // Convertir coordenadas CoreImage a UIKit
            CGPoint rightEyePos = CGPointApplyAffineTransform
            (faceFeature.rightEyePosition, transform);

            // Creamos una UIView con el tamaño del ojo derecho
            UIView *rightEye = [[UIView alloc] initWithFrame:CGRectMake
            (rightEyePos.x - faceWidth * 0.15, rightEyePos.y - faceWidth * 0.15,
            faceWidth * 0.3, faceWidth * 0.3)];

            rightEye.backgroundColor = [[UIColor redColor]
            colorWithAlphaComponent:0.4];
            rightEye.center = rightEyePos;

            rightEye.layer.cornerRadius = faceWidth * 0.15;
            [self.view addSubview:rightEye];
        }

        // Ojo izquierdo
        if (faceFeature.hasLeftEyePosition) {

            // Convertir coordenadas CoreImage a UIKit
            CGPoint leftEyePos = CGPointApplyAffineTransform
            (faceFeature.leftEyePosition, transform);

            // Creamos una UIView con el tamaño del ojo izquierdo
            UIView *leftEye = [[UIView alloc] initWithFrame:CGRectMake
            (leftEyePos.x - faceWidth * 0.15, leftEyePos.y - faceWidth * 0.15,
            faceWidth * 0.3, faceWidth * 0.3)];

            leftEye.backgroundColor = [[UIColor redColor]
            colorWithAlphaComponent:0.4];
            leftEye.center = leftEyePos;

            leftEye.layer.cornerRadius = faceWidth * 0.15;
            [self.view addSubview:leftEye];
        }

        // Boca
        if (faceFeature.hasMouthPosition) {

            // Convertir coordenadas CoreImage a UIKit
            CGPoint mouthPos = CGPointApplyAffineTransform
            (faceFeature.mouthPosition, transform);

            // Creamos una UIView con el tamaño de la boca
            UIView *mouth = [[UIView alloc] initWithFrame:CGRectMake
            (mouthPos.x - faceWidth * 0.20, mouthPos.y - faceWidth * 0.20,
            faceWidth * 0.40, faceWidth * 0.40)];

            mouth.backgroundColor = [[UIColor greenColor] colorWithAlphaComponent:0.4];
            mouth.center = mouthPos;

            mouth.layer.cornerRadius = faceWidth * 0.20;
            [self.view addSubview:mouth];
        }
    }
}</pre>
<p><strong><br />
</strong></p>
<p><strong>RESULTADO</strong></p>
<p><img style="display: block; margin-left: auto; margin-right: auto;" src="http://www.ingens-networks.com/blog/image.axd?picture=2012%2f4%2fScreenshot_4.png" alt="" /></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Podéis descargar el proyecto <a href="http://www.ingens-networks.com/blog/file.axd?file=2012%2f4%2fDetectorCaras1.zip">DetectorCaras1.zip (69,79 kb)</a></p>
<p>&nbsp;</p>
<p>Fuente: <a href="http://www.ingens-networks.com/blog/post/2012/04/27/Reconocimiento-facial-en-iOS-5-con-Core-Image.aspx" target="_blank">Ingens Blog</a></p>
]]></content:encoded>
			<wfw:commentRss>http://bcn.nscoders.org/2012/06/10/reconocimiento-facial-en-ios-5-con-core-image.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>RubyMotion</title>
		<link>http://bcn.nscoders.org/2012/05/31/rubymotion.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=rubymotion</link>
		<comments>http://bcn.nscoders.org/2012/05/31/rubymotion.html#comments</comments>
		<pubDate>Thu, 31 May 2012 16:57:26 +0000</pubDate>
		<dc:creator>nsvictor</dc:creator>
				<category><![CDATA[IOs]]></category>
		<category><![CDATA[NSBlog]]></category>

		<guid isPermaLink="false">http://bcn.nscoders.org/?p=256</guid>
		<description><![CDATA[Hace unos días, Laurent Sansonetti, otrora ingeniero de Apple, anunció la disponibilidad de RubyMotion, y ha tenido bastante eco. Pero, que es RubyMotion? Este breve artículo tratará de despejar esta incógnita, para que podáis decidir si os interesa utilizarlo. Para empezar, RubyMotion es en sí un conjunto de herramientas, a saber: Unas herramientas de línea [...]]]></description>
			<content:encoded><![CDATA[<p>Hace unos días, Laurent Sansonetti, otrora ingeniero de Apple, anunció la disponibilidad de <a href="http://rubymotion.com">RubyMotion</a>, y ha tenido bastante eco. Pero, que es RubyMotion? Este breve artículo tratará de despejar esta incógnita, para que podáis decidir si os interesa utilizarlo.</p>
<p>Para empezar, RubyMotion es en sí un conjunto de herramientas, a saber:</p>
<ul>
<li>Unas herramientas de línea de comando, que generan proyectos (si alguna vez habéis utilizado <a href="http://rubyonrails.org">RoR</a>, es del mismo estilo), los ejecutan y los empaquetan</li>
<li>Un compilador de MacRuby</li>
<li>Una herramienta <a href="http://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop">REPL</a> que funciona sobre el simulador de iPhone</li>
</ul>
<p>Con estas herramientas disponemos de la capacidad de desarrollar aplicaciones completas para iOS usando MacRuby. MacRuby es una implementación de Ruby que se caracteriza por funcionar sobre el runtime de Objective-C, en lugar de sobre C pelado. Cuando usamos MacRuby, los tipos nativos de Ruby se encuentran implementados por tipos de Objective-C/Cocoa. Por ejemplo, un <code>string</code> de ruby será en realidad un <code>NSMutableString</code>. Un <code>hash</code> será en realidad un <code>NSMutableDictionary</code>. Y así sucesivamente. No solo eso, si no que disponemos de unas extensiones a la sintaxis habitual de Ruby que nos permiten llamar a métodos en Objective-C que admitan múltiples parámetros respetando su idiosincrasia.</p>
<p>Si habéis seguido el panorama de MacRuby de cerca, sabréis que en principio solo está soportado en el Mac. Había una serie de importantes escollos técnicos que sortear antes de poder ponerse a desarrollar con MacRuby para iOS. Así que Laurent Sansonetti, el principal impulsor de MacRuby dentro de Apple, se despidió de la compañía para iniciar su propia empresa que resolviera esta demanda. Y así fue como RubyMotion vio la luz, en forma de producto comercial. Actualmente se está ofreciendo bajo un descuento por lanzamiento, el precio final será de unos €160.</p>
<h2 id="breveintroduccinarubymotion">Breve introducción a RubyMotion</h2>
<p>Cómo se trabaja con RubyMotion? Para empezar, lo primero que hay que hacer es desplazarse a un directorio donde queramos tener los proyectos. Desde la terminal, y antes de empezar con nada más, podemos opcionalmente comprobar si hay alguna actualización:</p>
<pre><code>sudo motion update
</code></pre>
<p>Aunque parezca una tontería mencionarlo, este paso puede ser interesante. En apenas unos días, RubyMotion ha alcanzado la versión 1.5. Y no es cuestión baladí actualizarse, ya que en cada versión se está ofreciendo funcionalidad nueva bastante interesante. Por ejemplo, al salir la release 1.0, RubyMotion no soportaba diseñar la interfaz gráfica desde Interface Builder. La idea era generar la interfaz programáticamente, tal vez con ayuda de un <a href="http://es.wikipedia.org/wiki/Lenguaje_espec%C3%ADfico_del_dominio">DSL</a> especializado construido sobre ruby. Ahora ya se compilan los XIBs a NIBs automáticamente.</p>
<p>Una vez hecho esto, el siguiente paso sería crear un nuevo proyecto:</p>
<pre><code>motion create nombre
</code></pre>
<p>Esto crea una estructura de directorios, y unos ficheros iniciales con los que empezar a trabajar. Como ya estamos acostumbrados, este proyecto vacío ya es ejecutable (aunque no haga nada):</p>
<pre><code>cd nombre
rake
</code></pre>
<p>Eso inicia el proyecto, y nos abre una especie de shell (un REPL) desde donde podemos manipular los objetos de nuestra aplicación en vivo, utilizando un intérprete de Ruby! De hecho, cuando ya estamos mostrando elementos por pantalla en el simulador, con solo hacer ⌘-click obtenemos en la terminal la referencia al objeto.</p>
<p>Ahora ya solo se trata de empezar a trabajar poniendo las clases que faltan. Podéis ver los detalles en cualquiera de los tutoriales de RubyMotion que no paran de salir por todas partes, o los de MacRuby que ya existían. Si estáis interesados en aprender más, dejad vuestro feedback y trataremos de preparar algo más completo. De hecho, en la lista de correo no se ha mencionado para nada RubyMotion, así que asumo que soy el único que ha obtenido una licencia.</p>
]]></content:encoded>
			<wfw:commentRss>http://bcn.nscoders.org/2012/05/31/rubymotion.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#8220;Steve Jobs&#8221; 1955-2011</title>
		<link>http://bcn.nscoders.org/2011/10/06/steve-jobs-1955-2011.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=steve-jobs-1955-2011</link>
		<comments>http://bcn.nscoders.org/2011/10/06/steve-jobs-1955-2011.html#comments</comments>
		<pubDate>Thu, 06 Oct 2011 09:46:42 +0000</pubDate>
		<dc:creator>NSCoders</dc:creator>
				<category><![CDATA[Destacar]]></category>
		<category><![CDATA[NSBlog]]></category>

		<guid isPermaLink="false">http://bcn.nscoders.org/?p=225</guid>
		<description><![CDATA[“Stay Hungry, Stay Foolish” La mayoría de nosotros nunca te conocimos personalmente. Nunca estuvimos en una keynote tuya, te estrechamos la mano, ni recibimos un escueto correo tuyo. Pero a pesar de ello, nos sentimos apesadumbrados ahora que ya no estás, y nos falta algo. Porque afectaste a nuestras vidas  con tus ideas, y sin [...]]]></description>
			<content:encoded><![CDATA[<p><em><strong>“Stay Hungry, Stay Foolish”</strong></em></p>
<p><em><strong><br />
</strong></em></p>
<p><span id="more-225"></span></p>
<blockquote><p>La mayoría de nosotros nunca te conocimos personalmente. Nunca estuvimos en una keynote tuya, te estrechamos la mano, ni recibimos un escueto correo tuyo. Pero a pesar de ello, nos sentimos apesadumbrados ahora que ya no estás, y nos falta algo. Porque afectaste a nuestras vidas  con tus ideas, y sin ti ni siquiera estaríamos reuniéndonos y compartiendo conocimientos.</p>
<p>Tú nos enseñaste que los detalles son importantes. Que no hay que tener miedo de lanzarnos a por lo que creemos. Que la informática es para todos. Y que hay que tratar de hacer del mundo un lugar mejor. Y por eso hoy es un día triste. Pero trataremos de seguir tu ejemplo como si estuvieras a nuestro lado, inspirándonos y criticando nuestros puntos débiles para que hagamos un mejor trabajo sin caer en la complacencia.</p>
<p>Seguiremos ávidos e ilusos. Y pensando diferente.</p>
<p>Los NSCoders.</p></blockquote>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://bcn.nscoders.org/2011/10/06/steve-jobs-1955-2011.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Core Data tutorial for IOs (by Albert Mata)</title>
		<link>http://bcn.nscoders.org/2011/10/05/core-data-tutorial-for-ios-by-albert-mata.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=core-data-tutorial-for-ios-by-albert-mata</link>
		<comments>http://bcn.nscoders.org/2011/10/05/core-data-tutorial-for-ios-by-albert-mata.html#comments</comments>
		<pubDate>Wed, 05 Oct 2011 12:42:21 +0000</pubDate>
		<dc:creator>NSCoders</dc:creator>
				<category><![CDATA[El Rincon del Novato]]></category>
		<category><![CDATA[IOs]]></category>

		<guid isPermaLink="false">http://bcn.nscoders.org/?p=218</guid>
		<description><![CDATA[Nuestro compañero Albert Mata comparte con nosotros sus notas sobre Core Data, claras y directas al grano, para que no tengamos tan complicado nuestras primeras incursiones con la persistencia de datos en la plataforma de Apple   Descargar: Core Data Tutorial for IOs.pdf (mirror1) &#160; Cuando comenzamos a desarrollar aplicaciones iOS llega un momento en [...]]]></description>
			<content:encoded><![CDATA[<p>Nuestro compañero Albert Mata comparte con nosotros sus notas sobre Core Data, claras y directas al grano, para que no tengamos tan complicado nuestras primeras incursiones con la persistencia de datos en la plataforma de Apple <img src='http://bcn.nscoders.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />   <em>Descargar: <a title="Core Data tutorial for IOs.pdf (by Albert Mata)" href="http://bcn.nscoders.org/wp-content/uploads/2011/10/core-data-tutorial-for-ios-1.pdf" target="_blank">Core Data Tutorial for IOs.pdf</a> (<a href="http://www.albertmata.net/core-data-tutorial-for-ios.pdf" target="_blank">mirror1</a>)</em></p>
<p>&nbsp;</p>
<blockquote><p>Cuando comenzamos a desarrollar aplicaciones iOS llega un momento en que queremos utilizar funciones de persistencia para guardar ciertos datos entre distintas ejecuciones de la aplicación. De entre los distintos modos que tenemos disponibles para hacerlo, uno de los más recomendables es la utilización del framework Core Data.</p>
<p>Entre la documentación propia de Apple se encuentra el tutorial introductorio &#8216;Core Data Tutorial for iOS&#8217;. El documento adjunto es un simple resumen de dos páginas con los conceptos más importantes de dicho tutorial.</p>
<p>(by <a title="Albert Mata, LinkedIn" href="http://es.linkedin.com/in/almata" target="_blank">Albert Mata</a>, <a title="@almata" href="http://twitter.com/almata" target="_blank">@almata</a>)</p></blockquote>
<p>&nbsp;</p>
<p>Gracias Albert!</p>
]]></content:encoded>
			<wfw:commentRss>http://bcn.nscoders.org/2011/10/05/core-data-tutorial-for-ios-by-albert-mata.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nace el NSPodcast</title>
		<link>http://bcn.nscoders.org/2011/10/05/nace-el-nspodcast.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=nace-el-nspodcast</link>
		<comments>http://bcn.nscoders.org/2011/10/05/nace-el-nspodcast.html#comments</comments>
		<pubDate>Tue, 04 Oct 2011 22:12:07 +0000</pubDate>
		<dc:creator>NSCoders</dc:creator>
				<category><![CDATA[NSBlog]]></category>

		<guid isPermaLink="false">http://bcn.nscoders.org/?p=209</guid>
		<description><![CDATA[Tenemos nuevo bebe en la Asociación, nos hemos liado la manta a la cabeza y metido en un nuevo fregao. Os presentamos el &#8220;NSPodcast: el podcast de los NSCoders&#8221; en su primera edición. Aquí os dejamos el primer podcast de la Asociación NSCoders España. Para ser la primera edición, de muchas mas, creo que ya [...]]]></description>
			<content:encoded><![CDATA[<p>Tenemos nuevo bebe en la Asociación, nos hemos liado la manta a la cabeza y metido en un nuevo fregao. Os presentamos el &#8220;<a href="http://nscoders.org/category/nspodcast">NSPodcast: el podcast de los NSCoders</a>&#8221; en su <a href="http://nscoders.org/2011/10/y-llego-el-podcast-de-los-nscoders.html">primera edición</a>.</p>
<p><span id="more-209"></span><br />
Aquí os dejamos el primer podcast de la Asociación NSCoders España.</p>
<p>Para ser la primera edición, de muchas mas, creo que ya esta bien los poco mas de 36min de duración. 36min durante los cuales presentamos los orígenes de la asociación, el paso que parecía natural, de las &#8220;NSCoders Nights&#8221; a la &#8220;Asociación NSCoders España&#8221;. La diferencia entre los dos formatos. Lo que nos mueve a impulsarlo y apostar por este formato como un paso mas para los desarrolladores de Cocoa en toda España.<br />
Una pequeña introducción al evento del próximo 29-30 de Octubre en Vilanova y la Geltru, Barcelona. El formato, los contenidos, algunos detalles mas y alguna primicia <img src='http://bcn.nscoders.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  No demasiada información, si no más bien una pequeña pincelada del evento. En próximos podcast iremos sacando a la luz mas detalles, novedades y noticias. No os los perdáis!!</p>
<p>Y para terminar una de nuestras secciones estrellas de estos días: NSCollaborations. Esta semana:-Jonathan Chacón Barbero-Diego Freniche Brito</p>
<p>Os esperamos en la próxima edición del &#8230; NSPodcast!!</p>
<p><a href="http://nscoders.org/wp-content/uploads/2011/10/NSPodcast001.m4a">NSPodcast Edición num.001</a></p>
<p><em><strong>PD:</strong> Próximamente en sus mejores iTunes :p</em></p>
]]></content:encoded>
			<wfw:commentRss>http://bcn.nscoders.org/2011/10/05/nace-el-nspodcast.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://nscoders.org/wp-content/uploads/2011/10/NSPodcast001.m4a" length="17810287" type="audio/mpeg" />
		</item>
		<item>
		<title>NSCoders Apple Conference 2011</title>
		<link>http://bcn.nscoders.org/2011/09/30/nscoders-apple-conference-2011.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=nscoders-apple-conference-2011</link>
		<comments>http://bcn.nscoders.org/2011/09/30/nscoders-apple-conference-2011.html#comments</comments>
		<pubDate>Fri, 30 Sep 2011 21:27:03 +0000</pubDate>
		<dc:creator>NSCoders</dc:creator>
				<category><![CDATA[Conferencias]]></category>
		<category><![CDATA[Destacar]]></category>

		<guid isPermaLink="false">http://bcn.nscoders.org/?p=202</guid>
		<description><![CDATA[NSCoders Apple Conference 2011 Llega el evento más relevante del año para desarrolladores y aficionados a los dispositivos móviles de Apple. Los próximos 29 y 30 de octubre tendrá lugar en Neàpolis Vilanova i la Geltrú la NSCoders Conference 2011. De la mano de la Asociación NSCoders España llega un evento de dos días apto para [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://nsconf.nscoders.org"><span style="text-decoration: underline;">NSCoders Apple Conference 2011</span></a></p>
<p>Llega el evento más relevante del año para desarrolladores y aficionados a los dispositivos móviles de Apple. Los próximos 29 y 30 de octubre tendrá lugar en Neàpolis Vilanova i la Geltrú la NSCoders Conference 2011.</p>
<p>De la mano de la Asociación NSCoders España llega un evento de dos días apto para todos los públicos, desde personas interesadas o apasionadas por los Iphone e Ipad que quieran iniciarse en este mundo, hasta profesionales del sector que quieran ampliar sus conocimientos o intercambiar experiencias y establecer contactos con empresas.</p>
<p>El formato elegido ofrecerá dos líneas de contenido simultáneas: una  dirigida al público menos experimentado, con talleres de iniciación y contenidos elementales para dar los primeros pasos y  otra con contenidos más especializados dirigida a aquellos que quieran explorar a fondo la arquitectura y posibilidades de estas tecnologías.</p>
<p>La calidad de las ponencias está asegurada por auténticos gurús del desarrollo como el consultor en accesibilidad Jonathan Chacón, que mostrará como estos dispositivos son grandes aliados de las personas con discapacidades o desarrolladores de referencia como Diego Freniche e Imanol Prados.</p>
<p>Asimismo se contará con la presencia de empresas, que nos mostrarán las claves de sus tecnologías y algún ponente sorpresa que dejará a los asistentes con la boca abierta de par en par&#8230;</p>
<p>Toda la información del evento está disponible en la web del evento: <a title="NS Conference 2011" href="http://nsconf.nscoders.org">nsconf.nscoders.org</a></p>
]]></content:encoded>
			<wfw:commentRss>http://bcn.nscoders.org/2011/09/30/nscoders-apple-conference-2011.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Homebrew</title>
		<link>http://bcn.nscoders.org/2011/07/13/homebrew.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=homebrew</link>
		<comments>http://bcn.nscoders.org/2011/07/13/homebrew.html#comments</comments>
		<pubDate>Wed, 13 Jul 2011 07:50:57 +0000</pubDate>
		<dc:creator>nsvictor</dc:creator>
				<category><![CDATA[NSBlog]]></category>
		<category><![CDATA[OSX]]></category>
		<category><![CDATA[brew]]></category>
		<category><![CDATA[homebrew]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[package manager]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://bcn.nscoders.org/?p=75</guid>
		<description><![CDATA[Una de las herramientas que como desarrolladores, sysadmins, o simplemente usuarios adeptos debemos conocer es la línea de comandos. MacOS X es un Unix de pura cepa, y como tal, puede ejecutar una amplia gama de herramientas pensadas para llevar a cabo toda clase de tareas. Sin embargo, pocas de estas herramientas se encuentran disponibles [...]]]></description>
			<content:encoded><![CDATA[<p>Una de las herramientas que como desarrolladores, sysadmins, o simplemente usuarios adeptos debemos conocer es la línea de comandos. MacOS X es un Unix de pura cepa, y como tal, puede ejecutar una amplia gama de herramientas pensadas para llevar a cabo toda clase de tareas.</p>
<p>Sin embargo, pocas de estas herramientas se encuentran disponibles de serie en nuestros sistemas. Para poder utilizarlas, debemos instalarlas manualmente, lo cual es cuando menos engorroso, y cuando más, puede significar horas y horas perdidas tratando de resolver dependencias de las herramientas que utilizamos.</p>
<p>Para solucionar este problema, nacieron los gestores de paquetes. Del mismo modo que en linux disponemos de <code>rpm</code> y <code>dpkg</code> (o <code>yum</code> y <code>apt</code>), en MacOS X existen también varios sistemas de gestión de paquetes. En este artículo me centraré en el que considero más avanzado y más útil de ellos, <strong>Homebrew</strong>, ya que las alternativas, mayormente <strong>Macports</strong> (inspirado en el sistema de ports de FreeBSD) y <strong>fink</strong> (inspirado a su vez en apt), han ido poco a poco quedándose atrás en cuanto a frecuencia de actualización y catálogo de software disponible. Homebrew es obra del prolífico <a href="http://methylblue.com/">Max Howell</a>, autor entre otras herramientas de las versiones Android e iOS de <a href="http://www.tweetdeck.com/">TweetDeck</a>, y de los clientes de <a href="http://last.fm">last.fm</a>.  </p>
<p>Homebrew es un sistema  que goza de las simpatías de muchos desarrolladores y, por tanto, de un ímpetu, que lo ha convertido rápidamente en una elección muy popular entre los usuarios más técnicos. No en vano es el proyecto con <a href="https://github.com/popular/forked">mayor número de forks en GitHub</a> (hecho que, al contrario de lo que pueda parecer, no es un indicativo de fragmentación, si no de participación popular, ya que cada persona que quiere añadir un paquete, o actualizarlo, simplemente crea un fork, añade su <em>receta</em>, y envía una solicitud de <em>pull</em> al mantenedor para que lo incorpore al proyecto principal).</p>
<p>Una de las principales características que tiene homebrew frente a otros gestores de proyectos, es que no necesitas ser root para instalar un paquete. Homebrew normalmente instala los ejecutables en <code>/usr/local/</code>, nada de <code>/opt/</code>, <code>/sw/</code> ni tonterías similares. Y por tanto, espera que ese directorio sea escribible sin permisos de root. Al respecto ha habido cierta controversia, a mi al menos al principio no me parecía del todo correcto. Pero si nos ponemos a mirar, veremos que casi cualquier aplicación que bajamos de internet, y que se instale a pelo, es decir sin instalador, la copiamos tranquilamente a <code>/Applications/</code> sin pensárnoslo dos veces. Y al contrario, cuando ejecutamos un script con <code>sudo</code>, estamos corriendo más riesgo del que pensamos.</p>
<p>Para instalar homebrew, simplemente vamos a <a href="https://github.com/mxcl/homebrew">https://github.com/mxcl/homebrew</a> y vemos que hay que ejecutar un pequeño script en ruby:</p>
<pre><code>/usr/bin/ruby -e "$(curl -fsSL https://raw.github.com/gist/323731)"
</code></pre>
<p>Si ejecutar un script obtenido a partir de una URL te pone los pelos de punta (debería), puedes echar un vistazo primero.</p>
<p>Una vez hecho esto, ya tenemos homebrew listo para instalar paquetes. Podemos probarlo de la siguiente manera:</p>
<pre><code>brew install wget
</code></pre>
<p>Esto instruirá a brew a descargarse el código fuente de la utilidad <strong>wget</strong>, compilarlo, e instalarlo en <code>/usr/local/</code>. Homebrew en este sentido, es más parecido a los <em>ports</em> o al <em>emerge</em> de Gentoo. No lo he mencionado, dado que doy por sentado que todos tenemos Xcode, pero evidentemente necesitaremos las herramientas de desarrollo, no necesariamente Xcode al completo, pero si los paquetes de compiladores y demás.</p>
<p>Por cierto, por algún extraño motivo, en MacOS X, <code>/usr/local/bin</code> no está antes en el <code>$PATH</code> que <code>/usr/local/</code>, con lo cual, si instalamos alguna herramienta de las que vengan con el sistema o con Xcode, nos vamos a encontrar que la del sistema tiene prioridad sobre la versión que nosotros hemos instalado explícitamente (con lo cual, es como si no hubieramos hecho nada). En cualquier otro sistema UNIX (o linux), lo normal es que las customizaciones tomen prioridad, así que no acabo de entender muy bien esta política. Podemos solucionar esto de dos maneras, editando nuestro fichero <code>~/.bash_profile</code> para modificar la variable de entorno <code>$PATH</code>, o bien cambiando el orden en <code>/etc/paths</code> (lo cual va a requerir permisos de root, al aplicarse a todo el sistema).</p>
<p>Las definiciones de los paquetes en homebrew siguen la metáfora de una cervecera. Cada paquete es una <em>receta</em> o <em>fórmula</em> para elaborar un&#8230; bueno, en castellano no tenemos una buena traducción para <em>brew</em>, en el sentido cervecero. Brebaje suena parecido pero es algo completamente distinto. Podríamos abusar del lenguaje y usar la palabra caldo, que los vinateros usan, pero lo dejaremos como <em>brew</em>. <em>To brew</em> en inglés es también un verbo, que es lo que representa el comando que usamos.</p>
<p>En fin, después de esta digresión, paso a enumerar los comandos más habituales de que disponemos para gestionar los paquetes. Lo mejor es que echemos un vistazo al manual de <code>brew</code> y los veamos cuando tengamos dudas:</p>
<pre><code>brew search paquete
</code></pre>
<p>Este comando buscará un match en los nombres de los paquetes y nos listará los que coincidan (si el nombre de paquete está cerrado entre barras, se interpretará como una expresión regular). Una vez creemos haber encontrado el que nos puede interesar, lo podemos comprobar con</p>
<pre><code>brew home paquete
</code></pre>
<p>Esto nos abrirá el navegador por defecto que tengamos en el sistema, en la página web del producto en cuestión. Estamos en el s. XXI y usamos Macs, así que no hay excusa para andarnos con cosas que recuerden a <code>gnu info</code>. Cualquier producto debería tener un website canónico.</p>
<pre><code>brew install paquete
</code></pre>
<p>Este comando instalará el paquete, bajándose el código fuente si no está cacheado, y compilándolo. Del mismo modo,</p>
<pre><code>brew remove paquete
</code></pre>
<p>lo eliminará del sistema. Si necesitamos saber qué fórmulas tenemos instaladas, pediremos un listado:</p>
<pre><code>brew list
</code></pre>
<p>Si a este comando le añadimos además el nombre de una fórmula, lo que veremos son los ficheros instalados por esa fórmula.</p>
<p>Cuando queramos actualizar los paquetes, primero ejecutaremos</p>
<pre><code>brew update
</code></pre>
<p>que actualizará brew y sus fórmulas, y luego podemos hacer algo como</p>
<pre><code>brew install $(brew outdated)
</code></pre>
<p>para que nos instale las fórmulas nuevas de las que tengamos instaladas. Normalmente, al actualizar una fórmula nos instala la versión nueva pero no retira las antiguas, que siguen instaladas (aunque fuera del <code>$PATH</code>). Para limpiar estas versiones antiguas, el comando que necesitamos es</p>
<pre><code>brew cleanup
</code></pre>
<p>Bueno, hasta aquí esta breve introducción. Hay unos cuantos comandos más, pero son menos frecuentemente utilizados, así que dad un vistazo a <code>man brew</code> para dar con ellos.</p>
]]></content:encoded>
			<wfw:commentRss>http://bcn.nscoders.org/2011/07/13/homebrew.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Proxima Conferencia &#8211; Hello NSCoder 2</title>
		<link>http://bcn.nscoders.org/2011/07/07/proxima-conferencia-hello-nscoder-2.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=proxima-conferencia-hello-nscoder-2</link>
		<comments>http://bcn.nscoders.org/2011/07/07/proxima-conferencia-hello-nscoder-2.html#comments</comments>
		<pubDate>Wed, 06 Jul 2011 22:05:09 +0000</pubDate>
		<dc:creator>NSCoders</dc:creator>
				<category><![CDATA[Conferencias]]></category>
		<category><![CDATA[NSBlog]]></category>

		<guid isPermaLink="false">http://bcn.nscoders.org/?p=145</guid>
		<description><![CDATA[Aprovechamos la inauguración de nuestro blog para invitaros a la proxima conferencia de nuestra &#8220;Hello NSCoder&#8221; serie. La conferencia se realiza el sábado 16 de Julio en el CINC Barcelona, manteniendo la linea argumental iniciado en la edición anterior. Mostraremos más temas de desarrollo de aplicaciones para iOS. En esta segunda edición continuaremos desarrollando la [...]]]></description>
			<content:encoded><![CDATA[<p>Aprovechamos la inauguración de nuestro blog para invitaros a la proxima conferencia de nuestra &#8220;Hello NSCoder&#8221; serie.</p>
<p>La conferencia se realiza el <strong>sábado 16 de Julio</strong> en el <a href="http://www.cinc.com/">CINC Barcelona</a>, manteniendo la linea argumental iniciado en la edición anterior.  <span style="font-family: 'helvetica neue', helvetica, arial, sans-serif; font-size: small;">Mostraremos más temas de desarrollo de aplicaciones para iOS.</span></p>
<p><span style="font-family: 'helvetica neue', helvetica, arial, sans-serif; font-size: small;"> </span></p>
<p><span style="font-family: 'helvetica neue', helvetica, arial, sans-serif; font-size: small;">En esta segunda edición continuaremos desarrollando la App iniciado en la primera conferencia &#8220;Hello NSCoder I&#8221;. A parte del formato de ponencias de 90 y 45 minutos se expondrá un formato nuevo de micro sesiones de 15 minutos llamados &#8220;Recipes&#8221; en cuales se explica temas mas cortos y muy específicos.</span></p>
<p><span style="font-family: 'helvetica neue', helvetica, arial, sans-serif;"><span style="font-size: small;"><br />
</span></span></p>
<p><strong>Agend</strong>a:</p>
<p>9:00 &#8211; <span style="font-family: 'helvetica neue', helvetica, arial, sans-serif; font-size: small;">Geolocalización &amp; MapKit (Alfonso @setfilesl / Guillem @gfernandezg / Andreas @aquarioverde)</span></p>
<p><span style="font-family: 'helvetica neue', helvetica, arial, sans-serif; font-size: small;">10:30 &#8211; Pausa </span></p>
<p><span style="font-family: 'helvetica neue', helvetica, arial, sans-serif; font-size: small;">10:45 &#8211; </span><span style="font-family: 'helvetica neue', helvetica, arial, sans-serif; font-size: small;">Introducción a Git &amp; GitHub (Victor @jalencas)</span></p>
<p><span style="font-family: 'helvetica neue', helvetica, arial, sans-serif; font-size: small;"> </span><span style="font-family: 'helvetica neue', helvetica, arial, sans-serif; font-size: small;">11:30 &#8211; Debug y Analisis de Aplicaciones (Jose Juan @minyunmen)</span></p>
<p><span style="font-family: 'helvetica neue', helvetica, arial, sans-serif; font-size: small;">12:15 &#8211; Pausa</span></p>
<p><span style="font-family: 'helvetica neue', helvetica, arial, sans-serif; font-size: small;"> </span><span style="font-family: 'helvetica neue', helvetica, arial, sans-serif; font-size: small;">12:30 &#8211; Solid (Pedro @pedromsantos)</span></p>
<p><span style="font-family: 'helvetica neue', helvetica, arial, sans-serif; font-size: small;"> </span><span style="font-family: 'helvetica neue', helvetica, arial, sans-serif; font-size: small;">12:45 &#8211; Mecadotecnia (Leo @Leo1098R)</span></p>
<p><span style="font-family: 'helvetica neue', helvetica, arial, sans-serif; font-size: small;"> </span><span style="font-family: 'helvetica neue', helvetica, arial, sans-serif; font-size: small;">13:00 &#8211; Lazy Loading (Ricardo @risalba)</span></p>
<p><span style="font-family: 'helvetica neue', helvetica, arial, sans-serif; font-size: small;"> </span><span style="font-family: 'helvetica neue', helvetica, arial, sans-serif; font-size: small;">13:15 &#8211; Pausa</span></p>
<p><span style="font-family: 'helvetica neue', helvetica, arial, sans-serif; font-size: small;">13:30 &#8211; Bloack </span><span style="font-family: 'helvetica neue', helvetica, arial, sans-serif; font-size: small;">(Alfonso @setfilesl / Guillem @gfernandezg)</span></p>
<p><span style="font-family: 'helvetica neue', helvetica, arial, sans-serif; font-size: small;"> </span><span style="font-family: 'helvetica neue', helvetica, arial, sans-serif; font-size: small;">13:45 &#8211; Efecto Lupa (Ivan @ileider)</span></p>
<p><span style="font-family: 'helvetica neue', helvetica, arial, sans-serif; font-size: small;">14:00 &#8211; Streaming Audio (</span><span style="font-family: 'helvetica neue', helvetica, arial, sans-serif; font-size: small;">Jose Juan @minyunmen)</span></p>
<p>&nbsp;</p>
<p style="text-align: center;"><strong>Don&#8217;t miss it!!!!</strong></p>
<p style="text-align: center;"><strong>Subscribe now:</strong></p>
<p style="text-align: center;"><a href="http://hellonscoder2.eventbrite.com/">http://hellonscoder2.eventbrite.com/</a></p>
<p style="text-align: center;"><strong><strong>And see you soon!</strong><br />
</strong></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Por cierto, para los que no sabeis porque nos llamamos <strong>NS</strong>Coders y los que dudáis de donde viene el NS:</p>
<p>NS == <a href="http://es.wikipedia.org/wiki/NEXTSTEP">NEXT STEP</a> == sistema operativo de los ordenadores NeXT, que tenia Objective-C como lenguaje de programación</p>
<p>Pues, solo querría aclararlo porque algunos me preguntaron hoy &#8230;</p>
<p>&nbsp;</p>
<p style="text-align: center;"><strong><br />
</strong></p>
<p style="text-align: center;"><strong><br />
</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://bcn.nscoders.org/2011/07/07/proxima-conferencia-hello-nscoder-2.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cuánto vale nuestro trabajo?</title>
		<link>http://bcn.nscoders.org/2011/07/04/cuanto-vale-nuestro-trabajo.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=cuanto-vale-nuestro-trabajo</link>
		<comments>http://bcn.nscoders.org/2011/07/04/cuanto-vale-nuestro-trabajo.html#comments</comments>
		<pubDate>Mon, 04 Jul 2011 15:02:11 +0000</pubDate>
		<dc:creator>nsguillem</dc:creator>
				<category><![CDATA[Sala de Maquinas]]></category>
		<category><![CDATA[disquisicion]]></category>

		<guid isPermaLink="false">http://bcn.nscoders.org/?p=105</guid>
		<description><![CDATA[Tras la lectura últimamente de distintos artículos acerca de la profesión de programador en los que nos preguntamos constantemente si debemos abandonar nuestra pasión como programadores sacrificándola en pro de una mejora económica, siempre necesaria en los tiempos que corren, se nos plantea el dilema de cuánto vale nuestro trabajo. Me contaba un gran profesional [...]]]></description>
			<content:encoded><![CDATA[<div>
<div style="text-align: justify">Tras la lectura últimamente de distintos artículos acerca de la profesión de programador en los que nos preguntamos constantemente si debemos abandonar nuestra pasión como programadores  sacrificándola en pro de una mejora económica, siempre necesaria en los tiempos que corren, se nos plantea el dilema de <em>cuánto vale nuestro trabajo</em>.</div>
<div style="text-align: left"></div>
<div style="text-align: justify">Me contaba un gran profesional hace tiempo una historia acerca de un taller de fresadores en el que el jefe del taller estaba a punto de jubilarse y decidió buscar un substituto entre los fresadores que gestionaba en el taller. De todos ellos pensó en el que más tiempo llevaba en el taller y que disponía de un grado de maestría excepcional y que había demostrado pasión por su trabajo y un afán de mejora continua, era capaz de hacer una pieza como nadie en un tiempo inigualable. Finalmente así lo hizo y consiguió dos cosas, perder a su mejor fresador y tener un mal responsable de taller.</div>
<div></div>
<div style="text-align: justify">A todos nos llega un momento en la vida en el que tenemos que tomar una decisión importante, esos momentos que llaman encrucijada en los que has de tomar el camino de la derecha o el de la izquierda y nunca sabrás lo que hubiese ocurrido si hubieses tomado el otro camino, como las píldoras de Morfeo en Matrix. Puedes decidir hacer lo que de verdad te apasiona intentando convertir tu pasión en tu trabajo o decidir hacer aquello que te va a proporcionar mayores ingresos de forma más fácil y rápida aunque no disfrutes de ello.</div>
<div></div>
<div style="text-align: justify">Yo soy de los que tras caminar mucho tiempo por el camino de los ingresos he decidido que tengo que hacer de mi pasión mi medio de vida. Cuando he contado mis intenciones a compañeros de profesión he escuchado frases como: &#8221; <em>Y te vas a poner como simple programador?, con la experiencia que tienes?</em>‚Äô Pues sí, porque necesito disfrutar con mi trabajo.</div>
<div></div>
<div style="text-align: justify">Una vez tomada la decisión nos planteamos cuánto vale nuestro trabajo. Debo ir a precio para poder empezar a tener una cartera de proyectos? Total si no me bajo los pantalones yo, se los bajará otro y perderé seguro el proyecto. Esto, como se suele decir, es pan para hoy y hambre para mañana, si has aceptado un precio miserable por un proyecto cual es el argumento para pedir más por el siguiente. El argumento de &#8220;ahora ya me conoces y sabes lo que soy capaz de hacer‚Äô acostumbra a ser poco convincente ya que quién te contrató la primera vez pensará en buscar a otro buen programador que tenga la necesidad de demostrar que tú tenias al principio. Pero, pongamos las cifras sobre la mesa.</div>
<div></div>
<div style="text-align: justify">Nos solicitan un proyecto del cual en el 75% de los casos la información que nos proporcionan es vaga, imprecisa y no se corresponde con la mayoría de deseos de todos los usuarios finales o incluso no refleja ni siquiera la realidad de las necesidades.</div>
<div></div>
<div style="text-align: justify">Lo primero que haremos es indicar que debemos realizar un estudio y una toma de requerimientos para realizar el trabajo, pero, por qué la mayoría de clientes consideran que eso no tienen que pagarlo? Es que el tiempo empleado en elaborar un pliego de requerimientos no es trabajo? Pedirían a un Arquitecto que no les cobrase los planos de la obra? O a una consultora que no les cobrase los informes? Invertimos una semana de reuniones y elaboración de una propuesta de proyecto, cuarenta horas.</div>
<div></div>
<div style="text-align: justify">Una vez consensuado el documento de proyecto, elaboramos el análisis técnico del mismo y presentamos las pantallas y funcionalidades, labor que nos lleva otras dos semanas, suma ochenta horas más. Y finalmente nos ponemos en el desarrollo que nos lleva un mes de trabajo para una aplicación media sin demasiadas florituras, otras 200 horas en las que no contamos las reuniones improductivas, los tiempos empleados en desarrollos que dependen de otros desarrollos y que luego cambian y por &#8230;, etc &#8230;</div>
<div></div>
<div>El final nos arroja la bonita cifra de trescientas veinte horas invertidas.</div>
<div></div>
<div style="text-align: justify">Si por un trabajo de este tipo, como se oye muy habitualmente se presupuestan 2.500€ hagamos el cálculo de coste/hora:</div>
<div>2.500€/320 = <strong>7.82€/hora</strong></div>
<div></div>
<div style="text-align: justify">Pero eso no es todo, de los 2.500€, siendo benévolos nos van a practicar una retención del 15% lo cual representará que de 7.82€/hora pasamos a 6,65€/hora y además, como probablemente nos van a pagar a 60 días en el mejor de los casos, si hemos facturado a mediados de trimestre, nos va a tocar adelantar el IVA, es decir 450€ y los 250€ de autónomo como mínimo que vamos a pagar por facturar.</div>
<div></div>
<div style="text-align: justify">El resultado es que empezamos pagando 700€ para, en el mejor de los casos recibir 2.500€ pasados sesenta días. Teniendo un ingreso final de 1875€ que entre las horas invertidas representarán a <strong>5.86€/hora.</strong></div>
<div></div>
<div style="text-align: justify">Alguien conoce un mecánico, fontanero, asistenta del hogar, etc &#8230; que cobre esos precios por hora? Porque yo le pago más a la canguro de mis hijas que es una chica que está estudiando.</div>
<div style="text-align: justify"></div>
<div style="text-align: justify">Debemos aprender a valorar más nuestro trabajo y a pedir por él lo que realmente vale. A cambio deberemos comprometernos a realizar un trabajo óptimo, a dar una asistencia post venta correcta, a atender todas las necesidades de nuestros clientes y a estar dispuestos a escuchar, pero en ningún caso a vendernos por <strong>5.86€/hora</strong>.</div>
<div style="text-align: justify"></div>
<div style="text-align: justify">Quizá estos cálculos hagan a más de uno plantearse las cosas de otro modo ya que lo que inicialmente suena a un buen sueldo por un mes de trabajo finalmente resulta una miseria ya que no hemos tenido en cuenta los costes del material necesario para realizar nuestra labor, desplazamientos, etc &#8230; y nunca serán ocho las horas invertidas al día en trabajar en ese proyecto.</div>
<div style="text-align: justify"></div>
<div style="text-align: justify">Este artículo pretende ser únicamente una reflexión de como debe enfocar un Indie sus ofertas económicas teniendo en cuenta que nadie nos asegura un proyecto cada mes y que debemos hacer una estimación anual de nuestras necesidades.</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://bcn.nscoders.org/2011/07/04/cuanto-vale-nuestro-trabajo.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
