quelques notes sur le développement d’applications iPhone

aucun commentaire

Voici quelques notes prises lors de mon auto-apprentissage sur le développement d’applications iphone.

En effet, étant du genre « c’est quoi déjà? », j’ai regroupé quelques informations dans cet article afin de pouvoir centraliser certaines informations que j’ai trouvées pertinentes… En espérant que cela puisse vous aider aussi.

L’essentiel des informations étant en anglais, j’ai donc laissé l’information dans la langue originale.

Some Objective-C stuff

  • When declaring a method, « - » is fr instance methods, « + » is for Class methods.
  • If you message nil, it returns zero.
  • with NSString inValue returns 0 if it’s not an integer. If it starts with an integer but followed by « crap » (9873ikdi) it will return the integer (9873). Same thing with floatValue, doubleValue…
  • If you overwite the -(id) init method, always return the result of [super init].
  • when release method is called, the retain count is decreased, if it’s zero then the dealloc s called
  • never call -(void)dealloc directly, except if you overwite the -(void)dealloc method, you should call [super dealloc].
  • if your method returns an object that you created in the method:
    • use the [newObject autorelease] or
    • prefix your method name with « alloc », « copy » or « new » to inform the developer that he will have to release it
  • balance the number of retain and release
  • If you use autorelease, the object will be put in the autorelease pull. At the end of the event handling cycle,  the autorelease pull will call the release method on the objects in the pull, and if the retain count hits 0, the object is deallocated)
  • « attribute.property = value » will call the setter, but « property = value » will access the property directly
  • you can overwite -(void) awakeFromNib method in your AppDelegate to initialize values

From « iPhone Application Programming Guide« 

  • When your application quits, you should save out information about your application’s current state in addition to any unsaved data. At launch time, you should look for this state information and use it to restore your application to the state it was in when it was last used.
applicationDidFinishLaunching: Use this method to restore the application to the state it was in during the previous session. You can also use this method to perform any custom initialization to your application data structures and user interface.
applicationWillTerminate: Use this method to save any unsaved data or key application state to disk. You can also use this method to perform additional cleanup operations, such as deleting temporary files.
  • All applications should respond to this notification and do their part to help relieve the memory pressure. For information on how to handle such notifications in your application, see “Observing Low-Memory Warnings.”
  • Icon.png is mandatory
  • an application can be interrupted by an incoming phone call, an SMS message, a calendar alert, or by the user pressing the Sleep button on a device.(…) If the user decides to take a call or reply to an SMS message, however, the system does proceed to terminate your application.
  • A keychain is a secure, encrypted container for passwords and other secrets. The keychain data for an application is stored outside of the application sandbox.
  • Avoid writing cache files to disk. The only exception to this rule is when your application quits and you need to write state information that can be used to put your application back into the same state when it is next launched.
  • Unlike most desktop applications, where the user manually chooses when to save files to disk, your application should save changes automatically at key points in your workflow. Exactly when you save data is up to you, but there are two potential options. Either you can save each change immediately as the user makes it, or you can batch changes on the same page together and save them when the page is dismissed, a new page is displayed, or the application quits. Under no circumstances should you let the user navigate to a new page of content without saving the data on the previous page.
  • If your application accesses the network using the Wi-Fi radios, you must notify the system of that fact by including the UIRequiresPersistentWiFi key in the application’s Info.plist file. The inclusion of this key lets the system know that it should display the network selection panel if it detects any active Wi-Fi hot spots. It also lets the system know that it should not attempt to shut down the Wi-Fi hardware while your application is running.
  • UIView:

View class hierarchy

NSFetchedResultsController: A « helper » controller between TableViewController and Core Data.

  • Load data lazily
  • multiple NIBs so you don’t load everything at the same time
  • Every controllers can receive didReceiveMemoryWarning… By default, it will unload all the views that are not on screen… So ViewDidLoad can be called more than once (at te beginning and after a memory Warning when the view needs to be reloaded)

More to come from the « iPhone Human Interface Guide« …

Sources:

http://developer.apple.com/iphone/index.action

http://deimos3.apple.com/WebObjects/Core.woa/Browse/itunes.stanford.edu.3124430053.03124430055

Ma première application iphone

aucun commentaire

Première application iphone

Et oui, il faut bien commencer un jour, je viens de finir ma première application iphone…

Pas très créatif (une simple calculatrice), pas de quoi être fier (de nombreuses améliorations sont possibles, notamment cacher le clavier une fois terminé…), mais tout de même… Pour une première application pour tester et apprendre objective-C, XCode, c’est pas pire, non?

Il me reste encore beaucoup de lecture à faire, notamment le « iPhone Human Interface Guideline« …

Un souvenir, histoire de rire de moi si je fais mieux dans quelques semaines ou quelques mois…

Geolocalisation

1 commentaire

Il y a longtemps que je voulais jouer avec la Geolocalisation, j’ai donc monté ce mini-site afin de tester différentes méthodes de géolocalisation:

  • geoIP: librairie PHP
  • Google Maps v3: aucune magie ici (pas de la geolocalisation), mais il y a possibilité d’utiliser les fonctionnalité GPS de l’équipement. Le « sensor » GPS n’est pas utilisé sur mon site, mais google Maps est utilisé de 2 façons:
    • pour ajuster les résultats des autre méthodes de géolocalisation (la « pin » est déplaçable)
    • comme méthode par défaut: un outils de recherche à la google Maps (en extrêmement simple simple simple) est offert
  • Google Gears
  • la geolocalisation des navigateurs « qui ont de l’allure » (firefox, safari) (navigator.geolocation.getCurrentPosition()). Lire https://mozillalabs.com/blog/2008/10/introducing-geode/ pour plus d’info sur l’implémentation dans firefox
  • Google Ajax API: en plus d’avoir accès à pleins de fonctionalités comme Google Maps, Feeds, Search, Earth, google Friends, etc… cette API permet aussi faire de la localisation  (merci à Marc Grabanski)

