Faire un navigateur web [Tutoriel iPhone n°7] [XCode 4]
Nouveau (avril 2011) : Ce tutoriel a été mis à jour et été testé pour XCode 4.
Le SDK de l’iPhone propose de nombreux composants permettants de gagner un temps précieux lors du développement. UIVebView est de ceux-ci puisqu’il permet d’intégrer une vue WebKit dans votre application. A titre d’exemple, ce tutoriel vous propose de construire un premier navigateur web, et vous verrez que le point plus délicat à bien comprendre n’est pas forcément là où on l’attend !
Ce tutoriel sera en effet l’occasion d’en savoir plus sur le comportement de UITextField, quand il s’agira de créer la barre d’adresse et d’interagir avec le clavier virtuel de l’iPhone.
Créer le projet et y ajouter une UIWebView
Démarrez XCode et créez un nouveau projet de type « View based application ». Nous l’appellerons « MyWebBrowser ».
Dans MyWebBrowserViewController.h, nous allons ajouter un nouvel Outlet de type UIWebView, ainsi que la propriété associée.
#import @interface MyWebBrowserViewController : UIViewController { IBOutlet UIWebView *webView; } @property (nonatomic, retain) UIWebView *webView; @end
L’objet UIWebView, est, comme son nom l’indique bien, une vue dans laquelle va pouvoir être affiché le contenu d’une page web. Ce contenu va interagir avec l’utilisateur de la même manière qu’une page web standard : zoom, navigation, suivre les liens, remplir et envoyer les formulaires, etc. Cette instance « webView » sera donc l’objet central de notre navigateur web.
N’oubliez pas de synthétiser la propriété dans MyWebBrowserViewController.m et de faire un release dans la méthode dealloc :
@implementation MyWebBrowserViewController @synthesize webView; - (void)dealloc { [webView release]; [super dealloc]; }
Sauvegardez les fichiers .h et .m, puis ouvrez le fichier « MyWebBrowserViewController.xib« . A l’aide de la bibliothèque d’objets de la colonne de droite, faîtes glisser un objet UIWebView sur la vue.
Vous allez voir que XCode vous propose que la UIWebView prenne toute la place disponible : c’est parfait ! Inutile de le contrarier outre mesure pour le moment
. Associer l’outlet « webView » de l’objet File’s Owner (clic droit sur File’sOwner et tracez un trait depuis l’élément webView de la fenêtre noire vers la vue nouvellement créée).
Sauvegardez ; il ne reste plus qu’à compiler et à lancer l’application.
Premier problème : il n’y a rien dans le navigateur…
Oui, mais en même temps, nous n’avons pas précisé d’adresse en particulier ! C’est l’occasion de parler rapidement du fonctionnement de UIWebView. Les données dans UIWebView sont chargées à partir d’une requête Internet : une NSURLRequest. Cette requête est un objet créé à partir d’une adresse URL : un objet NSURL. On peut expliquer cela comme on veut, le code est encore ce qu’il y a de plus clair à comprendre. Repérez la méthode viewDidLoad qui doit être en commentaire dans le fichier MyWebBrowserViewController.m, et transformez la ainsi :
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. - (void)viewDidLoad { [super viewDidLoad]; // Créer une URL NSURL *urlAddress = [NSURL URLWithString: @"http://www.google.com"]; // Faire une requête sur cette URL NSURLRequest *requestObject = [NSURLRequest requestWithURL:urlAddress]; // Charger la requête dans la UIWebView [webView loadRequest:requestObject]; }
Sauvegardez et compilez. C’est mieux ! Vous voici sur le moteur de recherche. Touchez le champ Google et saisissez l’intitulé de votre recherche, touchez les liens, tout fonctionne !
Second problème : l’affichage des sites n’est pas adapté à la taille du téléphone
Google affiche correctement le moteur de recherche ainsi que les résultats, mais dès qu’on essaie d’aller un peu plus loin, ça se corse : les sites n’apparaissent pas adaptés à la taille du téléphone, à l’inverse de Safari mobile où tout est zoomé pile poil comme il faut.
Il s’agit d’une simple propriété à affecter à notre UIWebView. Ouvrez à nouveau « MyWebBrowserViewController.xib », sélectionnez la UIWebView et dans l’onglet « Attributes Inspector » de la colonne de droite, cochez la case « Scale Page To Fit ».
Sauvegardez, et recompilez. Cette fois, c’est bon.
Un navigateur a besoin d’une barre d’adresse !
Et oui ! S’il est vrai que dans cet état notre navigateur fonctionne, ce serait quand même plus pratique avec une barre d’adresse. Réouvrez le fichier MyWebBrowserViewController.h et ajoutez un nouvel outlet de type UITextField que nous appellerons adressField. Ajoutez la propriété correspondante, synthétisez la dans MyWebBrowserViewController.m et faites un release dans la méthode dealloc. C’est le même fonctionnement que précédemment !
Retournons modifier MyWebBrowserViewController.xib : réduisez la taille de la UIWebView, et ajoutez un objet UITextField qui prendra toute la largeur.
Connectez ce UITextField à l’outlet que nous venons de créer (exactement de la même façon que la UIWebView) et sauvegardez.
Comment configurer le clavier virtuel ?
Si vous compilez et lancez votre application à ce moment du projet, le toucher du champ texte va faire apparaître le clavier virtuel. Mais comment faire pour configurer ce clavier ? En effet, dans Safari Mobile, quand il s’agit de saisir l’URL, les caractères « . », « / » ou encore l’extension sont en accès rapide. De plus, le bouton en bas à droite propose généralement un bouton « Aller ».
S’il est une chose qu’il est important de bien comprendre à ce stade, c’est que vous n’avez pas la main directement pour configurer le clavier virtuel : vous ne pouvez pas l’invoquer directement ou de lui envoyer des messages. C’est au moment de l’exécution que iOS « attache » le clavier virtuel au composant qui l’a appelé. C’est donc ce composant qui va savoir quel type de clavier virtuel il souhaite se voir proposé. Cette configuration est appelée : Text Input Traits.
Dans l’interface de modification de MyWebBrowserViewController.xib, sélectionnez le UITextField et affichez l’inspecteur dans la colonne de droite. Dans l’ « Attributes Inspector », vous remarquerez une section relative à ces « Text Input Traits ».
De nombreuses options sont configurables :
- le type de clavier (par défaut, URL, numéro de téléphone, email…)
- si c’est un clavier de mot de passe ou non (l’option Secure)
- la mise en place de l’auto-correction (vous pouvez la désactiver, mais n’oubliez pas que l’utilisateur choisit, dans les préférences, son mode de fonctionnement : il n’est pas forcément du meilleur goût que de passer outre ce choix)
- le bouton de validation que vous souhaitez voir apparaître
- des options d’apparence
- etc.
Choisissez un clavier URL et le bouton « Go » pour la validation.
Récupérer le Go lancé par le clavier
Si vous compilez et lancez votre application maintenant, il va se passer quelque chose d’assez désagréable. Vous touchez le champ d’adresse, tapez http://www.tutomobile.fr et maintenant vous pourrez écraser vigoureusement le bouton Go, il ne faut pas rêver : il ne va rien se passer du tout. Toucher ce bouton doit faire deux choses :
- mettre à jour la UIWebView avec la nouvelle adresse
- masquer ce clavier qui n’est plus nécessaire jusqu’à ce qu’on retouche le champ d’adresse
Le premier réflexe serait de créer une (IBAction) dans notre MyWebBrowserViewController et de relier un événement à cette action. Une manière de faire qui pourrait ressembler à celle que nous avons employée pour les UIButton dans le Tutoriel n°3, par exemple. Mais là : problème ! Il n’y a pas vraiment l’événement qui correspond à ce Go.
Il y a une autre voie. UITextField peut (et souvent doit) être accompagné d’un Delegate (mais si, rappelez-vous le Tutoriel n°6 où nous parlions des AppDelegate) ; c’est à dire un « représentant » : un objet qui vient en soutien. Nous allons dire à notre UITextField que notre classe MyWebBrowserViewController est son représentant.
Ouvrez le fichier MyWebBrowserViewController.h et modifiez la déclaration de la classe qui devient :
@interface MyWebBrowserViewController : UIViewController <UITextFieldDelegate> {
Ceci signifie que MyWebBrowserViewController implémente désormais le protocole UITextFieldDelegate. En d’autre termes, votre classe lance un cri du coeur : « oui ! UITextField, je suis digne d’être ton delegate ! ». Pour savoir ce qu’il est nécessaire ou possible d’implémenter comme méthode dans le cadre de ce protocole, appuyez sur la touche « Commande » du clavier (euh… pomme, quoi) et double-cliquez sur <UITextFieldDelegate> pour consulter la déclaration. Toutes les méthodes sont optionnelles, celle qui nous intéresse s’appelle textFieldShouldReturn.
Retournez dans le code de MyWebBrowserViewController.m et implémentez comme suit :
- (BOOL) textFieldShouldReturn:(UITextField *)textField { NSURL *urlAddress = [NSURL URLWithString: textField.text]; // Ouvrir l'URL NSURLRequest *requestObject = [NSURLRequest requestWithURL:urlAddress]; //Load the request in the UIWebView. [webView loadRequest:requestObject]; // Réduire le clavier [textField resignFirstResponder]; return YES; }
Pour afficher l’adresse URL saisie dans la UIWebView, vous remarquerez que le code est sensiblement le même que précédemment. Pour réduire le clavier, c’est extrêmement simple : lorsque vous touchez le UITextField, le clavier apparaît et s’inscrit comme étant le « First Responder » de l’objet. Si vous lancez le message resignFirstResponder, vous révoquez le clavier : il disparaît.
Il reste une dernière toute petite chose que nous n’avons pas faîte, assigner au UITextField son nouveau delegate. Retournez modifier MyWebBrowserViewController.xib, cliquez droit sur le UITextField, et faîtes glisser depuis « delegate » vers l’objet « File’s Owner ». Sauvegardez, compilez et testez.
Attention, dans cette version, il est nécessaire de préciser « http:// » devant les URLs que vous tapez pour que cela fonctionne. Voilà un petit exercice rapide à réaliser : ajouter automatiquement « http:// » si ce n’est pas précisé par l’utilisateur !
C’est ainsi que s’achève ce tutoriel iPhone n°7. Vous l’aviez compris, le navigateur web était un prétexte pour vous faire aussi découvrir quelques subtilités des UITextFields, que vous retrouverez dans la plupart de vos applications. Cependant, s’il vous reste quelques minutes, je vous conseille d’aller jeter un oeil sur le tutoriel Android n°9 pour voir les différences qui peuvent séparer les deux plateformes sur des objets comme une vue Web.

Cette création par Tuto Mobile est mise à disposition selon les termes de la licence Creative Commons Paternité - Pas d'Utilisation Commerciale - Partage des Conditions Initiales à l'Identique 3.0 Unported.
Encore un peu de lecture :
-
Création dʼun SplashScreen animé [Tutoriel iPhone n°12] -
[Concours] Résultats du concours pour gagner 4 formation video2brain iPhone -
[Concours] Gagner 4 formations vidéos pour apprendre le développement iPhone















Bonjour,
je te remerci pour ce tuto mais je fais se que tu indique mais soit cela ne marche pas mais je dois loupé un truc car quand j’ouvre mon fichier .xib de la view ba je ne peux pas associer la webview au file owner, j’ai que view qui est indiquer dans la petite liste. view avec view mais je n’ai pas de webview ! sinon voila en gros je n’y arrive pas ^^
sa me soul un peu !
@keke : Hello ! Vérifie que tu as bien saisi IBOutlet devant la déclaration de ton attribut dans XCode : c’est ce mot clé qui indique à InterfaceBuilder que tu peux associer cet attribut à un élément dans la vue.
Je viens de me faire tous les tutoriaux iPhone du site, merci pour tout, c’est super bien expliqué.
Félicitation
Encore une fois, un grand merci. J’ai beaucoup cherché après une façon fonctionnelle de cacher le clavier et c’est ici que c’est le mieux expliqué (et que ca fonctionne :p)
bravo
Merci !
J’arrive avec la suite dans les prochains jours !
Super bien fait, ces tutos.
Juste une question :
Pourquoi [webView dealloc] et pas [webView release] ?
Merci.
Super tuto juste un petit pb la barre d’adresse ne marche pas … j ai pas comprit pourquoi le clavier part mais google reste xD
ps: je suis sur iPad
Hello tout le monde !
Ce tutoriel a été testé et mis à jour pour fonctionner avec XCode 4. J’en ai profité pour faire quelques corrections minimes (merci @CB !)
Bonjour,
je voudrais juste un petit peu améliorer ton code, mais je ne trouve pas de méthode avec les NSString pour voir si une chaine de caractères est dans une autre, quel est le nom de cette methode?
Merci d’avance.
Super tes tutos Quelqu’un a trouver comment ajouter http:// si l’utilisateur ne le rentre pas ? moi je seche …
Bonne idée de mettre à jour le tuto sous XCODE 4, car c’est pas évident de manipuler cette nouvelle interface et pas beaucoup de doc.
Mais il manque des phase dans ton tuto :
1/d’où vient le fichier MyWebBrowserViewController.h
2/d’où vient le fichier xib ?
3/d’où vient le object/uiview du MyWebBrowserViewController.xib ? (car si c’est un uiviewcontroller, c’est un objet viewcontroller
voilà, merci de la mise à jour
Pour rajouter le http:// il faut ajouter ceci dans le fichier MyWebBrowserViewController.m
dans la méthode « -(BOOL) textFieldShouldReturn:(UITextField *)textField »
le pan de code suivant :
if ([textField.text rangeOfString:@"http://"].location == NSNotFound ) {
textField.text = [@"http://" stringByAppendingString:textField.text];
}
cela va scanner le contenu du texte, si la chaîne « http:// » n’est pas trouvée, il va l’ajouter grâce à la fonction « stringByAppendingString ».
Je me suis inspiré du tuto calculatrice à la méthode qui est appelée lorsque l’on touche la virgule
Voilà
Bonjour,
j’aimerais ajouter aussi le petit indicateur d’activité, seulement je n’arrive pas a faire en sorte qu’il apparaisse du début a la fin du chargement de façon juste.
pour l’afficher :
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
mon soucis est que celui ci disparait largement avant la fin du chargement de la page car je me base sur la view, comment puis-je me baser sur la webview?
Merci d’avance
Bonjour,
je galère un peu donc je voudrais savoir si ce serait possible que vous mettiez le projet xcode en ligne sur par exemple mediafire ou autre?
Merci d’avance je galère
Si tu savais comme je t’aime.
Une demi-journée que j’essaye de comprendre comment fonctionne ce satané ‘Interface Builder’.
Un grand merci.