Subscribe Twitter Twitter

jueves, 12 de agosto de 2010

Copias de Seguridad del proyecto

¿Cuántas veces has estado programando y cosas que funcionaban dejan de funcionar...? Para evitar esto en XCode disponemos de una herramienta muy sencilla y útil.

Podemos hacer "capturas instantáneas" (crear versiones) del proyecto e irlas guardando y en un momento dado restaurar y que el proyecto vuelva a una versión concreta, ésta herramienta nos va a facilitar llevar esta gestión de manera sencilla y eficiente.



Para crear una versión puedes hacerlo de dos maneras:
* XCode : File - Make Snapshot
* Acceso directo: comando(manzana) + control + S
*Primera opción (make) del gestor de versiones , para abrir el gestor: en XCode: File - Snapshot

Gestión de versiones: File-Snapshots


Opciones en la parte superior:
- make: Crea una nueva versión
- delete: Elimina la versión seleccionada.
- restore: Restaura el proyecto a la versión seleccionada.
- hide: esconde la zona derecha de la pantalla donde se muestra el detalle de los cambios que se han realizado.

Justo debajo de este menú tenemos el listado de las versiones que tenemos guardadas y cuando seleccionamos una de ellas debajo aparece el detalle de la misma (nombre fecha y comentarios) y en la parte derecha de manera resumida los ficheros que se han modificado, si hacemos clic sobre cualquiera de los cambios debajo aparece el fichero antiguo y el actual para que veamos que cambio en concreto se ha producido.

Algo tal que así:



Y finalmente en la parte inferior izquierda sale un resumen de los ficheros eliminados, modificados y añadidos.


martes, 10 de agosto de 2010

Gestión de un UIView

Por cada fichero de interfaz .xib que tenga una vista (UIView) debemos tener una clase que será la encargada de manejar todo lo relacionado con ese .xib. Ésta clase heredará de la clase UIViewController y se encargará de gestionar todo lo relacionado con la vista asociada (UIView).

Aunque una misma clase en teoría puede manejar más de una vista en la práctica se tiene una clase por cada xib.

Ésta clase que hereda del UIViewController se encarga de gestionar además de los elementos que añadamos en la vista como por ejemplo botones, label... gestionará el ciclo de vida del UIView controlando por ejemplo los siguientes "eventos":

- didReceiveMemoryWarning: El controlador recibe un aviso de memoria.

-didRotateFromInterfaceOrientation: Se invoca después de que la vista ha rotado.

-willRotateToInterfaceOrientation:duration: Se invoca cuando comienza a rotar la vista, el duration indica el tiempo que va a tardar en rotar.

-viewDidAppear: Se invoca después de que la vista ha aparecido.

-viewDidDisappear: Se invoca después de que la vista ha desaparecido.

-viewDidLoad: Se invoca después de que la vista se ha cargado en memoria.

-viewWillAppear: Se invoca justo antes de que la vista aparezca.

-viewWillDisappear: Se invoca justo antes de que la vista desaparezca.

-willAnimateFirstHalfOfRotationToInterfaceOrientation:duration: Se ejecuta antes de la rotación de la primera mitad del interfaz y la duración que va a durar.

-willAnimateSecondHalfOfRotationFromInterfaceOrientation:duration:Se ejecuta antes de la rotación de la segunda mitad del interfaz y la duración que va a durar.

domingo, 8 de agosto de 2010

UIApplication

Toda aplicación del iphone tiene un objeto de tipo UIApplication el cual es el punto de entrada de la aplicación y se encargará de inicializar y de mostrar un UIWindow y cargar además en este UIWindow la primera vista a mostrar. Además este UIApplication debe encargarse de gestionar el ciclo de vida de la aplicación y para eso hace uso del UIApplicationDelegate. De todas maneras es el UIApplication el que recibe los eventos pero se gestionan mediante el delegado.

