Blog d'un développeur multi-support

[DIM] pour les intimes :)

Nouveauté du site

Comme c’est à la mode, j’ai succombé à FriendFeed. J’ai donc remodelé ce blog en fonction.

A la place de l’encadré « ma veille quotidienne » où je vous donnais tous mes flux que je suivais et qui au final n’était pas très intéressant je l’ai remplacé par mon flux d’activité delicious/google reader. Il y aura donc en temps réel une sélection d’article qui me semble intéressant.

A propos des commentaires de mes articles je laisse le système par défaut, mais je donne en plus la possibilité de voir les réactions sur FriendFeed et si vous avez un compte vous pourrez directement réagir à partir de la page. Peut être qu’avec deux systèmes il y aura deux fois plus d’activité (ou pas ^^).

A oui, et mon compte FriendFeed est : http://friendfeed.com/guillaumechave. Pour les raleurs qui diront « ouais mais tu connais personne la looze », je leur dirait « je viens de m’inscrire et je t’emm*** » :p

Image representing FriendFeed as depicted in C...
Image via CrunchBase
Tags :

Débuter sur le développement iPhone

Salut,
Il m’est arrivé plusieurs fois qu’on me demande ce qu’il faut pour bien débuter sur iPhone. La question est simple, la réponse un peu moins. Je vais commencer par le plus simple, le matériel.

Matériel :

  • un Mac intel. Désolé mais vos vieux mac à la cave ne marcheront pas.
  • un de test. Le simulateur ne suffit pas.
  • une licence de développeur Apple. (Pas bien cher, 70€ je crois ..). Ceux qui disent  « Mais je jailbreak j’envoie mes appli en SSH et fuck Apple » je leur répond « Vous vous faites bien chier. » Et les solutions pour auto signer son code pour l’envoyer « comme en vrai » c’est pas trop la joie (faut refaire les manips pour chaque projets ..)

Sinon pour développer sur PC (windows notamment) sachez qu’on peut compiler des applis et se les envoyer en SSH etc. C’est faisable, mais alors quel perte de temps et vous verrez dans la suite de l’article qu’on y gagne pas tant que ça.

Logiciels :

  • Xcode le seul et unique IDE sympathique. Il auto-complète un peu, permet de compiler directement sur le téléphone sans prise de tête, fourni un debugger pas à pas.
  • Interface Builder. Ça c’est le truc tape à l’oeil  qu’Apple met en avant. C’est pour construire les écrans et relier les éléments graphiques à leurs représentations « code ». C’est super pratique et beaucoup plus ergonomique que de le faire sur Android :
    // Lie les champs graphiques à des champs codes
    EditText login = (EditText) findViewById(R.id.login);
  • Instruments. Super pratique pour voir l’état en temps réel de l’iphone : consommation CPU, RAM, allocations d’objets etc. C’est avec ce genre d’outils que tu te dis « en fait je ne sais pas coder léger »

Donc on voit bien que même s’il existe des solutions pour compiler sur PC, les « toolchain iphone » c’est quand même dommage de se séparer de ces logiciels. Encore que pour Xcode eclipse doit pouvoir suffir, les deux autres logiciels n’ont pas l’air d’avoir d’équivalent.

Et puis la finalité de développer sur iPhone c’est bien d’avoir son quart d’heure de gloire sur l’appStore non ? Alors autant commencer bien et dans la légalité. Car si Apple découvre que vous n’avez pas utilisé ses outils, que votre appli est dispo en jailbreak etc .. ben c’est foutu après.

Langage de programmation

Je suis passé par 3 phases quand j’ai commencé à programmer en objective-c.

  • Déroutant au début (retain une variable ? Kesako ?)
  • a l’air d’avoir des mécanismes complexes (le parsage d’XML est chelou quand on vient du web php/as3 etc)
  • Pratique et puissant quand on comprend les mécanismes par delegate, que l’on joue avec les threads, que l’on crée ses propres classes outils (comme pour ma classe de requete http)

Mais comment apprendre ce langage ? la réponse est simple : dans la documentation.

Documentation et

La documentation et les guides Apple sont bien pratiques pour appréhender le langage et les mécanismes.

