smartfrog
smartfrog
SmartFrog Blog
14 posts
Développement Mobile
Don't wanna be here? Send us removal request.
smartfrog · 11 years ago
Text
iOs - Swift : Syntaxe de base et utilisation de code Objective-C
Apple vient de lancer un nouveau language de programmation, SWIFT. Language moderne et léger, il a pour but de rendre la plateforme d'Apple plus accessible aux développeurs.
Si vous avez déjà travaillé avec des languages comme ActionScript, Goo, C#, il ne vous faudra que peu de temps avant de vous sentir à l'aise.
Pour ce premier tuto, j'ai réalisé une petite application composée de deux écrans. Le premier écran affichera une liste de tweet, le second, la page internet pointée par le lien du tweet.  
Les points abordés par ce tuto sont : 
La création d'un projet iOs Swift
Configuration pour utiliser du code Objective-c
Déclaration de variables
Les optionnelles
Le casting
Les closures (Block en obj-c)
Utilisation de code Objective-c depuis Swift
Accessoirement, la lib STTwitter
Pré-requis
Vous devez avoir installé xCode 6
Téléchargez la bibliothèque : STTwitter
Avoir créer un application sur https://dev.twitter.com/
Télécharger le code source du tuto
Création d'un projet iOs Swift
Ici rien de nouveau par rapport à l'ancienne version d'xCode. A noter la présence d'un champ "Language" initialisé par défaut sur Swift.
Tumblr media
Ajout de la bibliothèque STTwitter
Dézippez l'archive téléchargée depuis GitHub et glissez/déposez le répertoire STTwitter dans xCode.
Tumblr media Tumblr media
Création du fichier Bridge pour utiliser du code Objective-C avec Swift
Pour pouvoir importer et utiliser du code Objective-C, il faut passer par un fichier de Bridging.
Commencez par créer un nouveau header.
Tumblr media
Appelez le comme vous voulez. La convention veut que les fichiers de Bridge soient nommés nomduprojet-Bridging-Header.h
Dans notre cas, tutoSwift01-Bridging-Header.h.
Il faut ensuite ajouter notre fichier dans les paramètres de build. Build Settings -> Objective-C Bridging Header.
Tumblr media
Maintenant éditez le fichier de bridge et ajoutez l'import de STTwitter.h
#import "STTwitter.h"
C'est bon, vous pouvez maintenant utiliser les classes de STTwitter depuis votre code Swift
Lancez une compile, tout devrait marcher sans problème.
Notions de base
Je ne vais pas ici vous détailler le code de toutes les pages et faire du pas-à-pas. Le but est de comprendre la syntaxe de Swift. Le code complet du tuto est dispo ici.
On va s'intéresser au code du fichier StatusViewController.
import UIKit class StatusViewController: UITableViewController { var twitterAPI:STTwitterAPI?; var arrayData:NSDictionary[] = []; init () { super.init(nibName: nil, bundle: nil) self.twitterAPI = STTwitterAPI(OAuthConsumerKey:"XXXXXXXXX", consumerSecret:"XXXXXXX", oauthToken:"XXXX", oauthTokenSecret:"XXXXXX"); self.twitterAPI?.getUserTimelineWithScreenName(nil, count:100, successBlock: { (objects: AnyObject[]!) in self.arrayData = objects as NSDictionary[]; self.tableView.reloadData(); }, errorBlock: { (error: NSError!) in println(error); } ) } override func viewDidLoad() { super.viewDidLoad(); self.title = "Status"; } // MARK: UITableView Delagate and DataSource override func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int { return self.arrayData.count; } override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell { var cell:UITableViewCell? = tableView.dequeueReusableCellWithIdentifier("statusCell") as? UITableViewCell; if (cell == nil) { cell = UITableViewCell(); } let status:NSDictionary = self.arrayData[indexPath.row] as NSDictionary; cell!.text = status.objectForKey("text") as String; return cell!; } override func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) { let status:NSDictionary = self.arrayData[indexPath.row] as NSDictionary; let statusViewController = StatusDetailViewController(); let entities:NSDictionary = status.objectForKey("entities") as NSDictionary; let urls:NSArray = entities.objectForKey("urls") as NSArray; let url:NSDictionary = urls[0] as NSDictionary; statusViewController.loadPage(url.objectForKey("url") as String); self.navigationController.pushViewController(statusViewController, animated:true); } }
Déclaration de variables
Pour déclarer une variable on utilise le mot-clé var et le mot-clé let pour une constante.
var twitterAPI:STTwitterAPI?; var arrayData:NSDictionary[] = []; let status:NSDictionary = self.arrayData[indexPath.row] as NSDictionary;
Les optionnelles
On peut voir la présence du symbole ? derrière le type de la variable (ici STTwitterAPI). Cela veut dire que la variable twitterAPI peut ne pas être initialisé et donc ne pas avoir de valeur ou plutôt être nil.
Lorsque que l'on souhaite accéder à un membre ou utiliser un fonction d'une variable optionnelle, il faut utiliser le caractère ?. Cela revient a tester si la variable est nil avant de tenter d'accéder à un membre ou une fonction.
self.twitterAPI?.getUserTimelineWithScreenName ...
Revient à faire :
if (self.twitterAPI) self.twitterAPI.getUserTimelineWithScreenName ...
Le casting
On utilise l'opérateur as pour caster un objet. L'opérateur is est lui utilisé pour pour vérifier le type d'un objet.
let status:NSDictionary = self.arrayData[indexPath.row] as NSDictionary;
Les closures (Block en obj-c)
C'est l'équivalent des Blocks en Obj-c. En gros c'est le fait de pouvoir définir une fonction  à un niveau local en prenant en compte des variables d’un scope supérieur.
self.twitterAPI!.getUserTimelineWithScreenName(nil, count:100, successBlock: { (objects: AnyObject[]!) in self.arrayData = objects as NSDictionary[]; self.tableView.reloadData(); }, errorBlock: { (error: NSError!) in println(error); }
La syntaxe générale est la suivante :
{ (parameters) -> return type in statements }
Dans notre exemple précédent on définit deux closures, une pour le success l'autre le l'error.
Appeler du code Objective-c depuis Swift
Pour le moment je n'ai pas trouvé ça très évident. Trouver la signature et la façons d'utiliser les méthodes déclarées en obj-c n'est pas intuitive. Dans la beta d'xCode 6, l'auto-complétion en swift ne semble pas être super au point. Du coup il faut aller voir l'header objc- et tenter de traduire la signature de la méthode que l'on souhaite utiliser en Swift.
Pour la conversion des types, elle doit normalement être auto, NString -> String, NSArray -> Array, NSDictionary -> Dictionary ... Je dis normalement car j'ai eu des problèmes dans l'utilisation du résultat de la méthode getUserTimeLine. L'obj-c retourne un NSDictionary que j'ai essayé d'utiliser en tant que Dictionary<String, AnyObject> mais ça ne fonctionnais pas correctement. Je me suis donc résigné à utiliser le type NSDictionary en Swift.
Conclusion
Voilà pour ce premier aperçu de Swift. Perso j'aime vraiment bien. La syntaxe est claire, légère, pas de gestion de mémoire, des mécanismes modernes (generique, subscript, closure, optionnelles) ... Après je ne suis pas forcément objectif, ayant codé pendant de nombreuses années en Actionscript, dont Swift reprend pour beaucoup la syntaxe. A vous de vous faire votre opinion.
0 notes
smartfrog · 12 years ago
Text
IOs 7 : Quoi de neuf pour les développeurs ?
Apple vient de lancer en grande pompe la nouvelle version de son système. Jamais une mise à jour n'avait apporté autant de changements. Nous allons faire un point sur ce que iOs 7 va apporter aux développeurs.
Interface Utilisateur
UIKit Dynamics :  c'est une sorte de moteur physique et d'animation qui va permettre de gérer la gravité, les collisions, le lien, la pousser sur nos UIView. Ce framework n'est pas prévu pour le jeu video mais pour donner un côté plus dynamique aux applications. On pense à l'effet parallax ou à l'effet lorsqu'on laisse retomber le panneau appareil photo depuis l'écran verrouillé.
Text Kit : Le but est de pouvoir manipuler le texte comme on le fait avec Core text mais beaucoup plus simplement. On pourra gérer tous les paramètres d'un texte, que ce soit l'apparence, le layout, la font... On retrouve ici les NSAttributedString qui avait été introduite dans iOs6 mais d'autres composants ont été ajoutés permettant de gérer le layout et définir la région ou sera afficher le texte.  Tous les composants contenant du texte (UiTextField, UITextView..) ont été recréés autour de Text Kit et donc les attributs que l'on peut appliquer sur le texte y seront directement disponibles.
    Multi-tâche
Des modifications ont été apportées au multi-tache déjà présent dans iOs 6 afin d'optimiser la batterie. De plus, Il est maintenant possible de réaliser des mises à jour de donnés en tache de fond. Les notifications pourront  également être gérées en tâche de fond avec des 'push silencieux'. 
    AirDrop
Permettra le partage de données entre deux terminaux "proches" physiquement. 
  Gaming
Apple à fait beaucoup pour le jeu vidéo dans iOs 7. On trouve une API pour la gestion des controllers (manettes ...) ainsi que SpriteKit un framework pour le développement de jeu 2D (du même genre que cocoa 2D).
    Camera / Photo / Vidéos
Apple nous donne la possibilité d'enregistrer des vidéos à 60fps, ce qui permettra de jouer avec le slow motion. On aura également le contrôle du zoom, l'accès à différent effets/transitions et la possibilité de combiner plusieurs pistes vidéos. Le scan de BarCode deviendrait également disponible.
  InterApp Audio
Permettra à votre applications d'échanger des flux audio afin de recevoir ou envoyer du son à d'autres applications. Cela devrait faciliter la création de projets musicaux sur un terminal iOS. Exemple une app gère la guitare, une autre le piano et une autre se charge de mixer les tracks pour faire un morceau.
    MapKit
Pas mal d'améliorations. Utilisation de la vue 3D où il sera possible de régler la position et l’angle de vue de la caméra. Autre point important, la possibilité de faire appel au service d'itinéraire.
  Pour finir ...
Les nouveautés notables sont surtout au niveau de interface graphique et du jeux vidéos. Avec UIKit Dynamique et TextKit, on nous donne le moyen de faire des applications proposant une nouvelle expérience utilisateur, conforme à la vision d'Apple.  Avec SpriteKit et la gestion des manettes de jeux, Apple pousse fort le développement de jeux vidéos. Combiné avec AirDisplay, l'iPhone/iPad pourraient remplacer une console de salon.
Les infos relatives à iOs 7 sont sous NDA, du coups pas de tutoriels prévus pour le moment. On se rattrapera cet automne lors de la sortie officielle de l'os.
0 notes
smartfrog · 12 years ago
Text
Application mobile : le pattern "Hamburger" SideBar
Vous l'avez surement déjà rencontré. Ce pattern est présent dans de nombreuses applications. Il tire son nom de l'icône (
Tumblr media
) indiquant qu'une liste d'options est disponible. Lorsque l'utilisateur appuie sur cette icône, la vue principale se déplace vers la droite, laissant apparaitre un menu. 
Google l'a adopté dans pratiquement dans toutes ses applications iPhone. Il est également présent dans les applications Facebook, Path et Feedly.
Gmail
Tumblr media
Google Plus
Tumblr media
YouTube
Tumblr media
Facebook
Tumblr media
Path
Tumblr media
Feedly
Tumblr media
Ce pattern permet d'afficher un menu de navigation assez conséquent  et des informations supplémentaires, sans perdre de place sur l'écran principale. 
Cela peut également permettre de proposer deux types de fonctionnalités aux utilisateurs. Des fonctionnalité accessibles sans avoir besoin de se connecter et d'autres nécessitants une connexion. Le formulaire de connexion sera alors affiché dans le menu de gauche. Une fois la connexion effectuée le formulaire de connexion est remplacé par la liste des fonctionnalités disponibles.
Tumblr media
Ce pattern est en train de devenir un "standard" et  vous allez le rencontrer de plus en plus. Gardez le en tête, il pourra vous être utile lors de la phase de conception de votre application.
Si vous faites du développement, vous trouverez des implémentations ici :
iOs 
devindoty/DDMenuController 
mystcolor/JTRevealSidebarDemo 
Inferis/ViewDeck
Android
jfeinstein10/SlidingMenu
Javascript 
SlidingMenuJS
1 note · View note
smartfrog · 12 years ago
Text
IOS Smart Layout - disposer facilement les éléments au sein de vos écrans
Si comme nous vous créez vos écrans IOS en disposant vos éléments programmatiquement, en vous passant du designer xCode, jetez un oeil à notre bibliothèque Smart Layout.
Nous avons créé ces composants car nous avions besoin de pouvoir positionner facilement des éléments horizontalement, verticalement ou en fonction du conteneur parent. 
Vous y trouverez 3 types d'UIView :
UIHView / UIVView : Organise les éléments horizontalement / verticalement. Vous pouvez spécifier l'alignement vertical (top, middle, bottom), l'alignement horizontal (left, center, right), le gap entre les éléments et le padding.
UIAbsolutView: Organise les éléments indépendamment les uns des autres. Vous ajoutez  les éléments avec les contraintes suivantes: top, bottom, left, right. Ces contraintes représentent l'espace entre l'éléments que vous ajoutez et les bords du conteneur parent.
Pour chacune de ces UIView vous pouvez définir une image de fond.
Utilisation de UIHView
[self setBackgroundImage:@"background"]; self.padding = 20; self.gap = 20; self.hAlign = center; self.vAlign = middle; UIButton * button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [button1 setTitle:@"Button1" forState:UIControlStateNormal]; [self addSubview:button1 withSize:CGSizeMake(200, 200)]; UIButton * button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; button2.frame = CGRectMake(0, 0, 200, 200); [button2 setTitle:@"Button2" forState:UIControlStateNormal]; [self addSubview:button2]; UIButton * button3 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [button3 setTitle:@"Button3" forState:UIControlStateNormal]; [self addSubview:button3 withSize:CGSizeMake(200, 200)];
Vous obtenez trois boutons positionnés horizontalement, centrés horizontalement et verticalement.
Tumblr media
Utilisation de UIVView
[self setBackgroundImage:@"background"]; self.padding = 20; self.gap = 20; self.hAlign = right; self.vAlign = middle; UIButton * button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [button1 setTitle:@"Button1" forState:UIControlStateNormal]; [self addSubview:button1 withSize:CGSizeMake(200, 200)]; UIButton * button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; button2.frame = CGRectMake(0, 0, 200, 200); [button2 setTitle:@"Button2" forState:UIControlStateNormal]; [self addSubview:button2]; UIButton * button3 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [button3 setTitle:@"Button3" forState:UIControlStateNormal]; [self addSubview:button3 withSize:CGSizeMake(200, 200)];
Vous obtenez trois boutons positionnés verticalement, centrés vericalement et alignés à droite.
Tumblr media
Utilisation de UIAbsolutView
[self setBackgroundImage:@"background"]; UIButton * button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [button1 setTitle:@"Button1" forState:UIControlStateNormal]; [self addSubview:button1 toTop:@20 right:@20 bottom:@20 left:@20]; UIButton * button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; button2.frame = CGRectMake(0, 0, 200, 200); [button2 setTitle:@"Button2" forState:UIControlStateNormal]; [self addSubview:button2 toTop:@30 right:nil bottom:nil left:@30]; UIButton * button3 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [button3 setTitle:@"Button3" forState:UIControlStateNormal]; button3.frame = CGRectMake(0, 0, 200, 200); [self addSubview:button3 toTop:nil right:@30 bottom:@30 left:nil];
Ici nous avons :
Le button 1 avec top 20, bottom 20, left 20, right 20 : occupera tout l'espace disponible en laissant une marge de 20 pixel, en haut, en bas, à gauche et à droite.
Le button 2 avec top 30, right nil, bottom nil et left 30 : conserve sa longueur et sa largeur d'origine. Il est positionné à 30 pixels du haut et à 30 pixels du bord gauche.
Le button 3 avec top nil, right 30, bottom 30 et left nil : conserve sa longueur et sa largeur d'origine. Il est positionné à 30 pixels du bas et à 30 pixels du bord droit.
Tumblr media
Essayer Smart Layout
Vous pouvez télécharger Smart Layout sur GitHub.
N'hésitez pas à nous faire part de vos remarques et demandes d'améliorations.
0 notes
smartfrog · 13 years ago
Text
Tutoriel iOs : Utiliser GitHub avec xCode
Dans ce tutoriel, nous allons sortir du développement iOs à proprement parler et s’arrêter sur la configuration de GitHub dans xCode.
Commencer par créer un repository sur GitHub pour votre projet
On l'appelle par exemple 'xCodeTest'.
Tumblr media
Créer un nouveau projet dans xCode
Tumblr media
Vérifier que "Create local git repository for this project" est coché.
Tumblr media
Configurer le projet pour qu'il fonctionne avec GitHub
Aller dans le menu d'XCode "File->Source Control/Repositories...".
Sélectionner ensuite le nom de votre projet et cliquer sur "Add Remote"
Tumblr media
Saisir un nom et l'adresse du repository sur GitHub.
Tumblr media
Ajouter ensuite votre nom d'utilisateur et votre mot de passe.
Tumblr media
Premier commit et push
Relancer xCode et rouvrer votre projet.
Faire une modification dans les sources et Aller dans "File->Source Control->Commit..." 
Tumblr media
Pour "pusher', "File->Source Control->Push..."
Tumblr media
Voila, votre projet est maintenant connecté à GitHub.
Tumblr media
1 note · View note
smartfrog · 13 years ago
Text
Tutoriel iOs : Twitter depuis son application
Depuis l'intégration de twitter dans iOs 5 il est devenu très simple de proposer des application qui permette de poster sur twitter.
Nous allons voir ici comment utiliser ce framework twitter dispo depuis iOs 5.
Création d'un nouveau projet
Dans Xcode, créez un nouveau projet de type SingleViewApplication. Vous pouvez appeler cette nouvelle application TwitterApp. Choisissez iPhone pour le type de device et assurez vous que Use Storyboard et Use Automatic Reference sont sélectionnés.
Cliquer sur MainStoryboard.storyboard pour afficher l’interface builder.
Insérez un button et indiquez "Twitter" comme label. 
Tumblr media
Il faut maintenant connecter notre button avec notre ViewController.
Vérifiez que l’ “Assistant Editor” est affiché.
Tumblr media
Dans l’assistant vous devez être en mode automatique et affiche ViewController.h
Tumblr media
Glisser le Button depuis le storyBoard vers la fenêtre du ViewController.h en maintenant la touche “control” enfoncée. Vous devez la déposer entre @interface et @end. Pour le type de connexion utilisé "Outlet" et indiquer "twitButton" pour le nom.
Tumblr media
Il faut maintenant ajouter une action pour le clique sur le bouton. Glisser de nouveau le Button depuis le storyBoard vers la fenêtre du ViewController.h en maintenant la touche “control” enfoncée. Déposer le juste après le IBOutlet créer précédemment. Cette fois choisissez "Action" dans le type de connection et "twitButtonTapped" pour le nom.
Tumblr media
Aufinal notre ViewController.h doit ressembler à ça :
#import <UIKit/UIKit.h> @interface ViewController : UIViewController @property (weak, nonatomic) IBOutlet UIButton *twitButton; - (IBAction)twitButtonTapped:(id)sender; @end
Il faut maintenant ajouter le code qui va permettre d'envoyer un twit après un clique sur le bouton.
Utilisation du framework Twitter d'iOs 5
 Avant de pouvoir utiliser TWTweetComposeViewController, il faut ajouter le framework twitter à notre application. Sélectionner notre projet dans le "project navigator' puis la target "TwitterApp". Aller dans l'onglet "Build Phase" puis cliquer sur le "+" de la section "Link binary with libraries". Ajouter "Twitter.framework".
Tumblr media
Ouvrez ViewController.m. Et ajouter l'import suivant : 
#import <Twitter/Twitter.h>
On ajoute le contenu de la méthode qui va être appelée lors du "tap" sur le bouton.
- (IBAction)twitButtonTapped:(id)sender { if ([TWTweetComposeViewController canSendTweet]) { TWTweetComposeViewController *tweetSheet = [[TWTweetComposeViewController alloc] init]; [tweetSheet setInitialText: @"Ca tweet à donf :)"]; [self presentModalViewController:tweetSheet animated:YES]; } else { UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Sorry" message:@"Vous ne pouvez pas twitter. Vérifier la connexion internet et qu'un compte twitter est configuré" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alertView show]; } }
Si vous n'avez pas configuré de compte twitter dans votre simulator, vous verrez l'alerte suivante :
Tumblr media
Dans le simulator, sortez de l'application et allez dans la section twitter des paramètres pour ajouter un compte.
Tumblr media
Testez de nouveau votre application, la tweetSheet apparaitra alors :
Tumblr media
Ajouter un lien à notre tweet
Il faut faire appel à la méthode addURL de TWTweetComposeViewController.
Modifier la méthode twitButtonTapped comme suit :
- (IBAction)twitButtonTapped:(id)sender { if ([TWTweetComposeViewController canSendTweet]) { TWTweetComposeViewController *tweetSheet = [[TWTweetComposeViewController alloc] init]; [tweetSheet setInitialText: @"Ca tweet à donf :)"]; [tweetSheet addURL:[NSURL URLWithString:@"http://smartfrog.fr"]]; [self presentModalViewController:tweetSheet animated:YES]; } else { UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Sorry" message:@"Vous ne pouvez pas twitter. Vérifier la connexion internet et qu'un compte twitter est configuré" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alertView show]; } }
Vous obtiendrez alors :
Tumblr media
De la même façon vous pouvez ajouter une image présente sur l'iPhone avec la méthode - (BOOL)addImage:(UIImage *)image .
Vous pouvez télécharger les sources de ce tutorial ici : TwitterApp.zip
0 notes
smartfrog · 13 years ago
Text
Revue de tweets du 13 octobre 2012
Tablette - La chaîne de télévision Gulli lance sa première tablette sous Android à destination des enfants : Consulter l'article
Tablette - L’usage de la tablette renforce la fréquentation de la TV des 18-49 ans aux USA : Consulter l'article
Mobile - Trafic web mobile en France : 74,8% iOs - 23,5% Android - 0,6% Bada - 0,3% BlackBerry - 0,2% Symbian - moins de 0,2% Windows Phone : Consulter l'article
HTML5 - Microsoft adapte le hit Contre Jour au Web : Consulter l'article - Jouer
iOs - Using Charles Proxy to examine iOs apps : Consulter l'article
iOs - Enable Kid Mode in iOS - Consulter l'article
Smart TV - Spotify diffuse la musique sur les TV Samsung : Consulter l'article
UX - How FlipBoard was created and its plan beyond iPad : Consulter l'article
0 notes
smartfrog · 13 years ago
Text
Tutoriel iOs : Parser des données JSON
Depuis iOs 5, il n'est plus nécessaire de passer par des bibliothèques tiers pour parser du JSON. Nous allons voir ici comment utiliser cette API afin de récupérer des données provenant de YouTube et les afficher dans une TableView.
Nous allons utiliser le service suivant http://gdata.youtube.com/feeds/api/standardfeeds/most_popular qui permet de récupérer les vidéos les plus populaires de YouTube.
Pour commencer, affichage d'une TableView
Dans Xcode créer un nouveau projet de type SingleViewApplication. Vous pouvez appeler cette nouvelle application YouTubeJson. Choisissez iPhone pour le type de device et assurez vous que Use Storyboard et Use Automatic Reference sont sélectionnés.
Cliquer sur MainStoryboard.storyboard pour afficher l’interface builder.
Tumblr media
Depuis la bibliothèque d’objets, sélectionnez  TableView et glissez le sur la vue.
Tumblr media Tumblr media
Vérifiez que l’ “Assistant Editor” est affiché.
Tumblr media
Dans l’assistant vous devez être en mode automatique et affiche ViewController.h
Tumblr media
Il faut maintenant glisser la TableView depuis le storyBoard vers la fenêtre du ViewController.h en maintenant la touche “control” enfoncée . Vous devez la déposer entre @interface et @end.
Une popUp apparait. Indiquez Outlet comme type de connexion et nommer la variable _tableView. Cliquez sur connect.
Tumblr media
Il faut maintenant indiquer dans ViewController.h qu'il faut implémenter UITableViewDelegate et UITableViewDataSource.
@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
Il faut également rajouter une propriété tableViewArray de type NSArray qui contiendra les données à afficher dans la liste.
Le fichier ViewController.h doit ressembler à cela :
#import <UIKit/UIKit.h> @interface ViewController : UIViewController { NSArray *tableViewArray; } @property (weak, nonatomic) IBOutlet UITableView *_tableView; @property (nonatomic, retain) NSArray *tableViewArray; @end
Maintenant en lançant l'application, nous allons voir la liste s'afficher.
Tumblr media
Récupération des données
Dans ViewController.m, on ajoute l'accès à la propriété tableViewArray via @synthesize.
@implementation ViewController @synthesize tableViewArray;
Dans la méthode ViewDidLoad nous faisons appel au service YouTube
NSError *error = nil; NSData *jsonData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://gdata.youtube.com/feeds/api/standardfeeds/most_popular?v=2&alt=json"]]; id jsonObjects = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
Il faut ensuite parcourir notre objet pour accéder aux champs qui nous intéressent. Pour récupérer un objet on utilise une variable de type NSDictionary et une variable de type NSArray pour des tableaux d'objets.
Nous allons dans un premier temps récupérer l'objet "feed" qui est une propriété de notre objet Json principal :
NSDictionary *feed = [jsonObjects objectForKey:@"feed"];
Puis la liste des "entries" contenue dans cet objet "feed"
NSArray *entries = [feed objectForKey:@"entry"];
Nous parcourons ensuite la liste des "entry" afin de récupérer les titres pour les afficher dans notre TableView.
NSMutableArray *titles = [[NSMutableArray alloc] initWithCapacity:[entries count]]; for (NSDictionary *item in entries) { [titles addObject:[[item objectForKey:@"title"] objectForKey:@"$t"]]; } self.tableViewArray = titles;
Pour afficher toutes les propriétés d'un objet, nous pouvons procéder comme suit :
NSArray *keys = [item allKeys]; // values in foreach loop for (NSString *key in keys) { NSLog(@"%@ is %@",key, [item objectForKey:key]); }
La méthode ViewDidLoad au final doit être ainsi :
- (void)viewDidLoad { [super viewDidLoad]; NSError *error = nil; NSData *jsonData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://gdata.youtube.com/feeds/api/standardfeeds/most_popular?v=2&alt=json"]]; id jsonObjects = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error]; NSDictionary *feed = [jsonObjects objectForKey:@"feed"]; NSArray *entries = [feed objectForKey:@"entry"]; NSMutableArray *titles = [[NSMutableArray alloc] initWithCapacity:[entries count]]; for (NSDictionary *item in entries) { NSArray *keys = [item allKeys]; // values in foreach loop for (NSString *key in keys) { NSLog(@"%@ is %@",key, [item objectForKey:key]); } [titles addObject:[[item objectForKey:@"title"] objectForKey:@"$t"]]; } self.tableViewArray = titles; }
Affichage des données dans la TableView
Il faut rajouter les méthodes numberOfRowsInSection et cellForRowAtIndexPath fournies par le delegate. NumberOfRowsInSection retourne le nombre de ligne  et cellForRowAtIndexPath permet d'indiquer le contenu d'une ligne de la TableView.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [tableViewArray count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SimpleTableIdentifier"]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"SimpleTableIdentifier"]; } cell.textLabel.text = [tableViewArray objectAtIndex:indexPath.row]; return cell; }
Il faut maintenant faire le lien entre la TableView et les données du contrôleur. Il faut retourner dans MainStoryboard.storyboard. Sélectionner la TableView et afficher le connection inspector. Faites ensuite le lien entre delegate et viewController et dataSource et viewController.
Tumblr media
Vous pouvez maintenant lancer votre application pour voir la liste des vidéos les plus populaires de YouTube.
Tumblr media
Les sources de ce tutoriel sont disponible ici : YouTubeJson.zip
1 note · View note
smartfrog · 13 years ago
Text
Tutoriel iOs : Utilisation de MapKit
Pour ce premier tutorial nous allons nous intéresser à l'utilisation de MapKit. Cette Api permet d'afficher facilement une carte, des annotations et des itinéraires. C'est un élément qui peu revenir assez régulièrement lorsque vous réalisez une application iPhone.
Dans ce tutorial nous allons afficher sur une carte les stations RATP que nous avons récupérées dans un fichier CSV open data. 
Pour commencer, affichage d'une carte.
Dans Xcode créer un nouveau projet de type SingleViewApplication. Vous pouvez appeler cette nouvelle application RatpMap. Choisissez iPhone pour le type de device et assurez vous que Use Storyboard et Use Automatic Reference sont sélectionnés.
Cliquer sur MainStoryboard.storyboard pour afficher l'interface builder.
Tumblr media
Depuis la bibliothèque d'objets, sélectionnez  MapView et glissez le sur la vue.
Tumblr media Tumblr media
Cliquez sur la MapView que vous venez d'ajouter, puis sélectionner le quatrième onglet de l'inspector et ajoutez "Show User Location".
Tumblr media
Ainsi l'application récupèrera la position de l'iPhone et l'affichera sur la carte.
Il faut maintenant ajouter le Framework MapKit aux dépendances de l'application. Dans l'arborescence projet, cliquez sur le nom du projet. Ensuite sélectionnez "Build Phases". Dans la section "Link Binary With Libraries", cliquez sur "+" et ajoutez "MapKit".
Tumblr media
Vous pouvez maintenant lancer l'application.
Tumblr media
Centrer et afficher la position de l'utilisateur
Ouvrez le fichier ViewController.h et ajouter l'import de MapKit
#import <MapKit/MapKit.h>
Il faut maintenant ajouter la mapView que nous avons positionné dans notre interface avec notre controller.
Sélectionner de nouveau MainStoryboard.storyboard. Vérifiez que l' "Assistant Editor" est affiché.
Tumblr media
Dans l'assistant vous devez être en mode automatique et affiche ViewController.h
Tumblr media
Il faut maintenant glisser la map depuis le storyBoard vers la fenêtre du ViewController.h en maintenant la touche "control" enfoncée . Vous devez la déposer entre @interface et @end.
Une popUp apparait. Indiquez Outlet comme type de connexion et nommer la variable _mapView. Cliquez sur connect.
Tumblr media
Aller maintenant dans ViewController.m . En dessous de @implementation ViewController rajouter 
@synthesize _mapView;
Dans la méthode viewDidLoad ajoutez les lignes suivantes :
[_mapView setUserTrackingMode:true]; _mapView.zoomEnabled = true;
setUserTracking permet de forcer la carte à suivre la position de l'utilisateur et à centrer dessus. zoomEnabled, active le zoom sur la carte.
Lancer l'application. Pour simuler une position, aller dans le menu du simulateur iOs : Débogage->Lieu->Lieu personnalisé. Ajouter les coordonnées suivantes - Latitude 48,857431, longitude 2,351801 . Vous serez alors dans le centre de paris 
Tumblr media
Parcourir le fichier CSV
Télécharger le fichier suivant ratp.csv . Il contient les coordonnées de toutes les stations RATP. Je l'ai trouver sur le site http://www.data.gouv.fr/ qui contient plein de données libre d'utilisation.
Ajoutez le fichier à votre application. Pour cela faites, bouton droit sur le package "Supporting Files"->Add File to RatpMap. N'oublier pas de sélectionner "Copy items into destination group folder ..."
Il faut maintenant parser le fichier. Dans le fichier ViewController.m , nous allons modifier la méthode ViewDidLoad . Elle doit maintenant ressembler à ceci.
- (void)viewDidLoad { [super viewDidLoad]; [_mapView setUserTrackingMode:true]; _mapView.zoomEnabled = true; NSString *csvFilePath = [[NSBundle mainBundle] pathForResource:@"ratp" ofType:@"csv"]; NSString *dataStr = [NSString stringWithContentsOfFile:csvFilePath encoding:NSUTF8StringEncoding error:nil]; NSArray* allLinedStrings = [dataStr componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]]; for (NSString *line in allLinedStrings) { NSLog(@"%@", line); NSArray* infos = [line componentsSeparatedByString: @"#"]; } }
Exécuter votre application. Dans la fenêtre de log vous devez voir quelque chose comme ça.
Tumblr media
Afficher les stations RATP
Maintenant nous possédons les données des stations RATP, il nous faut maintenant les afficher sur la carte.
Pour cela il faut utiliser des objets appelés "Annotation". Dans un premier temps il faut créer une classe qui implémente MKAnnotation.
Sélectionnez le package RatpMap et faites clic droit->New File ->iOS\Cocoa Touch\Objective-C class. Appelez la classe "Location".
Editer Location.h pour qu'il contienne le code suivant :
#import <Foundation/Foundation.h> #import <MapKit/MapKit.h> @interface Location : NSObject { NSString *_name; NSString *_address; CLLocationCoordinate2D _coordinate; } @property (copy) NSString *name; @property (copy) NSString *address; @property (nonatomic, readonly) CLLocationCoordinate2D coordinate; - (id)initWithName:(NSString*)name address:(NSString*)address coordinate:(CLLocationCoordinate2D)coordinate; @end
Faites de même avec Location.m
#import "Location.h" @implementation Location @synthesize name = _name; @synthesize address = _address; @synthesize coordinate = _coordinate; - (id)initWithName:(NSString*)name address:(NSString*)address coordinate:(CLLocationCoordinate2D)coordinate { if ((self = [super init])) { _name = [name copy]; _address = [address copy]; _coordinate = coordinate; } return self; } - (NSString *)title { if ([_name isKindOfClass:[NSNull class]]) return @"Unknown charge"; else return _name; } - (NSString *)subtitle { return _address; } @end
Maintenant retournez dans le fichier ViewController.m et ajouter l'import de "Location.h"
#import "Location.h"
Modifiez la méthode ViewDidLoad pour qu'elle ressemble à ça.
- (void)viewDidLoad { [super viewDidLoad]; [_mapView setUserTrackingMode:true]; _mapView.zoomEnabled = true; NSString *csvFilePath = [[NSBundle mainBundle] pathForResource:@"ratp" ofType:@"csv"]; NSString *dataStr = [NSString stringWithContentsOfFile:csvFilePath encoding:NSUTF8StringEncoding error:nil]; NSArray* allLinedStrings = [dataStr componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]]; for (NSString *line in allLinedStrings) { NSLog(@"%@", line); NSArray* infos = [line componentsSeparatedByString: @"#"]; if ([infos count] > 1) { NSString * latitude = [infos objectAtIndex:2]; NSString * longitude = [infos objectAtIndex:1]; NSString * crimeDescription =[infos objectAtIndex:3]; NSString * address = [infos objectAtIndex:4]; CLLocationCoordinate2D coordinate; coordinate.latitude = latitude.doubleValue; coordinate.longitude = longitude.doubleValue; Location *annotation = [[Location alloc] initWithName:crimeDescription address:address coordinate:coordinate] ; [_mapView addAnnotation:annotation]; } } }
Lancer l'application, les stations RATP sont maintenant présentes à l'écran.
Tumblr media
Vous pouvez télécharger les sources de ce tutorial ici : RaptMap.zip
0 notes
smartfrog · 14 years ago
Text
Flex 4.5 Hero, vos applications arrivent sur mobile
Adobe a pris le parti de faire de Flex une plateforme universelle de développement. Déjà disponible sur Windows/Mac/Linux, Adobe attaque maintenant les mobiles et les tablettes en permettant, à partir d'un même code source, le déploiement sur Android, Blackberry tablet Os et bientôt iOs (iPhone et iPad). Avec les nouvelles versions de son sdk Flex (4.5 Hero ) et de son environnement de développement, Flash Builder 4.5 Burrito, Adobe fourni tous les éléments nécessaires aux développeurs pour réaliser des applications mobiles multi-plateformes. Nous allons nous intéresser à toutes ces nouveautés en réalisant une petite application mobile de planning poker.
Préambule
Commençons par récupérer tout ce dont nous avons besoin :
Flash Builder Burrito
Sdk Flex 4.5
Sdk Air BlackBerry
Packager iPhone
Maintenant que vous avez installé tout cela, nous allons pouvoir commencer.
Création d'un projet Flex Mobile
La première chose à faire est de créer un projet Flex Mobile.
Tumblr media
Choix du Sdk Flex 4.5 Hero
Tumblr media
Choix des plateformes cibles, ici Android et BlackBerry Tablet Os
Tumblr media
iOs n'est, pour le moment, pas disponible dans les plateformes cibles. Il faudra procéder différemment pour packager notre application sur la plateforme d'apple.
Une nouvelle façon de penser ses applications
Du fait de la taille des écrans des périphériques mobiles, les patterns ergonomiques ne sont plus les mêmes. Pas question de faire appel à une popUp pour afficher un formulaire contenant une grande quantité de champs. Adobe s'est basé sur les patterns utilisés par Apple et Google. Une application va être composée d'une succession de vues. L'utilisateur peut en permanence revenir à l'étape précédente. L'organisation d'une application mobile Flex est la suivante :
Tumblr media
ViewNavigator : Permet de gérer l'affichage des vues.
ActionBar :  Affiche des informations sur la vue courante et permet de réaliser des actions (entre autre de navigation)
View: L'écran que nous souhaitons afficher.
Application Planning Poker
Pour illustrer ces nouveaux concepts, je vous propose de nous baser sur l'exemple d'une petite application de planning poker, dont vous pouvez télécharger les sources ici. Le fichier PlanningPoker.mxml contient  une MobileApplication dont la première vue est PlanningPokerAccueil.
<?xml version="1.0" encoding="utf-8"?> <s:MobileApplication xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" firstView="views.PlanningPokerAccueil">   <fx:Declarations> <!-- Placer ici les éléments non visuels (services et objets de valeur, par exemple). --> </fx:Declarations>   </s:MobileApplication>
C'est donc PlanningPokerAccueil qui est affiché au lancement de l'application.
Tumblr media
Dans PlanningPokerAccueil.mxml, lorsque l'on choisit une carte nous avons :
protected function openCard():void { navigator.pushView(CardView, list.selectedItem); }
Nous faisons appel au viewNavigator et ajoutons ici "CardView" à la pile des vue, en passant les données de l'objet à afficher.
Tumblr media
Le fichier CardView.mxml se présente ainsi :
<?xml version="1.0" encoding="utf-8"?> <s:View xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" title="Estimation" xmlns:presentation="presentation.*" >   <fx:Declarations> <!-- Placer ici les éléments non visuels (services et objets de valeur, par exemple). --> </fx:Declarations>   <s:layout> <s:VerticalLayout horizontalAlign="center" verticalAlign="middle" paddingTop="10" paddingBottom="10"/> </s:layout>   <presentation:Card id="card" value="{data}" height="100%" currentSide="back" click="card.turn()"/>   <s:Label text="(Tap card to turn it)" />   <s:navigationContent> <s:Button label="Back" click="navigator.popToFirstView()"/> </s:navigationContent> </s:View>
La balise nous permet d'ajouter un objet de navigation. Ici un bouton qui nous permettra de revenir à l'écran d'accueil.
navigator.popToFirstView()
Packager pour Android / BlackBerry
Dans le menu projet sélectionnez : Exporter vers une version validée ...
Tumblr media
Sélectionnez les plateformes  cibles :
Tumblr media
Ajoutez (ou créez) votre certificat :
Tumblr media
Vos applications packagés sont maintenant disponibles dans votre répertoire projet.
Tumblr media
Packager pour iOs
C'est un peu plus compliqué. Suite au refus d'Apple d'accepter des applications n'étant pas écrite directement en xCode, Adobe avait stoppé ses efforts sur le packager iPhone. Depuis, Apple a fait marche arrière et Adobe a annoncé qu'il reprenait ses travaux. Une version intégrée au flash builder devrait être disponible courant 2011.
Il est cependant déjà possible de packager pour iOs en utilisant le packager iPhone.  Les  performances n'étant pas encore au rendez-vous pour un déploiement sur iPad, et la solution temporaire, nous ne nous y attarderons pas plus que cela.
Pour plus d'info vous pouvez consulter l'article sur flex-tutorial.com
Conclusion
Adobe a fait le pari de faire de Flex la future plateforme universelle de développement d'application. C'est ambitieux mais il est déjà possible d'apprécier le résultat en réalisant des applications exécutables sur différentes plateformes mobiles et ne nécessitant pas l'apprentissage d'un nouveau langage ou sdk. Il manque encore pas mal de composants mobiles, la gestion d'iOs n'est pas encore au point, mais la direction prise est la bonne. On attend avec impatience la version finale de ce sdk orienté mobile.
0 notes
smartfrog · 15 years ago
Text
Parsley : Un framework IOC pour vos applications Flex
Parsley est un framework pour application Flex et Flash, construit autour d'un conteneur IOC et d'un framework de messaging. Il peut être utilisé pour créer des architectures fortement découplées. Son utilisation est d'ailleurs recommandée par les Guidelines de Cairngorm 3.
Nous allons voir ici une présentation des différents concepts présents dans Parsley. Pour cela nous allons réaliser un exemple simple : un écran qui permet de récupérer et d'afficher un liste d'utilisateurs. Les sources de l'exemple sont disponibles ici.
Patterns utilisés dans l'exemple
Voici une description des patterns que nous allons utiliser. Ils sont issus de Cairngorm 3. Pour plus de détails, vous pouvez consulter l'article précédent : Cairngorm 3, architecture et bonnes pratiques pour vos applications Flex
View : Représentation de la partie graphique d'une page ou d'un composant. Ne contient que du Mxml (Pas de code de comportement dans une balise script) et un PresentationModel.
PresentationModel (Pm) : Se charge de fournir et de mettre en forme les données à afficher par le composant. Il contient également le comportement de la vue. Exemple, lorsque l'utilisateur clique sur le bouton "Liste des utilisateurs", c'est le PresentationModel qui lance l'évènement déclenchant l'appel serveur.
Command : A chaque appel service est associé une commande. Elle comporte trois méthodes, "execute", "result", "fail". "Execute" permet de réaliser l'appel serveur en passant les bons paramètres. "Result" va traiter le résultat retourner par le serveur. "Fault" va traiter les exceptions lancées par le serveur.
ServiceEvent : A chaque commande est associé un évènement. Lorsque l'évènement est lancé, la méthode "execute" de la commande associée est appelée.
RemoteObject : Il représente une classe de service localiser sur le serveur. Supposons que la destination (ici 'UserService') fournit la méthode 'findUsers'. La methode "execute" de notre command fera appel au remoteObject de la manière suivante : remoteObject. findUsers(parametres).
Le contexte : Parsley fournit un 'contexte' qui contiendra tous les objets (PresentationModel (PM), Command, RemoteObject) dont l'application à besoin.
Schèma récapitulatif de l'exemple présenté
Tumblr media
Configuration du context
Comme tout framework IOC, Parsley fournit un conteneur pour les objets utilisés dans l'application. Pour cela on créer un fichier mxml (ExempleContext.mxml), dans lequel nous déclarons tous nos objets.
<?xml version="1.0" encoding="utf-8"?> <fx:Object xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:presentation="com.bamboublog.presentation.*" xmlns:application="com.bamboublog.application.*">   <fx:Declarations> <presentation:UserListScreenPm /> <application:FindUsersCommand /> <s:RemoteObject id="userService" /> </fx:Declarations>   </fx:Object>
Maintenant il faut créer le contexte à l'initialisation de l'application. Ajouter dans le fichier mxml de votre application le 'ContextBuilder' de parsley avec la balise suivante :
<spicefactory:ContextBuilder config="{ExempleContext}" />
Cela permet de créer le contexte à partir de la description que nous avons fait précédemment.
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" xmlns:context="org.spicefactory.parsley.dsl.context.*" xmlns:spicefactory="http://www.spicefactory.org/parsley" xmlns:presentation="com.bamboublog.presentation.*"> <fx:Script> <![CDATA[ ]]> </fx:Script>   <fx:Declarations> <spicefactory:ContextBuilder config="{ExempleContext}" /> </fx:Declarations>   <presentation:UserListScreen width="100%" height="100%"/> </s:Application>
Injection de dépendance
Pour faire de l’injection de dépendance il faut utiliser le métatag [Inject] au dessus d’une propriété.
Par défaut Parsley se sert du type de l’objet pour faire l’injection. Si plusieurs objet d’un même type sont disponibles, il est possible de spécifier l’id de celui à injecter :
[Inject(id="userService")] public var service:RemoteObject;
Dans le cas d’une « vue », qui n’est pas contenue dans le contexte, il faut utiliser la balise « Configure » fournit par parsley.
<?xml version="1.0" encoding="utf-8"?> <s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:parsley="http://www.spicefactory.org/parsley"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Declarations> <parsley:Configure /> </fx:Declarations> <fx:Script > <![CDATA[ [Inject] [Bindable] public var model:UserListScreenPm; ]]> </fx:Script> <s:Button label="Liste des users" click="{model.findUserList()}"/> <mx:DataGrid width="100%" height="100%" dataProvider="{model.userList}"/> </s:Group>
Messaging
La classe qui va dispatcher un évènement qui doit être géré par Parsley, doit l'indiquer par le métatag [ManagedEvents].
package com.bamboublog.presentation { import com.bamboublog.application.FindUsersEvent;   import mx.collections.ArrayCollection;   [Bindable] [ManagedEvents("FindUsersEvent")] public class UserListScreenPm {   public var userList:ArrayCollection     public function findUserList():void { dispatchEvent(new FindUsersEvent()); } } }
La classe commande doit être configurée comme suit pour être liée à l'évènement 'FindUsersEvent'
Le métatag [Command(selector="FindUsersEvent")] : Indique la méthode à exécuter lorsque l'évènement 'FindUserEvent' est intercepté.
Le métatag [CommandResult(selector="FindUsersEvent")] : Indique la méthode qui traitera le résultat retourné par le seveur.
Le métatag [CommandError(selector="FindUsersEvent")] : Indique la méthode qui traitera les erreurs retournées par le serveur.
package com.bamboublog.application { import com.bamboublog.presentation.UserListScreenPm;   import mx.collections.ArrayCollection; import mx.controls.Alert; import mx.rpc.AsyncToken; import mx.rpc.Fault; import mx.rpc.remoting.RemoteObject;   public class FindUsersCommand {   [Inject(id="userService")] public var service:RemoteObject;   [Inject] public var userListScreenPm:UserListScreenPm;   public function FindUsersCommand() { }   [Command(selector="FindUsersEvent")] public function execute(event:FindUsersEvent):AsyncToken { return service.findUsers() as AsyncToken; }   [CommandResult(selector="FindUsersEvent")] public function result(result:ArrayCollection):void { userListScreenPm.userList = result; }   [CommandError(selector="FindUsersEvent")] public function fault(fault:Fault):void { Alert.show("Error : "+fault.message) } } }
Pour aller plus loin...
La documentation Parsley
0 notes
smartfrog · 15 years ago
Text
Flex dans les nuages avec Google App Engine et BlazeDs
Depuis quelques temps les solutions permettant d'héberger des applications dans le cloud sont de plus en plus populaires. Elles permettent à des sociétés, ou des particuliers, de déployer facilement et à moindre coût, une application au sein d'une infrastructure robuste.
Nous allons nous intéresser à Google App Engine qui permet de déployer des applications écrites en Java ou Python. Flex est devenu l'un des standards du développement d'application à interface riche. De plus en plus d'entreprises et de grands comptes investissent dans cette technologie afin de fournir des applications profitant d'un grand confort d'utilisation. Nous allons donc nous intéresser ici au déploiement d'une application Java/Flex dans le Cloud de Google. Nous utiliserons pour cela BlazeDs, qui est le framework le plus répandu pour assurer la communication entre une application Flex et un backend java. Vous pouvez télécharger le code associé à ce tutorial ici.
Installation du plugin Google pour Eclipse
Pour commencer, il faut installer le plugin Google pour Eclipse. Pour Eclipse 3.5 (Galileo) :
Dans Help menu > Install New Software....
Ajouter : http://dl.google.com/eclipse/plugin/3.5
Sélectionner et installer le plugin Google ainsi que le SDK Google engine
Pour Eclipse 3.4 (Ganymede) :
Dans Help menu > Software Updates...
Ajouter le site http://dl.google.com/eclipse/plugin/3.4
Sélectionner et installer le plugin Google ainsi que le SDK Google engine
Création d'un projet Google App Engine
De nouvelles icônes sont maintenant disponibles dans le menu d'Eclipse : Cliquer sur la première icône (le 'g' sur fond bleu) qui permet de créer un nouveau projet Google App Engine. Indiquez nom et package de votre projet et décochez l'utilisation de GWT.
Tumblr media
Le projet est créé avec la structure suivante :
Tumblr media
Ajout de BlazeDs au projet Google App Engine
Nous allons ajouter les bibliothèques et les fichiers de configuration relatif à BlazeDs, comme dans tout projet java web classique. Vous pouvez télécharger BlazeDs ici. Attention : il y a un problème avec la bibliothèque flex-messaging-core et la classe flex.messaging.io.amf.AbstractAmfInput.java à laquelle il faut appliquer un petit fix pour la faire fonctionner dans App Engine. Vous pouvez télécharger la version patchée de la lib ici. Pour plus de détail sur la modification apporté au flex-messaginf-core, allez voir ici : http://martinzoldano.blogspot.com/2009/04/appengine-adobe-blazeds-fix.html Voici ce que vous devez avoir, après avoir ajouté les bibliothèques BlazeDs (et remplacé flex-messaging-core par sa version patché) dans le répertoire war/WEB-INF/lib.
Tumblr media
Ensuite, ajoutez les fichiers de configuration BlazeDs dans war/WEB-INF/flex
Tumblr media
Configuration du projet
Modification du fichier war/WEB-INF/web.xml
If faut déclarer la servlet qui va permettre à l'application Flex d'attaquer les services java.
!-- Begin BlazeDS Stuff -->
<!-- Http Flex Session attribute and binding listener support --> <listener> <listener-class>flex.messaging.HttpFlexSession</listener-class> </listener>   <!-- MessageBroker Servlet --> <servlet> <servlet-name>MessageBrokerServlet</servlet-name> <display-name>MessageBrokerServlet</display-name> <servlet-class>flex.messaging.MessageBrokerServlet</servlet-class> <init-param> <param-name>services.configuration.file</param-name> <param-value>/WEB-INF/flex/services-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
Modification du fichier war/WEB-INF/app-engine-web.xml
Il faut indiquer que notre projet Google App engine autorise les sessions en ajoutant :
<sessions-enabled>true</sessions-enabled>
Modification du fichier war/WEB-INF/flex/services-config.xml
Il faut s'assurer que l'option 'manageable' est désactivé.
<system> <manageable>false</manageable> <redeploy> <enabled>false</enabled> </redeploy> </system>
Ensuite dans la définition des channels vous pouvez supprimer la référence au contex-root dans l'url du end-point. Sur le cloud de Google le context-root ne sert à rien.
<channels>   <channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel"> <endpoint url="http://{server.name}:{server.port}/messagebroker/amf" class="flex.messaging.endpoints.AMFEndpoint"/> </channel-definition>   <channel-definition id="my-secure-amf" class="mx.messaging.channels.SecureAMFChannel"> <endpoint url="https://{server.name}:{server.port}/messagebroker/amfsecure" class="flex.messaging.endpoints.SecureAMFEndpoint"/> <properties> <add-no-cache-headers>false</add-no-cache-headers> </properties> </channel-definition>   <channel-definition id="my-polling-amf" class="mx.messaging.channels.AMFChannel"> <endpoint url="http://{server.name}:{server.port}/messagebroker/amfpolling" class="flex.messaging.endpoints.AMFEndpoint"/> <properties> <polling-enabled>true</polling-enabled> <polling-interval-seconds>4</polling-interval-seconds> </properties> </channel-definition>   </channels>
Modification du fichier war/WEB-INF/flex/remoting-config.xml
Ici rien d'extraordinaire, nous allons juste déclarer le service que nous allons créer et utiliser dans ce tuto.
<destination id="applicationService">
<properties> <source>com.bamboublog.blazeds_gae.ApplicationService</source> </properties> 
</destination>
 Application de test
Coté serveur / Hello service
On créer la classe ApplicationService qui contient le service hello.
package com.bamboublog.blazeds_gae;   public class ApplicationService {   public String hello() { return "Hello Flex"; }   }
Nous l'avons déjà déclaré dans le remoting-config.xml.
Coté client
Créer un projet Flex et ajouter le code suivant, permettant d'appeler le service "hello".
<?xml version="1.0" encoding="utf-8"?>   <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">   <fx:Script> <![CDATA[ import mx.controls.Alert; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent;   protected function button1_clickHandler(event:MouseEvent):void { remote.hello(); }   protected function remoteobject1_resultHandler(event:ResultEvent):void { helloLabel.text = event.result as String; }   protected function remote_faultHandler(event:FaultEvent):void { Alert.show(event.fault.message); }   ]]> </fx:Script>   <fx:Declarations> <s:RemoteObject id="remote" destination="applicationService" showBusyCursor="true" result="remoteobject1_resultHandler(event)" fault="remote_faultHandler(event)"/> </fx:Declarations>   <s:layout> <s:VerticalLayout /> </s:layout>   <s:Button click="button1_clickHandler(event)" label="HELLO"/> <s:Label id="helloLabel" text="Yo" />   </s:Application>
Dans la configuration du projet Flex, modifiez les arguments de compilation pour ajouter le chemin du fichier services-config.xml: -services /Users/fred/Documents/workspace/blaze_gae/war/WEB-INF/flex/services-config.xml
Tumblr media
Ensuite il faut indiquer à Flash Builder de compiler le projet flex dans le répertoire war du projet Google App Engine. On indique cela dans le champs 'Dossier de sortie'
Tumblr media
Maintenant dans le répertoire war nous avons :
Tumblr media
Déploiement du projet
Il y a deux manières de déployer le projet.
Déploiement en local
Pour cela sélectionnez, 'Executer en tant que'-> 'Web Application'.
Tumblr media
L'application est maintenant accessible à l'adresse suivante : http://localhost:8888/blazeds_gae_flex.html
Déploiement dans les nuages sur Google App Engine
Pour cela vous devez avoir un compte google et avoir créé une application sur le Google App Engine. Pour cela, aller ici : https://appengine.google.com/ Dans Eclipse, cliquez sur l'icone représentant un réacteur :
Tumblr media
Une erreur nous indique que notre projet n'est pas associé à un application ID. Cela correspond au nom du application que vous avez créer sur votre compte Google App Engine. Cliquez alors sur "App Engine project settings ... " et indiquez l'ID de l'application que vous avez créé avec votre compte Google App Engine.
Tumblr media
Vous pouvez maintenant lancer le déploiement en entrant votre email et mot de passe. Voila votre application est dans les nuages.
Tumblr media
Conclusion
Bien que BlazeDs soit la solution la plus répandu pour la communication Flex/Java, la version 'officiel' ne fonctionne pas dans le Google App Engine. If faut en modifier les sources, ce qui pour une utilisation en environnement professionnelle, peut être décourageant. J'espère qu'Adobe prendra la mesure du problème et proposera rapidement une version réglant ce problème. En attendant, vous pouvez toujours vous tourner vers GraniteDs qui lui fonctionne sans la nécessité dun patch.
0 notes
smartfrog · 15 years ago
Text
Cairngorm 3, architecture et bonnes pratiques pour vos applications Flex
Cela fait quelques semaines qu'Adobe a mis à disposition Cairngorm 3. Si vous vous dites "chouette voici la nouvelle version de mon framework MVC préféré", et bien vous vous trompez un peu. Cependant vous n'allez pas être déçu, car Adobe, avec Cairngorm 3, ne se place plus au niveau des framework MVC mais passe un cran au dessus. 
En effet Cairngorm 3 se veut comme un regroupement de bonnes pratiques, de bibliothèques et d'outils adaptés au développement d'applications Flex. Cairngorm 3 ne fournit plus de framework MVC mais recommande l'utilisation d'un framework IOC. A noter que certaines des bibliothèques fournies par Cairngorm ne fonctionnent qu'avec Parsley ou Swiz.
Architecture de l'application Flex
Cairngorm propose une structure en couches applicatives telle qu’elles se sont généralisées dans les applications côté serveur.
Tumblr media
Pour plus de détails, jetez un oeil à cette application exemple.
Couche Presentation
Présente l'information à l'utilisateur.
View : Représentation de la partie graphique d'une page ou d'un composant. Ne contient que du Mxml (Pas de code de comportement dans une balise script) et un PresentationModel.
PresentationModel (Pm) : Se charge de fournir et de mettre en forme les données à afficher par le composant. Il contient également le comportement de la vue. Le Pm peut manipuler des objets du domaine.
Couche Application
Cette couche va contenir tout ce qui permet de gérer les interractions et les actions dans l'application.
Command : Permet d'encapsuler les actions réalisées par l'application. Notamment utilisée pour gérer les appels serveur.
Interceptor : Permet d'intercepter une action afin d'effectuer un traitement avant son exécution. Par exemple, intercepter une action de suppression afin de demander à l'utilisateur de confirmer.
Controller : Est en charge de coordonner les interactions au sein et entre les différentes couches.
Couche Domain
Cette couche contient une modélisation des concepts et objets métier. Ils ont les responsabilités suivantes :
Validation
Filtrage (Peut également être réalisé par le PresentationModel)
Trie (Peut également être réalisé par le PresentationModel)
Formatage (Peut également être réalisé par le PresentationModel)
Couche Infrastructure
Contient le code et les bibliothèques qui n'ont pas de rapport, ni avec le métier, ni avec l'application.
UI Framework
Communication avec des systèmes externes
Export des données
...
Les bibliothèques
Nous ne rentrerons pas dans le détails de chacune de ces bibliothèques, chacune d'elle méritant un article à part entière. Vous en trouverez ici un premier aperçu.
Design by Contract Library : Met en oeuvre le principe de programmation par contrat.
Observer Library : Permet d'observer et de réagir aux changements de certains objets depuis le mxml.
Popup Library : Gestion des popUps.
Task Library : Permet l'execution de tâches en parallèles ou en séquentielles.
Validation Library : Aide à la validation des données.
Persistence Library : Framework de persistance pour gérer une base SqLite dans une application Air.
Navigation Library : Fournis une gestion de la navigation dans l'application. Pour avoir eu l'occasion de l'essayer, cette bibliothèque est vraiment bien faites et très pratique.
Module Library : Gestion des modules.
Integration Library : Aide à la gestion des interractions avec les systèmes extérieurs (envoie et réception des données, gestion des erreurs, résolutions de confits ...).
Conclusion
Je travaille actuellement sur un projet Flex 4, avec Parsley 2.2, en suivant les recommendations Cairngorm 3. Pour le moment, mis à part quelques détails (sur lesquels je reviendrais prochainement), toute l'équipe est très satisfaite. Nous retrouvons certains patterns, comme les PresentationModel, que nous avions déjà mis en place au dessus de Cairngorm 2. De plus le découpage en couche correspond à celui que nous avions côté serveur (cf. Domain Driven Design). L'utilisation d'un framework IOC est un plus indéniable (couplage faible entre les classes, gestion de différentes configurations, ...). Parsley est très bien documenté et donc facile à prendre en main. Les bibliothèques Cairngorm sont vraiment bien pensées et nous facilite la vie. Elles fournissent des "solutions standards" à des problèmes (gestion des popup, de la navigation, de tâches ...) que nous avons déjà tous rencontrés. Cet article sera suivi de plusieurs autres sur Parsley et sur les différentes bibliothèques proposées par Cairngorm 3.
0 notes
smartfrog · 15 years ago
Text
Et XP dans tout ça ?
Ces dernières années, Scrum, et plus récemment Kanban, ont monopolisé l'attention du monde agile. Scrum a de nombreuses qualités, il fournit une organisation et un ensemble de pratiques de gestion de projet, simples et efficaces. Cependant il n'adresse qu'une partie des problématiques, en laissant de côté celles liées à la production. 
En partie à cause de la médiatisation et du succès de Scrum, une analogie est souvent faite entre ce dernier et l'agilité au sens large. Cela a tendance à réduire l'agilité aux seules questions de gestion de projet, alors qu'elle englobe bien d'autres choses comme, par exemple, les pratiques d'ingénierie. Un projet, Scrum ou non, dans lequel il n'y a pas de bonnes pratiques d'ingénierie, aura toutes les chances d'échouer. Xp (eXtreme Programming), très populaire il y a quelques années, disparait du devant de la scène, alors que certaines de ses pratiques et de ses valeurs devraient être connues et partagées par toute équipe de développement. Scrum met en place le cadre permettant aux différents profils (fonctionnel, développeur, manager, designer, ...) de travailler ensemble. XP, lui intervient dans la mise en place des pratiques d'ingénierie (Intégration continue, Refactoring, Tdd ...) et dans la définition de valeurs communes. (Pour une description un peu plus détaillée d'Xp, je vous invite à consulter ce précédent billet). De plus, certains principes d'Xp peuvent très bien s'appliquer en déhors de l'équipe de développement, dans des phases en amont ou parallèle à réalisation.
Yagni (You aint gonna need it) :  Principe selon lequel, il ne faut faire que ce dont on est sûr d'avoir besoin. Cela peut servir durant les phases de recueil et de définition du besoin. Si une fonctionnalité n'est pas nécessaire dans l'immédiat, laissez-la de côté. De même essayer de répondre à des besoins qui n'ont pas été formulés par l'utilisateur est du simple gâchis.
Keep It Simple : Ce principe suggère que la meilleure façon de rendre une application flexible et maintenable est de la simplifier au maximum. Ce qui applicable pour le code peut également l'être pour les interfaces. A ne pas oublier lors du prototyping des écrans et de la cinématique de l'application. Plus l'application sera simple à utiliser, mieux elle sera acceptée par les utilisateurs.
Pour finir les valeurs de Courage, Communication, Feedback, Simplicité et Respect sont des valeurs saines, facilement partageables par toute l'équipe, du développeur au designer en passant par les managers. En combinant Scrum et Xp, nous adressons une grande partie des problématiques liées aux projets informatiques. Là où SCRUM fournit un "corps", Xp lui, fournir un "coeur".
0 notes