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?
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];
}
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];
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.
}
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")
}