Los eventos que se manejan desde el UIApplicationDelegate son por ejemplo arrancar la aplicación , cerrar la aplicación o eventos como que entre una llamada mientras la aplicación se está ejecutando.

Vamos a detallar un poco más lo eventos que podemos manejar:

didChangeStatusBarFrame: El frame de la barra de estado ha cambiado.
willChangeStatusBarFrame: El frame de la barra de estado va a cambiar.

didChangeStatusBarOrientation: Cambia la orientación de la barra de estado
willChangeStatusBarOrientation:duration: La orientación de la barra de estado va a cambiar y el parámetro duration le indica cuanto va a durar la animación.

handleOpenURL: Le indica al delegado que quiere abrir una url.

applicationDidBecomeActive: Se ejecuta justo después de que la aplicación vuelva estar activa de nuevo. Por ejemplo te ha entrado una llamada y has terminado, la aplicación vuelve a estar activa y justo en ese momento se ejecuta este evento.

applicationDidFinishLaunching: Se ejecuta cuando la aplicación ha terminado de cargarse.

applicationDidReceiveMemoryWarning: Cuando recibe este mensaje es debido a que el SO le ha enviado este mensaje a la aplicación ya que se ha quedado el dispositivo sin memoria pero antes de cerrarla se le da una "oportunidad" de ejecutar este método para que se libere la memoria que se pueda de la app.

applicationSignificantTimeCharge: Se ha producido un cambio significativo en el tiempo durante la ejecución de tu aplicación.

applicationWillResignActive: Se ejecuta antes de que pase a inactiva por ejemplo te entra una llamada.

applicationWillTerminate: La aplicación se cierra.

applicationDidEnterBackground: La aplicación va a entrar en segundo plano pero si la aplicación no tiene implementado multitarea en este método deberías guardar los estados de la aplicación, liberar la memoria ya que se queda en "pausa" en segundo plano y cuando el usuario vuelve a entrar estará en el estado en el que se quedó pero cuando está en esta "pausa" si el SO necesita memoria la va a cerrar.

applicationWillEnterForeground: La aplicación vuelve a primer plano.


Nota: El UIapplicationDelegate de nuestra aplicación es el nombreAplicaciónAppDelegate, se generá automáticamente cuando creamos un nuevo proyecto (independientemente de la plantilla que usemos) y esa clase hereda de NSObject e implementa el protocolo UIApplicationDelegate.

Nota: Cuando hablamos de que se produce un evento o el delegado recibe un evento significa en realidad que se envía un mensaje concreto al delegado en función de lo que suceda y de esa manera ejecute el código correspondiente.

viernes, 6 de agosto de 2010

Versión móvil del blog

Ya tenemos la versión móvil del blog para que podáis leerlo desde el iphone/ipod o ipad pudiendo si queréis cambiar a la vista clásica.

Espero que os resulte útil.

martes, 3 de agosto de 2010

Programación desde cero: Procedimientos y funciones

No sé si te habrás encontrado en algún manual algo relacionado con los conceptos de procedimientos y funciones aunque no sea así es importante para lo que es fundamentos de la programación en general.

Tanto un procedimiento como una función son porciones de código que hacen algo y que se les ha dado un nombre, por ejemplo imagínate que dentro de una misma aplicación quieres comprobar si un año es bisiesto y para ello hay que hacer una serie de comprobaciones, pero tu en tu aplicación tienes que hacerlo en varios sitios por lo que si copias el mismo código varias veces iba a quedar muy redundante a parte que si por lo que sea te has equivocado en alguna condición de año bisiesto tienes que andar buscando por toda la aplicación en los sitios en los que la copiaste para ir modificándolo.

¿Qué hacemos? pues a ese trozo de código le asignamos un nombre por ejemplo "comprobacionBisiesto" y de esa manera en todas las partes de la aplicación en las que quiera comprobar si un año es bisiesto tendría que poner "comprobaciónBisiesto" y de esa manera cuando tengamos que hacer un cambio en "comprobaciónBisiesto" solo lo haremos una vez.


