Méthode didFailLoadWithError obligatoirement valide avec un UIViewController ?

apocaalypsoapocaalypso Membre
avril 2009 modifié dans API UIKit #1
Bonjour,

dans mon application iPhone, l'utilisateur a la possibilité de regarder les news de l'application directement via celle-ci grâce à  une UIWebView.

Le problème c'est que je n'ai pas de méthode appellée lorsque la page internet ne peut pas se charger (didFailLoadWithError:).

J'ai donc ceci pour charger la page Internet :
<br />-(void)switchToNews:(NSString *)website<br />{<br />	// Removing the Home views<br />	[homeButtonsView removeFromSuperview];<br />	<br />	// Transition<br />	[UIView beginAnimations:nil context:NULL];<br />	[UIView setAnimationDuration:0.5];<br />	[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:[self superview] cache:NO];<br />	// Adding the News view<br />	[self addSubview:newsView];<br />	[UIView commitAnimations];<br /><br />	// Make the background transparent<br />	[newsView setBackgroundColor:[UIColor clearColor]];<br />		<br />	[self loadWebsite:website];<br />}<br /><br />-(void)loadWebsite:(NSString *)website<br />{<br />	// Loading the last news<br />	NSURL *newsURL = [NSURL URLWithString:website];<br />	NSURLRequest *newsReq = [NSURLRequest requestWithURL:newsURL];<br />	// Load the request in the WebView<br />	[newsWebView loadRequest:newsReq];<br />}<br />


J'ai donc rajouté à  la suite :
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error<br />{<br />	// load error, hide the activity indicator in the status bar<br />	[UIApplication sharedApplication].isNetworkActivityIndicatorVisible = NO;<br /><br />UIAlertView * scoreError = [[UIAlertView alloc] initWithTitle: @&quot;Network error&quot; message: @&quot;Error sending your info to the server&quot; delegate: self cancelButtonTitle: @&quot;Ok&quot; otherButtonTitles: nil];<br /> <br />[scoreError show];<br />}<br />


Mais rien ne s'affiche lorsque Internet est coupé.
Je pense que c'est parce que le type de mon .m est UIView et non UIViewController non ?

Si c'est ça je n'ai plus qu'à  tout recommencer...

Merci de vos conseils !

Réponses

  • AliGatorAliGator Membre, Modérateur
    15:38 modifié #2
    didFailLoadWithError est une méthode... de delegate !
    Elle est donc appellée sur le delegate de ta UIWebView... encore faut-il que tu définisses ce dernier !

    Un "newsView.delegate = (l'objet qui va implémenter ta méthode didFailLoadWithError)" est donc la solution... en l'occurence "newsView.delegate = self" permettrait que lorsque ta newsView foire son chargement, elle appelle didFailLoadWithError sur... self, autrement dit ton UIViewController dans lequel tu mets ce code.
  • apocaalypsoapocaalypso Membre
    15:38 modifié #3
    Lorsque je met mon newsView.delegate = self dans mon -(void)switchToNews:(NSString *)website, il me retourne une erreur :
    error: request for member &#39;delegate&#39; in something not a structure or union<br />
    


    Je ne comprend pas.
  • AliGatorAliGator Membre, Modérateur
    15:38 modifié #4
    c'est quoi newsView ? une UIView ou une UIWebView ?
    Moi je pensais que c'était une UIWebView mais ça ne semble pas être le cas ?
    Ou alors c'est une UIWebView de manière général, mais ta variable newsView est typée comme étant une UIView (ce qui est légal puisque UIWebView hérite de UIView...) mais du coup quand tu veux accéder aux propriétés spécifiques de la classe UIWebView, il faut bien sûr transtyper (caster) ta variable newsView en UIWebView.

    De plus, je t'invite à  lire la doc de UIWebView, la propriété delegate... et la doc du protocole UIWebViewDelegate (d'ailleurs il faudra que tu déclares ton "self" (ton UIViewController en l'occurence) comme implémentant le protocole UIWebViewDelegate dans ton .h sinon il va pas aimer). Entre autres il est dit dans la doc qu'avant de désallouer une UIWebView (ta newsView en l'occurence), il faut absolument remettre son delegate à  nil (typiquement dans le dealloc de la UIWebView), donc faudra pas oublier.
  • apocaalypsoapocaalypso Membre
    15:38 modifié #5
    En fait ici, newsView est la UIView qui contient ma WebView et newsWebView est ma UIWebView contenue dans newsView qui va charger la page Web.
  • AliGatorAliGator Membre, Modérateur
    15:38 modifié #6
    Ok donc en réfléchissant 2 secondes t'as ta réponse.
    C'est la UIWebView qui appelle sur son delegate la méthode webView:didFailLoadWithError:
    Il suffit donc de définir le delegate de ta UIWebView à  l'objet (typiquement ici self, ton UIViewController) dans lequel tu as implémenté cette méthode.

    Utilisation classique d'un delegate, quoi ;)
  • apocaalypsoapocaalypso Membre
    15:38 modifié #7
    Ok, j'ai mis mon newsWebView.delegate = self dans ma loadWebsite: et ma webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error juste après et ça marche.

    Merci beaucoup Ali pour ton aide !
  • apocaalypsoapocaalypso Membre
    avril 2009 modifié #8
    Ah, j'aurais une dernière petite question du même genre.
    J'ai une UIAlertView avec deux boutons : un pour quitter la vue "Quit" et l'autre pour cancel "No" :
    UIAlertView *quitMessage = [[UIAlertView alloc] initWithTitle:@&quot;Quit Game&quot;<br />															message:@&quot;Are you sure you want to quit the game ?&quot; <br />														&nbsp;  delegate:self<br />												&nbsp; cancelButtonTitle:@&quot;No&quot;<br />												&nbsp; otherButtonTitles:@&quot;Quit&quot;, nil];<br />		[quitMessage show];<br />		[quitMessage release];<br />
    


    Et je voudrais faire quelque chose si l'utilisateur tape le bouton "Quit".
    J'ai donc :
    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex<br />{<br />	if(buttonIndex == 1)<br />	{<br />		[gameView removeFromSuperview];<br />	}	<br />}<br />
    


    Mais ça ne marche pas.
    Pourtant j'ai bien delegate:self dans mon UIAlertView non ?
  • AliGatorAliGator Membre, Modérateur
    15:38 modifié #9
    Met un NSLog au début de ta méthode de delegate "alertview:clickedOnMachin:", dès la première ligne, pour voir au moins si la méthode est appelée ou pas... Si ça se trouve elle est appelée mais c'est ton if qui n'est pas bon, commençons par isoler le bon problème ;)
  • LastikoLastiko Membre
    15:38 modifié #10
    il est fort ce Ali; il donne toutes les reponses  ;D
    en faite dans ton code d'origine tu avais ca
    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
    


    l'erreur etait bien dans la premiere ligne
    - (void)alertView:(UIAlertView *)quitMessage clickedButtonAtIndex:(NSInteger)buttonIndex<br />{<br />	if(buttonIndex == 1)<br />	{<br />		NSLog(@&quot;zoooooooooooouuuuuuu&quot;);<br />	}&nbsp;  <br />}
    
  • apocaalypsoapocaalypso Membre
    15:38 modifié #11
    ça marche, j'ai bien remplaçé alertView par quitMessage.
    Par ailleur mon if n'était pas associé au bon bouton, j'ai remplacé par 0.
  • AliGatorAliGator Membre, Modérateur
    15:38 modifié #12
    remplacer alertView par quitMessage dans la signature de la fonction ne change rien, ce n'est que la signature de la fonction, le nom local de la variable qui va être affectée à  la UIAlertView appelant cette méthode de délégué... comme tu ne te sers pas de cette variable dans ta méthode de delegate en plus, puisque tu n'as que ton "if" dedans, bah ça n'a vraiment aucune incidence.
    Et il n'y a aucune obligation à  mettre le même nom pour le paramètre que pour ta variable qui t'a servi à  créer ton AlertView... d'ailleurs si en plus de ça ton UIAlertView* quitMessage était une variable d'instance (et non une variable locale à  ta méthode qui crée le UIAlertView) ça ferait de l'obfuscation (shadowing), puisque tu aurais 2 variables de même nom (celle de ta classe, la variable d'instance, et celle de ta signature de méthode, variable locale à  la méthode)...

    C'était donc bien juste le "if" qui était faut comme suggéré dès le premier message ;)
  • LastikoLastiko Membre
    15:38 modifié #13
    et moi qui pensait avoir une réponse :(

    bon ben je vais allez tester ce que tu viens d'expliquer comme ca je vais un peu comprendre aussi :D
  • LastikoLastiko Membre
    15:38 modifié #14
    donc effectivement , merci pour l'explication
  • apocaalypsoapocaalypso Membre
    15:38 modifié #15
    Effectivement, en remplaçant par alertView ça marche aussi.
    Merci pour tes grandes explications Ali !
  • apocaalypsoapocaalypso Membre
    15:38 modifié #16
    C'est normal que le bouton "Quit" se trouve à  gauche dans le firmware 3.0 et à  droite dans le 2.2.1 ?
    Du coup quand on clique sur "Quit" c'est cancel.
Connectez-vous ou Inscrivez-vous pour répondre.