APP中調(diào)用網(wǎng)頁的情況很多,常規(guī)情況下不需要我們考慮任何處理,直接加載即可??墒枪δ苄枰^為嚴(yán)格的時(shí)候,就需要前端的你設(shè)置準(zhǔn)確的處理,以達(dá)到更好的用戶體驗(yàn)。尤其是需要判斷狀態(tài)碼的時(shí)候,需要注意了。
獲取statusCode的正確姿勢(shì)
一般情況下正常加載網(wǎng)頁返回的statusCode都是200,當(dāng)然,也會(huì)有404、400之類的情況,但是有一點(diǎn)要注意了,返回404這種狀態(tài)碼的時(shí)候,UIWebView的回調(diào)方法- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error;是不會(huì)走的,因?yàn)閣eb成功load的,只是服務(wù)端返回錯(cuò)誤碼而已。因此要注意,需要通過單獨(dú)的方法而不是通過UIWebView的回調(diào)方法來獲取statusCode,通過查閱資料,網(wǎng)上大多數(shù)的方法都是通過:
[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil]; NSLog(@"statusCode:%ld", response.statusCode);
來獲取response的狀態(tài)碼,可是筆者經(jīng)過反復(fù)測(cè)試得不到正確結(jié)果,查看源碼發(fā)現(xiàn)在iOS9之后此方法已經(jīng)廢棄,官方解釋:
"Use [NSURLSession dataTaskWithRequest:completionHandler:] (see NSURLSession.h"
所以,別說了,棄之。
來看看最新的方法:
NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError *_Nullable error) { NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response; NSLog(@"statusCode:%ld", httpResponse.statusCode); }]; [dataTask resume];
當(dāng)然了,該方法是放在[_webView loadRequest:request];之前,還是放在UIWebView的回調(diào)方法中,根據(jù)實(shí)際需要就行。
其實(shí),如果你在用三方AFNetworking,并且經(jīng)歷過2.0到3.0的更新,那么你會(huì)發(fā)現(xiàn)它也是在這方面進(jìn)行了大變革。
不同狀態(tài)碼的前端處理
statusCode已經(jīng)獲取到了,后期處理就簡(jiǎn)單了。
呵呵。
有時(shí)候,當(dāng)網(wǎng)頁的statusCode為類似404時(shí),我們并不希望只顯示“404 not found”。例如,筆者在加載網(wǎng)頁時(shí)都是需要在請(qǐng)求頭中添加參數(shù)token,如果token不對(duì),后臺(tái)會(huì)給我返回401,意思是登錄失效,需要重新登錄。此時(shí)則需要彈出登錄框之類的刷新UI動(dòng)作。
if (httpResponse.statusCode == 401) { // 彈出登錄框 }
當(dāng)statusCode=401時(shí),網(wǎng)頁加載半天,彈出登錄框的方法也已經(jīng)走了,不過彈出框直到最后才彈出。
經(jīng)過反復(fù)測(cè)試,筆者才發(fā)現(xiàn)問題,原來在block中的刷新UI在這種情況下是需要把該方法添加到主線程中的,加載速度恢復(fù),貼上代碼:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { // 獲取返回的狀態(tài)嗎 NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError *_Nullable error) { NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response; NSLog(@"statusCode:%ld", httpResponse.statusCode); if (httpResponse.statusCode == 401) { dispatch_sync(dispatch_get_main_queue(), ^{ // 彈出登錄框 }); }); } }]; [dataTask resume]; return YES; }