NetworkActivityIndicator

seb92seb92 Membre
juin 2011 modifié dans Vos applications #1
Bonjour à  tous,

Je souhaite activer un indicateur d'activité lorsque je charge des flux RSS dans mon application.
J'ai une 1 vue ou il y a une tableView (plusieurs choix). Une fois la cellule cliquée, celle-ci me dirige vers une seconde vue.
Cette seconde vue récupère un flux RSS et les range dans une tableView aussi.

Je bloque sur la façon de mettre un indicateur d'activité lors du chargement des flux RSS.
Au début, j'ai essayé de l'instaurer dans la seconde vue :
<br />- (void)parserDidStartDocument:(NSXMLParser *)parser {<br />&nbsp; &nbsp;  [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];<br />}<br /><br /><br />- (void)parserDidEndDocument:(NSXMLParser *)parser {<br />&nbsp; &nbsp; [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];<br />}<br /><br />


L'indicateur s'arrete au bon moment, mais commence trop tard. Lorsque je clique sur la cellule de ma 1ere vue, celle-ce reste sélectionnée pendant au moins 5 secondes (le temps que le flux se charge pour la seconde vue) sans indicateur, avant de passer à  ma seconde vue (qui elle arrive chargée avec toutes ses données).

Donc je me suis dit qu'il fallait que je l'active avant de commencer la lecture du flux RSS. Plutôt le faire au moment ou je clique sur une cellule :
<br />- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { <br />&nbsp; &nbsp; [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];<br />...}<br /><br />

Mais rien n'y change, j'ai toujours le même problème.

Je comprends pas ce qui m'arrive, merci de me venir en aide.

