2009-07-24 7 views
1

iPhone/objC? Examinez une réponse pendant que webView: shouldStartLoadWithRequest: naviagiontType ... attend?

Je suis vraiment coincé ici et je pourrais utiliser de l'aide, s'il vous plaît.

Permettez-moi d'abord expliquer certaines choses:

J'ai un UIWebView qui charge une URL. une fois que l'utilisateur clique sur un lien - (BOOL) webView: shouldStartLoadWithRequest: navigationType: reçoit un message (selon le protocole). À l'intérieur de cette méthode, je peux décider si l'URL doit être chargée dans le WebView ou faire autre chose avec elle. J'établis un NSURLConnection ainsi je peux examiner la réponse.

- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request 
navigationType:(UIWebViewNavigationType)navigationType { 

    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 
    if (theConnection) { 
     NSLog(@" Connection established"); 
     receivedDataFromConnection = [[NSMutableData data] retain]; 
     } 
    else { 
     NSLog(@"Connection failed"); 
    } 


    if (downloadYESorNO == YES) { 
     NSLog(@"Do the download"); 
     return NO; 
    } 
    else { 
     NSLog(@"will show in webView"); 
     return YES; 
    } 
} 

une fois que l'application reçoit une réponse - (void) connexion: didReceiveResponse: reçoit un message (selon le protocole) et je peux analyser la réponse là.

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{  
     NSString *MIME = response.MIMEType; 
     NSString *appDirectory = [[NSBundle mainBundle] bundlePath]; 
     NSString *pathMIMETYPESplist = [appDirectory stringByAppendingPathComponent:@"MIMETYPES.plist"]; 

     NSArray *displayMIMETypes = [NSArray arrayWithContentsOfFile: pathMIMETYPESplist]; 
     BOOL *asdf = [displayMIMETypes containsObject:MIME]; 

     if (asdf == YES) { 
      downloadYESorNO =NO; 
     } 
     else { 
      downloadYESorNO = YES; 
     } 

     [receivedDataFromConnection setLength:0]; 
     [connection release]; 

Maintenant, ce que je suis en train de réaliser est de laisser - (BOOL) webView: shouldStartLoadWithRequest: attendre jusqu'à - connexion (void): didReceiveResponse: est prêt.

Je peux travailler avec sendSynchronousRequest: car il téléchargerait le fichier complet avant de pouvoir examiner la réponse.

Est-ce que quelqu'un a une idée? Merci d'avance. ou existe-t-il une meilleure façon d'examiner la réponse?

Répondre

6

Si vous voulez vraiment - (BOOL) webView: shouldStartLoadWithRequest: vous avez deux options. La première est que vous pouvez charger vos données de manière synchrone:

NSData * receivedDataFromConnection = [NSURLConnection sendSynchronousRequest: request returningResponse:&response error:&error]; 

Si vous faites que vous n'avez pas à mettre en œuvre les méthodes de délégués (car ils ne seront pas appelés). Vous devez simplement passer la réponse dans une méthode qui vérifie si vous voulez ou non télécharger. L'inconvénient est que vous allez jouer le runloop pendant que vous chargez si vous faites cela, ce qui signifie que l'interface utilisateur ne répondra plus, et si vous êtes sur une connexion lente, l'application pourrait être tuée parce qu'elle s'arrêtera répondre aux événements trop longtemps.

L'autre option est d'exécuter votre runloop intérieur du webView: shouldStartLoadWithRequest: NavigationType:

- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request 
navigationType:(UIWebViewNavigationType)navigationType { 

    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 
    if (theConnection) { 
     NSLog(@" Connection established"); 
     receivedDataFromConnection = [[NSMutableData data] retain]; 
     } 
    else { 
     NSLog(@"Connection failed"); 
    } 

    waitingForResponse = YES; 
    while (waitingForResponse) { 
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
     [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; 
     [pool drain]; 
    } 


    if (downloadYESorNO == YES) { 
     NSLog(@"Do the download"); 
     return NO; 
    } 
    else { 
     NSLog(@"will show in webView"); 
     return YES; 
    } 
} 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{  
    NSString *MIME = response.MIMEType; 
    NSString *appDirectory = [[NSBundle mainBundle] bundlePath]; 
    NSString *pathMIMETYPESplist = [appDirectory stringByAppendingPathComponent:@"MIMETYPES.plist"]; 

    NSArray *displayMIMETypes = [NSArray arrayWithContentsOfFile: pathMIMETYPESplist]; 
    BOOL *asdf = [displayMIMETypes containsObject:MIME]; 

    if (asdf == YES) { 
     downloadYESorNO =NO; 
    } else { 
     downloadYESorNO = YES; 
    } 

    [receivedDataFromConnection setLength:0]; 
    [connection release]; 
    waitingForResponse = NO; 
} 

En exécutant la runloop vous permettent le traitement des événements de continuer, ce qui permet à vos méthodes de délégués s'appellent. Il est clair que vous avez besoin de détecter quand cela est fait et arrêtez d'exécuter le runloop, ce qui est le but de l'ivar waitingForResponse. Parce que votre runloop est en cours d'exécution l'interface utilisateur sera non seulement toujours capable de répondre à l'événement, mais complètement interactif. Cela signifie que l'utilisateur peut taper sur plus de liens pendant que vous faites cela. Vous devrez vous protéger de cela, soit en rendant votre code réentrant, ou en désactivant l'interaction de l'utilisateur pour tout ce qui peut causer des problèmes.

Dans tous les cas, il y a beaucoup de pièges à l'approche. C'est vraiment quelque chose de compliqué, et si vous n'êtes pas un développeur Cocoa expérimenté, je ne le recommande pas, si vous pouvez trouver un autre moyen de gérer votre processus de téléchargement, ce sera beaucoup plus simple.

+0

merci beaucoup! Je vais essayer aujourd'hui et penser à des moyens plus simples parce que je suis tout à fait nouveau à développer. seulement 2 semaines d'expérience: D – Yllier

+0

vient de l'essayer. ça marche super bien, mais maintenant j'ai remarqué que mon idée n'est pas très bonne. Par exemple, si les gens essaient de poster dans un forum, ils vont poster un message d'erreur ou recevoir un message d'erreur ... – Yllier

Questions connexes