2012-07-23 6 views
22

Ich habe eine einfache iOS native App, die ein einzelnes UIWebView lädt. Ich möchte, dass das WebView eine Fehlermeldung anzeigt, wenn die App die erste Seite innerhalb von 20 Sekunden nicht vollständig in das WebView geladen hat.iOS-App - Timeout für UIWebView laden

ich meine URL für die WebView in meiner viewDidLoad wie folgt aus (vereinfacht) laden:

[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.example.com"] cachePolicy:NSURLCacheStorageAllowed timeoutInterval:20.0]]; 

Der timeoutInterval innerhalb des Codes über alles nicht wirklich „tun“, wie die von Apple hat es innerhalb des OS auf nicht wirklich 240 Sekunden Pause.

Ich habe meine webView didFailLoadWithError Aktionen eingestellt, aber wenn der Benutzer eine Netzwerkverbindung hat, wird dies nie aufgerufen. Das webView versucht gerade weiterhin, mit meinem spinnenden networkActivityIndicator zu laden.

Gibt es eine Möglichkeit, ein Timeout für das WebView festzulegen?

+1

jemand hier sagte die Timeout-Zeit für die Verbindung ist. Sobald es mit dem Server verbunden ist, wird kein Fehler mehr ausgelöst. Sie müssen Ihren eigenen NSTimer implementieren, nachdem er in webViewDidStartLoad verbunden ist und Sie selbst abbrechen http://stackoverflow.com/questions/1883888/nsmutableurlrequest-timeout-doesnt-trigger-if-data-starts-to-load-but-not- webvi – mask8

+0

Das sieht genau nach was ich suche ... könntest du mir vielleicht eine Anleitung geben, wie ich es umsetzen kann? (Ich bin ein Objective-C newby) – adamdehaven

+0

Ich muss nur wissen, was Sie dafür setzen: '- (void) webView: NSTimer * theTimer { NSLog (@" Ich ist hier bei 1 Minute Verzögerung "); } ' Wie welche Zielmethode würde ich verwenden? – adamdehaven

Antwort

40

Das TimeoutInterval ist für die Verbindung. Sobald die Webansicht mit der URL verbunden ist, müssen Sie NSTimer starten und Ihre eigene Timeout-Behandlung durchführen. Etwas wie:

// define NSTimer *timer; somewhere in your class 

- (void)cancelWeb 
{ 
    NSLog(@"didn't finish loading within 20 sec"); 
    // do anything error 
} 

- (void)webViewDidFinishLoad:(UIWebView *)webView 
{ 
    [timer invalidate]; 
} 

- (void)webViewDidStartLoad:(UIWebView *)webView 
{ 
    // webView connected 
    timer = [NSTimer scheduledTimerWithTimeInterval:20.0 target:self selector:@selector(cancelWeb) userInfo:nil repeats:NO]; 
} 
+0

Ich habe die obigen Methoden hinzugefügt, aber nach 20 Sekunden tut es nichts? - Ich habe ein UIAlertView in die Eigenschaft 'cancelWeb' eingefügt, aber es wird nie ausgelöst. – adamdehaven

+1

Entschuldigung eine Änderung, nicht 'NSTimer timerWithTimeInterval', sondern' terminatedTimerWithTimeInterval'. Sobald Ihr WebView mit der URL verbunden ist, wird 'webViewDidStartLoad' aufgerufen. Wenn nicht, haben Sie den Delegaten nicht richtig gesetzt. Dann startet diese Methode den Timer, um die 'cancelWeb' Methode in 20 Sekunden aufzurufen. – mask8

+0

Vielen Dank !!! Funktioniert perfekt :) Noch eine Frage - muss ich etwas tun, um den Timer freizugeben, wenn sie die App in der 'viewWillDisappear' oder' viewDidUnload' beenden? – adamdehaven

3

Mein Weg ist, um akzeptierte Antwort ähnlich, aber nur StopLoading wenn Zeit und Kontrolle in didFailLoadWithError.

- (void)timeout{ 
    if ([self.webView isLoading]) { 
     [self.webView stopLoading];//fire in didFailLoadWithError 
    } 
} 

- (void)webViewDidStartLoad:(UIWebView *)webView{ 
    self.timer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(timeout) userInfo:nil repeats:NO]; 
} 

- (void)webViewDidFinishLoad:(UIWebView *)webView{ 
    [self.timer invalidate]; 
} 

- (void)webView:(UIWebView *)webView didFailLoadWithError:(nullable NSError *)error{ 
    //Error 999 fire when stopLoading 
    [self.timer invalidate];//invalidate for other errors, not time out. 
} 
+0

Dies ist die bessere Antwort, da es die Webansicht nach dem Timeout tatsächlich stoppt. Ich würde auch vorschlagen, 'self.timer' auf' nil' zu setzen, nachdem Sie es ungültig gemacht haben und nachdem es abgeschlossen ist. – rmaddy

2

Swift-Programmierer kann es wie folgt tun:

var timeOut: NSTimer! 

func webViewDidStartLoad(webView: UIWebView) { 
    self.timeOut = NSTimer.scheduledTimerWithTimeInterval(7.0, target: self, selector: "cancelWeb", userInfo: nil, repeats: false) 
} 

func webViewDidFinishLoad(webView: UIWebView) { 
    self.timeOut.invalidate() 
} 

func webView(webView: UIWebView, didFailLoadWithError error: NSError?) { 
    self.timeOut.invalidate() 
} 

func cancelWeb() { 
    print("cancelWeb") 
} 
6

Alle der vorgeschlagenen Lösungen sind nicht ideal. Der richtige Weg, dies zu handhaben ist, mit dem timeoutInterval auf den NSMutableURLRequest selbst:

NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://web.site"]]; 

request.timeoutInterval = 10; 

[webview loadRequest:request]; 
+0

das ist die richtige lösung !!! – ElectroBuddha

+0

Ruft dies nach einem Timeout 'didFailToLoad withError' auf? –

+1

@Albertrenshaw ja, es ruft die Delegate-Methode automatisch auf –