Réponses

  • AliGatorAliGator Membre, Modérateur
    04:20 modifié #2
    Je parie que tu fais un download synchrone. Normal que toute ton appli bloque le temps du download du coup.
    Lis le "URL Loading Programming Guide" tout y est expliqué pour faire du download asynchrone.
  • seb92seb92 Membre
    04:20 modifié #3
    Bonjour, merci pour la réponse.


    J'ai pris la connaissance de la doc, et je n'implémente pas  "sendSynchronousRequest:".

    Pour créer la connection je fais juste :
    <br />- (void)parseXMLFileAtURL:(NSString *)URL {<br /><br />&nbsp; &nbsp; NSURL *xmlURL = [NSURL URLWithString:URL];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; rssParser=[[NSXMLParser alloc] initWithContentsOfURL:xmlURL];<br />....<br />}<br />
    
  • AliGatorAliGator Membre, Modérateur
    04:20 modifié #4
    Ca revient au même, initWithContentsOfURL de NSXMLParser effectue un download synchrone des données (NSData) à  l'URL spécifiée, avant de lancer le parsing.
    Il faut donc faire un download aysnchrone (via NSURLConnection, etc) pour récupérer soi-même les NSData (de façon non bloquante, donc, du coup), et une fois qu'on a les NSData utiliser initWithData au lieu de initWithContentsOfURL.
  • seb92seb92 Membre
    04:20 modifié #5
    Sa me fait toujours pareil, j'ai la cellule qui reste sélectionnée (pendant quelques secondes).
    Puis même pas une demi seconde avant le chargement de page, l'indicateur fonctionne, et disparait aussi tôt la page affichée.

    Lorsque l'on connait pas l'application, on à  l'impression qu'elle beug sur la 1ere vue....


    <br />- (void)parseXMLFileAtURL:(NSString *)URL {<br />	stories = [[NSMutableArray alloc] init];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:URL]];<br />&nbsp; &nbsp; NSData *response = [[NSData alloc]initWithData:[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]];<br />&nbsp; &nbsp; <br />&nbsp; &nbsp; <br />&nbsp; &nbsp; rssParser=[[NSXMLParser alloc] initWithData:response];<br />.....}<br />
    
  • AliGatorAliGator Membre, Modérateur
    04:20 modifié #6
    Ben heu normal tu utilises sendSynchronousRequest... Tant que tu resteras en asynchrone le pb sera tjs là 
  • seb92seb92 Membre
    04:20 modifié #7
    Ah oui, oups...

    Mais je suis obliger d'implémenter toute les méthodes de NSULconnection ? donc j'ai plus besoin de parser ici, mais plutôt dans :
    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {} ?
  • AliGatorAliGator Membre, Modérateur
    04:20 modifié #8
    Oui c'est ça, ou presque, c'est dans connectionDidFinishLoading qu'il faut lancer le parsing.
    dans didReceiveData tu ne fais que recevoir un bout des données (téléchargement progressif), données qu'il faut concaténer tout au long du download jusqu'à  ce qu'il arrive à  la fin (didFinishLoading) et qu'il ait le contenu complet du XML, où là  tu pourras le parser.

    Mais tout est expliqué dans le URL Loading System Programming Guide et surtout avec des exemples de code que tu n'as plus qu'à  copier/coller ou presque.
  • seb92seb92 Membre
    04:20 modifié #9
    Oui merci,
    Maintenant ce n'est plus au même endroit, mais ça fait toujours pareil.

    Alors, la je clique sur la cellule de mon tableau (1ere vue). J'arrive a la seconde vue ou c'est hyper rapide (plus comme avant ou ça reste 4/5secondes sur la cellule).
    Et je suis sur la seconde Vue avec une tableView vide, et pendant 4/5 secondes rien ne se passe. Puis comme avant, en 1/2 secondes le contenu se charge et l'indicateur aussi..

    donc j'ai pareil qu'avant, sauf que les 5 secondes ou il y a rien, ne sont plus lorsque je clique sur la cellule de ma 1ere vue mais a l'affichage de la seconde vue.

    Peut être une erreur dans ma la connection asynchrone ?
    <br />&nbsp; &nbsp; &nbsp;  <br />-(void) downloadAsync:(NSString *)URL {&nbsp; &nbsp; <br />&nbsp;  <br />&nbsp; &nbsp; NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:URL]];<br />&nbsp; &nbsp; [NSURLConnection connectionWithRequest: request delegate:self];<br />}<br /><br /><br /><br />- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response<br />{<br /><br />&nbsp; &nbsp; [dataFlux setLength:0];<br />}<br /><br /><br /><br />- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {<br />&nbsp; &nbsp; if (dataFlux) {<br />&nbsp; &nbsp; &nbsp; &nbsp; [dataFlux appendData:data];<br />&nbsp; &nbsp; } else {<br />&nbsp; &nbsp; &nbsp; &nbsp; dataFlux = [data mutableCopy];<br />&nbsp; &nbsp; }<br />}<br /><br />- (void)connectionDidFinishLoading:(NSURLConnection *)connection {<br />&nbsp; &nbsp; stories = [[NSMutableArray alloc] init];<br /><br />&nbsp; &nbsp; rssParser=[[NSXMLParser alloc] initWithData:dataFlux];<br />	.....<br />}<br />
    
  • AliGatorAliGator Membre, Modérateur
    04:20 modifié #10
    OK donc tout est parfaitement logique.

    Tu cliques sur la cellule, ça pousse ton contrôlleur, qui démarre un téléchargement des données en arrière plan.
    Toi pendant ce chargement des données, dans le thread principal tu ne fais rien (tu n'active pas le networkActivityIndicator, tu n'affiches pas à  l'écran un UIActivityIndicatorView...) donc normal que ça t'affiche un écran avec rien dedans (c'est à  toi bien sûr de prévoir d'informer l'utilisateur genre avec un message "chargement des données en cours").

    Sauf que maintenant ton téléchargement est asynchrone. Ca veut dire qu'il se fait en tâche de fond, et que pendant qu'il se fait, le reste de ton programme continue à  s'exécuter (par exemple ta 2e vue a le temps d'être poussée, mais tu as aussi le temps d'activer le networkActivityIndicator et d'afficher des vues et tout, ça bloque pas l'appli comme si elle était plantée) -- contrairement à  quand il était synchrone où toute l'appli était "gelée" le temps que le téléchargement se fasse car il attendait d'avoir fini le téléchargement avant de continuer à  exécuter le reste de ton code.
  • seb92seb92 Membre
    04:20 modifié #11
    Je vais me contenter de ça alors.
    Merci de ton aide  :)
Connectez-vous ou Inscrivez-vous pour répondre.