2012-07-23 52 views
22

設置超時我有一個加載一個UIWebView的一個簡單的iOS原生應用程序。如果應用程序不完全在20秒內完成在webView中加載初始頁面,我希望webView顯示錯誤消息。iOS應用 - 對於一個UIWebView加載

我在我的viewDidLoad像這樣(簡體)載入我的web視圖網址:

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

代碼中的timeoutInterval上面並沒有真正「做」什麼,因爲蘋果有它在操作系統中設置爲實際上並沒有超時240秒。

我已經把我的webView didFailLoadWithError行動,但如果用戶有一個網絡連接,這不會被調用。 webView只是繼續嘗試加載我的networkActivityIndi​​cator旋轉。

有沒有辦法來設置web視圖超時?

+1

有人在這裏說超時間隔是連接。一旦它連接到服務器,它不會拋出錯誤了。您需要實現自己的NSTimer它連接webViewDidStartLoad後自己http://stackoverflow.com/questions/1883888/nsmutableurlrequest-timeout-doesnt-trigger-if-data-starts-to-load-but-not-取消webvi – mask8 2012-07-23 15:45:07

+0

這看起來像我正在尋找的......你能給我一些關於如何實現它的指導嗎? (我是一個Objective-C牛逼) – adamdehaven 2012-07-23 15:48:43

+0

我只需要知道該怎麼把這個:' - (無效)webView的:*的NSTimer {theTimer NSLog的 (@ 「我在這裏以1個分鐘的延遲」); }' 像我會使用哪種目標方法? – adamdehaven 2012-07-23 15:58:52

回答

40

的timeoutInterval用於連接。一旦webview連接到URL,您需要啓動NSTimer並執行您自己的超時處理。喜歡的東西:

// 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

我添加了上面的方法,但它在20秒後什麼都不做? - 我在'cancelWeb'屬性中放入了一個UIAlertView,但它永遠不會觸發。 – adamdehaven 2012-07-23 16:14:31

+1

對不起一個更改,不是'NSTimer timerWithTimeInterval',而是'scheduledTimerWithTimeInterval'。一旦你的webView連接到URL,'webViewDidStartLoad'將被調用。如果沒有,您沒有正確設置委託。然後該方法啓動計時器在20秒內調用'cancelWeb'方法。 – mask8 2012-07-23 16:21:43

+0

非常感謝!完美的作品:) 還有一個問題 - 如果他們退出「viewWillDisappear」或「viewDidUnload」中的應用程序,是否需要做任何事情來釋放計時器? – adamdehaven 2012-07-23 16:25:18

3

我的方式類似於公認的答案,但只是stopLoading時超時和控制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

這是更好的答案,因爲它實際上超時後停止Web視圖。我也建議在你讓它失效並且完成後把'self.timer'設置爲'nil'。 – rmaddy 2017-05-02 23:30:58

2

斯威夫特程序員可以做到這一點如下:

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

所有建議的解決方案是不理想的。處理這種情況的正確方法是使用NSMutableURLRequest本身的timeoutInterval:

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

request.timeoutInterval = 10; 

[webview loadRequest:request]; 
+0

這是正確的解決方案! – ElectroBuddha 2017-07-06 13:54:44

+0

超時後會調用'didFailToLoad withError'嗎? – 2018-02-19 03:13:48

+1

@AlbertRenshaw是的,它會自動調用委託方法 – 2018-02-19 03:31:11