Cependant pour appréhender Interface Builder et sa relation avec le code c’est pas trop ça. Je conseille les tutos d‘ipup.fr qui ont pas mal d’images et surtout que c’est français.

Sinon pour plus de liens, je vous conseille toujours les liens de mon précédent article « créer des applications iphone » et mon flux delicious :

ps : Si vous voulez suivre mes « découvertes » iphone,  mon flux delicious est constamment mis à jour ! http://delicious.com/onishinji/iphone

Tags : ,

iPhone & NSTimer

Salut,

Les NSTimers sont bien cool et en général ça ne pose aucun souci à les utiliser. J’ai bien dit en général. J’ai eu un souci avec ce matin…vraiment étrange.

Sur un projet, j’en utilise un pour déclencher une méthode dans XX secondes une fois seulement. Ça marche impeccable. Sur un nouveau projet, je réutilise le même mais en faisant varier un paramètre « repeats » à YES. Et bien sur, ça ne marchait plus.

Voici un timer qui déclenche une méthode une seule fois :

1
2
3
4
5
6
7
8
-(void)blabla
{
	[NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:@selector(test:) userInfo:nil repeats:NO];
}
-(void)test:(NSTimer*)timer
{
	NSLog(@"je suis appelé 1 fois");
}

Un timer qui se déclenche une méthode en boucle, techniquement il faudrait juste dire « repeats:YES » mais ca n’a pas marché dans mon cas. Le timer n’était jamais « fired » :p (je m’essaie à l’anglais)

1
2
3
4
5
6
7
8
-(void)blabla
{
	[NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:@selector(test:) userInfo:nil repeats:YES];
}
-(void)test:(NSTimer*)timer
{
	NSLog(@"je suis appelé en boucle c'est la fête.");
}

Donc voici ce que j’ai utilisé pour que ça marche. J’ai forcé le démarrage du timer en boucle.

1
2
3
4
5
6
7
8
9
10
-(void)blabla
{
	NSTimer * timer = [NSTimer timerWithTimeInterval: 1 target: self selector: @selector(test:) userInfo: nil repeats: YES];
 
	[[NSRunLoop mainRunLoop] addTimer: timer forMode: NSDefaultRunLoopMode];
}
-(void)test:(NSTimer*)timer
{
	NSLog(@"je suis appelé en boucle c'est la fête.");
}

Voilà voilà

Tags : ,

iPhone & Trucs et Astuces

Bonjour tout le monde, encore de l’ .. et ouais j’aime bien faire des petits exemples :p

Cette fois ci à la demande non général de Sébastien H. voici quelques éléments de que j’utilise dans mes applications.  Donc voici ce qu’il y a dans cet exemple :

  • Comment créer et utiliser les préférences utilisateurs à travers l’objet NSUserDefaults et le fichier settings.bundle :p
  • Comment créer une vue modal. Vous savez ce genre d’écrans qui arrivent par le bas de l’application et qui repartent ensuite.
  • Je refait aussi un petit rappel sur les delegate iphone pour la vue modal.
  • Comment créer et utiliser le fameux menu d’actions à la façon safari pour permettre de fournir des boutons qui arrivent aussi par le bas de l’application (UIActionSheet)
  • Comment ouvrir d’autres applications installées sur l’iphone grâce à la méthode [UIApplication sharedApplication] :p

On m’a dit qu’il manquait un peu d’images, voici des screenshoots de l’application d’exemple :

Le design est assez simple ;p

Et n’oubliez pas de télécharger le projet Xcode de cet exemple

Tags : , , , ,

iPhone & Requete HTTP

Yop all,

A la demande général de Fabrice Bernhard, voici une classe que j’ai faite pour me simplifier la vie quand je dois faire une requête HTTP. Vous me direz « pas besoin blabla », mais cette classe gère l’envoie d’images, de sons en plus de simple paramètres POST classique. Vous faites moins les malins hein :) Et si je vous dit qu’elle gère aussi si la requête doit être fait en mode synchrone ou asynchrone hein ? Ça t’en bouche un coin ?

Bah en fait elle est très simple, j’ai juste joué au légo avec les classes Apple, mais c’est un lego qui me sert pas mal.

