web-dev-qa-db-fra.com

Application iOS - Définir le délai d'expiration pour le chargement UIWebView

J'ai une simple application native iOS qui charge une seule UIWebView. Je voudrais que la webView affiche un message d'erreur si l'application ne termine PAS COMPLÈTEMENT le chargement de la page initiale dans la webView dans les 20 secondes.

Je charge mon URL pour la webView dans mon viewDidLoad comme ceci (simplifié):

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

Le timeoutInterval dans le code ci-dessus ne "fait" rien du tout, car Apple le définit dans le système d'exploitation pour ne pas réellement expirer pendant 240 secondes.

J'ai mon webView didFailLoadWithError actions définies, mais si l'utilisateur dispose d'une connexion réseau, celle-ci n'est jamais appelée. Le WebView continue juste d'essayer de se charger avec la rotation de mon networkActivityIndicator.

Existe-t-il un moyen de définir un délai d'expiration pour la webView?

23
adamdehaven

Le timeoutInterval sert à la connexion. Une fois la vue Web connectée à l'URL, vous devrez démarrer NSTimer et faire votre propre gestion du délai d'expiration. Quelque chose comme:

// 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];
}
41
mask8

Toutes les solutions suggérées ne sont pas idéales. La bonne façon de gérer cela consiste à utiliser timeoutInterval sur le NSMutableURLRequest lui-même:

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

request.timeoutInterval = 10;

[webview loadRequest:request];
7
Sandy Chapman

Ma façon est similaire à la réponse acceptée, mais arrêtez simplement le chargement lorsque le délai d'expiration et le contrôle dans 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. 
}
3
LE SANG

Les codeurs Swift peuvent le faire comme suit:

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")
}
2
Satnam Sync