En plus, j’ai utilisé 2 API « géolocalisées »:

Vous pouvez assayer le tout l’URL suivante: http://geo.fruitsoftware.com/

Amusez-vous!

Symfony, project:deploy et cygwin

aucun commentaire

Pour tous ceux qui comme moi ne comprenaient pas pourquoi le « sync » de symfony gelait sur leur Windows, avec cygwin, voici l’astuce du jour (trouvé sur le trac de symfony):

Ajouter la ligne suivante dans votre properties.ini (par environnement):

[prod]
host=www.mywebproject.com
port=22
user=USERNAME
dir=/home/path/to/project/on/prod/
parameters="-azvC --force --delete --exclude-from=config/rsync_exclude.txt"

PS.1: j’avais trouvé une autre astuce qui nécessitait de modifier le fichier de la tache projectDeploy de Symfony (en ajoutant un « exec »), mais cette méthode est bien plus propre, merci!

PS.2: j’ai ajouté l’option « v » (=verbose) afin que rsync liste les fichiers qui sont affecté par la synchronisation. C’est à vous de voir!
PS.3: Il m’arrive de devoir changer les permissions des fichiers sur production (plus qu’un simple « symfony project:permissions »), donc histoire à suivre…
PS.4: Suite de l’histoire: Idiot, cygwin utilise les permissions à-la-Unix, il suffisait de mettre les bonnes permissions avec cygwin…

Merci Symfony

1 commentaire

Il était une fois…

IL était une fois une équipe qui réalisa un site web pour un client. Tout se passa normalement au cours du développement.
Mais un jour, alors que nous devions mettre sur le serveur du client, nous apprîmes (oui, oui! apprîmes) que:

  • le serveur du client était en fait 2 serveurs,
  • ces 2 serveurs étaient « load-balancés » (pas de » sticky-tcpip » possible)
  • la gestion des sessions PHP était « basique » (file)
  • nous n’avions pas la possibilité de changer la configuration des 2 serveurs (pour utiliser memcached par exemple) ou du « load-balancer »

(je vous passe les détails de mauvaises communications entre les équipes techniques en jeu…)

Horreur!

Qu’allons-nous devenir?

Que faisons-nous?

OMG!

Heureusement…

…tel le petit poucet qui avait pris soin de mettre des pierres dans ses poches, nous avions développé notre site avec le framework Symfony (1.4).

Il est possible de changer très facilement la manière dont sont sauvegardées les sessions PHP avec Symfony, grâce au fichier factories.yml.

Il n’a donc pas fallu plus que 30 minutes pour changer la manière de gérer les sessions!

Merci à…

Notes

  1. Oui, je sais, j’ai mis un « S » majuscule à « Symfony », c’est pour m’habituer.
  2. « … et à la fin, ils firent pleins de projets Symfony. »

Symfony 2.0 – Notes

aucun commentaire

Some thoughts about Symfony 2. I didn’t play with the sandbox yet, I just read the doc and browse the code (a little bit). So more to come…

routing « inheritence »

One main routing file that can include to other routing files

# hello/config/routing.yml
homepage:
  pattern:  /
  defaults: { _bundle: WebBundle, _controller: Default, _action: index }

hello:
  resource: HelloBundle/Resources/config/routing.yml

Components are actions, yeah!!

Everything is an action, and you can include an action into a template. That’s great, no need to define an action that just include a component (when you need some ajax but the first load is not ajax)

Generating Links

The generate() method takes the route name and an array of values as arguments.

Mmm, I hope there is another way to generate a route, using the controller name and action name (like the old « url_for »…). I think it’s part of the « kill the magic » cleanup…

Assets and links to images, css, js…

<img src="<?php echo $view->assets->getUrl('images/logo.png') ?>" />

You will be able to change the URL root path of your web app without breaking any links. I love it, but HTML integrators will complain… But I like it… and they will (have to?) live with that.

« imports » directive in Configuration file: cleaner configuration files!

#in config_prod.yml
imports:
  - { resource: config.yml }

Facebook Connect friend selector jquery plugin – première version!

1 commentaire

Suite à l’article précédent sur mes problèmes pour créer un widget permettant de sélectionner un ami facebook sur un site facebook connect, j’ai finalement créer un plugin jquery.

Vous pouvez downloader le plugin sur github.com.

Des infos (sommaires pour l’instant) sont disponibles ici. J’espère que vous allez apprécier!

Traduction fr_FR pour le thème wordpress « Life is Simple »

aucun commentaire

J’ai fait une traduction rapide du thème « life is simple » en français (fr_FR) mais certainement plus fr_CA…

Vous pouvez le télécharger ici.

À utiliser/modifier selon vos besoins!!

J’aime ça…

aucun commentaire

500 error - foursquare

.htpasswd Apache Tips

aucun commentaire

To create the file

sudo htpasswd -c  .htpassword.CLIENT.PROJECT USERNAME

To add users to it

sudo htpasswd  .thenameofthefile USERNAME2

to configure a website (vhost) to use that file

 <Directory "/var/www/staging/PATH/TO/CLIENT/PROJECT/web">
        Options -Indexes
        AuthName "TD Staging Server"
        AuthType Basic
        AuthUserFile /var/www/staging/td/.htpassword.CLIENT.PROJECT
        Require valid-user
        AllowOverride All
        Allow from All

    </Directory>