Pero por ejemplo tomando como base "comprobaciónBisiesto" para poder evaluar si año es bisiesto debo decirle a "comprobaciónBisiesto" cuál es el año que quiero que compruebe y por ello lo que hacemos es pasarle parámetros, ésto es común tanto cuando hablamos de procedimientos como de funciones en cambio la diferencia entre ambos es si esa porción de código que hemos escrito (comprobaciónBisiesto) devuelve algo o no, por ejemplo si queremos que devuelva un dato lo haremos con una función y sino con un procedimiento.

Hay lenguajes de programación que lo que nos permiten es las funciones y procedimientos que los parámtros de entrada (en este caso sería el año) puedan ser parámetros también de salida (para así devolver varios datos) pero eso depende del lenguaje de programación por lo que aquí no nos interesa ya que estamos hablando de programación en general.

Eso si en las funciones como solo se devuelve 1 dato y solo 1 dentro del trozo de código hay que hacer un return con la información a devolver ya sea un dato o una variable.


En nuestro caso de ComprobaciónBisiesto devolvería un tipo de dato booleano (verdadero/falso) y de esa manera sabríamos si lo es o no. En función del lenguaje de programación el tipo booleano puede tomar valores como 0/cualquier número, 0/1, true/false... esta representación va en función del lenguaje de programación.

En este caso lo que estamos haciendo es pasarle a la función un año y nos devuelve si es bisiesto o no.



Booleano comprobacionBisiesto(entero Año){
booleano esBisiesto

//Aquí irian todas las comprobaciones pertinentes

si (esBisiesto)
return verdadero
sino
return falso
// Otra opción más eficiente sería: return esBisiesto
}



En éste caso le pasamos como parámetro un tipo de dato entero y mostramos por pantalla su área pero como ves no devuelve nada ya que es un procedimiento.


MostrarAreaCuadrado(entero a){

mostrarPorPantalla(a*a);

}





lunes, 2 de agosto de 2010

Programación desde cero: Variables

El concepto de variable es muy usado en el mundo de la programación y aunque al principio de meterte en este mundillo te suene a chino es un concepto muy sencillo.

Una variable es en realidad un dato, éste dato puede ser por ejemplo una cadena de texto, un número entero,un número decimal o tipo de dato booleano (verdadero o falso) pero de alguna manera tenemos que hacer referencia a este dato que tenemos, para ello usamos un nombre.

Por ejemplo imaginemos que tenemos un dato referente a una edad, la edad va a ser 27 ¿cómo almacenamos ese dato? pues para ello declaramos una variable denominada miEdad, el tipo de dato es entero y el valor va a ser 27.

Sin entrar en un lenguaje de programación concreto sería algo tal que así:

Entero miEdad;
miEdad=27;


En la primera línea hemos declarado el tipo de dato que va a almacenar la variable miEdad que va a ser un dato de tipo entero.
En la segunda línea por el contrario hemos dado el valor a la variable, como es el primer valor que se asigna, normalmente se dice que lo hemos inicializado a 27.

Te preguntarás que pasará si intentamos acceder al valor que tenga miEdad antes de ser inicializado, depende el lenguaje puede dar un error o devolver null.

Hay lenguajes de programación que permiten hacer ambas cosas en una línea de la siguiente manera:

Entero miEdad = 27;

Nota: Los atributos a los que hacíamos referencia en el post de Objetos son en realidad variables pero que dan información a cerca de un objeto por lo que se llaman atributos.

Foro de Iphone Programación

Debido al gran número de correos con preguntas que hemos recibido, muchas en los comentarios de los blogs y que en muchos casos se repiten nos ha parecido muy buena idea crear un foro para centralizarlo todo y de esa manera aprender todos mejor :)

Espero vuestros posts!!!!

www.foroiphoneprogramacion.com

Si detectáis cualquier error o queréis comentarnos algo, sugerencias... ya sabéis!!!

