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.
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.
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.
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.
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.