Voici un exemple d’utilisation, ce code est tiré de l’exemple que j’ai fait pour vous, disponible en téléchargement :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
-(IBAction) send
{
// Crée la requete en mode asynchrone
HttpRequest *masuperRequete = [[HttpRequest alloc] initHttpRequest:formUrlAsk.text isSynchronous:false];
 
// Ajoute un parametre POST['cleParam'];
[masuperRequete addParam:@"cleParam" valeurs:formParam.text];
 
// Ajoute un fichier Image. Les parametres seront sous la forme file1, file2, file3 .. etc
[masuperRequete addImage:imageTmp.image];
 
// ajoute un son
// On doit recuperer les données du son sous la forme d'un NSDATA
// Ici le son est distant .. on le recupère donc avec the super classe en mode syncrhone
HttpRequest *sousReq = [[HttpRequest alloc] initHttpRequest:formUrlSound.text isSynchronous:true];
NSData * dataSound = [sousReq send];
 
// Recupere le nom du son
NSArray * mots = [formUrlSound.text componentsSeparatedByString:@"/"];
NSString *nameoffile = [mots lastObject];
 
[masuperRequete addSound:dataSound nameoffile:nameoffile nameinform:@"mamusique"];
 
// Envoie la superRequete
masuperRequete.delegate = self;
[masuperRequete send];
}
 
// y a un delegate pour recup le retour de la requete en mode asynchrone
-(void)downloadFinish:(NSMutableData *)data
{
NSLog(@"telechargement termine");
}

Maintenant voici le code source complet de l’exemple

Exemple de la classe HTTPRequest

Pour récupérer les données par la suite, rien de plus simple tout est dans $_POST et $_FILES.

maj : voilà le code source du fichier php que j’ai utilisé :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
 
<?php
 
$content_dir = 'upload/';
 
if(count($_POST) > 0 || count($_FILES) > 0)
{
 
 
 
 
	if(count($_POST) > 0)
	{
		echo "variable POST : \n";
		foreach($_POST as $cle=>$val)
			echo $cle . ' => ' . $val ."\n";
 
		if(isset($_POST['monson']))
		{
			$test = base64_decode($_POST['monson']);
 
			$file = fopen("upload/son.caf","w+");
 
			fwrite($file,$test);
 
			fclode($file);
		}
 
	}
 
	if(count($_FILES) > 0)
	{
		echo "variable FILES : \n";
		foreach($_FILES as $cle=>$image)
		{
 
			$tmp_file = $image['tmp_name'];
 
			if(!empty($tmp_file))
			{
 
 
				if( !is_uploaded_file($tmp_file) )
				{
					exit("Le fichier est introuvable");
				}
 
				// on vérifie maintenant l'extension
				$type_file = $image['type'];
 
				if( !strstr($type_file, 'jpg') &#038;&#038; !strstr($type_file, 'jpeg') &#038;&#038; !strstr($type_file, 'bmp') &#038;&#038; !strstr($type_file, 'png') &#038;&#038; !strstr($type_file, 'gif') )
				{
					//exit("Le fichier n'est pas une image");
				}
 
				// on copie le fichier dans le dossier de destination
				$name_file = $image['name'];
 
				echo $cle. " => " .$name_file ." reçu \n";
 
				if( !move_uploaded_file($tmp_file, $content_dir . $name_file) )
				{
					exit("Impossible de copier le fichier dans $content_dir");
				}
 
			}
	}
}
}
else
{
	 $rep = "upload/";
	$dir = opendir($rep);
 
	while ($f = readdir($dir)) {
  	 if(is_file($rep.$f)) {
    		echo "<li>Nom : ".$f;
		echo '<a href="upload/'.$f.'"> DL </a>';
      		echo "<li>Taille : ".filesize($rep.$f)." octets";
      		echo "<br /><br />";
   		}
	}
}
 
 ?>

Précisons quand même que ma classe est en alpha, certaines fonctionnalités ne sont pas implémentés. Je pense notamment à la gestion des erreurs, le qui donne le taux de progression de l’upload etc. Je vous laisse le faire :p

Enjoy !

Image representing Apple as depicted in CrunchBase

Image via CrunchBase

Tags : , , , ,