pynsoftware@gmail.com

Sentencias iterativas en objetive-C: Bucle FOR

¿Cuándo usarlo?

Este tipo de bucle se usa siempre y cuando conocemos el número de veces que se va a ejecutar un determinado código.

Sintaxis

for (inicialización del contador (1); condición de ejecución (2); actualización del contador(3)){

// Código a ejecutar

}

Secuencia de ejecución

1. Se inicializa el contador (1).
2. Se comprueba que el contador cumple la condición de ejecución(2).
2.1 Si cumple la condición se ejecuta el código a ejecutar y se actualiza el contador(3) y volvemos al paso 2.
2.2 Si no cumple la condición se sale del bucle for.

Ejemplo básico:

for (int i=0; i<10;i++) contador =" %d\n">

2010-08-02 02:22:27.912 pruebas[910:207] Contador = 0

2010-08-02 02:22:27.914 pruebas[910:207] Contador = 1

2010-08-02 02:22:27.915 pruebas[910:207] Contador = 2

2010-08-02 02:22:27.915 pruebas[910:207] Contador = 3

2010-08-02 02:22:27.916 pruebas[910:207] Contador = 4

2010-08-02 02:22:27.917 pruebas[910:207] Contador = 5

2010-08-02 02:22:27.918 pruebas[910:207] Contador = 6

2010-08-02 02:22:27.918 pruebas[910:207] Contador = 7

2010-08-02 02:22:27.919 pruebas[910:207] Contador = 8

2010-08-02 02:22:27.920 pruebas[910:207] Contador = 9



Notas:
Se puede declarar el contador fuera de la inicialización del contador.
La actualización del contador puede tomar diferentes formas:
- Incrementar: i++
- Decrementar: i--
- Cualquier otro tipo de modificación es válido, por ejemplo si queremos que se actualice de dos en dos sería de la siguiente manera: i = i + 2

Otro ejemplo:

for (int i=0; i<=10; i=i+2) { NSLog(@"Contador = %d\n",i); }

2010-08-02 02:22:27.920 pruebas[910:207] Contador = 0

2010-08-02 02:22:27.921 pruebas[910:207] Contador = 2

2010-08-02 02:22:27.921 pruebas[910:207] Contador = 4

2010-08-02 02:22:27.922 pruebas[910:207] Contador = 6

2010-08-02 02:22:27.922 pruebas[910:207] Contador = 8

2010-08-02 02:22:27.923 pruebas[910:207] Contador = 10


Otro ejemplo:

for (int i=1; i<30; i="i*3)" contador =" %d\n">

2010-08-02 02:22:27.923 pruebas[910:207] Contador = 1

2010-08-02 02:22:27.924 pruebas[910:207] Contador = 3

2010-08-02 02:22:27.925 pruebas[910:207] Contador = 9

2010-08-02 02:22:27.925 pruebas[910:207] Contador = 27


Ejemplo usando como contador un carácter:

Como ves no es necesario usar un contador de tipo entero para el bucle for.

for (char i='b'; i<'f';i++) { NSLog(@"Letra = %c\n",i); }


2010-08-02 02:22:27.923 pruebas[910:207] Contador = b

2010-08-02 02:22:27.924 pruebas[910:207] Contador = c

2010-08-02 02:22:27.925 pruebas[910:207] Contador = d

2010-08-02 02:22:27.925 pruebas[910:207] Contador = e


Otra versión:

for (char i='b'; i<'l';i=i+2) { NSLog(@"Letra = %c\n",i); }

2010-08-02 02:22:27.929 pruebas[910:207] Letra = d

2010-08-02 02:22:27.930 pruebas[910:207] Letra = f

2010-08-02 02:22:27.930 pruebas[910:207] Letra = h

2010-08-02 02:22:27.931 pruebas[910:207] Letra = j


Como ves solamente el bucle for da mucho juego!!!! :D