我正嘗試創建一個基於UIWebView
的應用程序。其主要目的是爲使用NTLM或基本身份驗證的少數網站提供身份驗證,而用戶在更改密碼(網站共享用戶/密碼數據庫)時不必輸入每個網站的用戶名/密碼。當從NSURLConnectionDataDelegate設置內容時,UIWebView重新加載baseUrl
爲了做到這一點,我「覆蓋」爲UIWebView
加載頁面數據,以便我可以截獲HTTP響應代碼,並在每次檢測到響應時詢問用戶密碼。
我已經建立了一個NSURLConnectionDataDelegate
來處理請求這樣:
@interface LPURLConnectionDelegate : NSObject<NSURLConnectionDataDelegate>
{
UIWebView* _webView;
NSMutableURLRequest* _request;
NSURLConnection* _connection;
NSString* _encoding;
NSString* _mimeType;
NSMutableData* _data;
}
- (LPURLConnectionDelegate*) initWithWebView:(UIWebView *)webView;
- (void) loadPageWithRequest: (NSURLRequest*)request;
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection;
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
@end
@implementation LPURLConnectionDelegate
- (void) loadPageWithRequest: (NSURLRequest*)request
{
_request = [request mutableCopy];
if(!_data)
{
_data = [NSMutableData dataWithCapacity:0];
[_data retain];
}
[_data setLength:0];
if(_connection)
{
[_connection cancel];
[_connection release];
_connection = nil;
}
_connection = [[NSURLConnection alloc] initWithRequest:_request delegate:self startImmediately:YES];
}
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
LPAppDelegate* delegate = [LPAppDelegate getInstance];
NSURLCredential* credential = [NSURLCredential credentialWithUser:[delegate getUsername] password:[delegate getPassword] persistence:NSURLCredentialPersistenceForSession];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
//handle connection failed
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(@"Connection did receive response");
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
_mimeType = [httpResponse MIMEType];
_encoding = [httpResponse textEncodingName];
//handle status - if the status is 401, the connection is canceled and the user is asked for his new password
}
- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection
{
return YES;
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[_data appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[_webView loadData:_data MIMEType:_mimeType textEncodingName:_encoding baseURL:[_request URL]];
}
@end
我UIWebViewDelegate
看起來是這樣的:
@interface LPWebViewDelegate : NSObject<UIWebViewDelegate>
- (void)webViewDidStartLoad:(UIWebView *)webView;
- (void)webViewDidFinishLoad:(UIWebView *)webView;
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error;
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
@end
@implementation LPWebViewDelegate
- (void) webViewDidStartLoad:(UIWebView *)webView
{
}
- (void) webViewDidFinishLoad:(UIWebView *)webView
{
//handle success
}
- (BOOL) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
LPURLConnectionDelegate* connectionDelegate = [[LPURLConnectionDelegate alloc] initWithWebView:webView];
[connectionDelegate loadPageWithRequest:request];
return NO;
}
- (void) webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
//handle fail
}
@end
基本上,我想要做的是告訴UIWebView
不要自行加載任何頁面,讓我處理加載頁面的請求。當請求完成並且用戶通過身份驗證時,我試圖使用UIWebView::loadData:MIMEType:textEncodingName:baseUrl
方法設置數據。
的這裏的問題是,從NSURLConnectionDataDelegate
設置UIWebView
的數據後,UIWebView
重新加載頁面設置爲baseURL
(至少在模擬器 - 我還沒有嘗試在實際設備上的代碼,只是還沒有)。
有沒有人知道一種方式來設置數據到UIWebView
s以這樣的方式,它不會重新加載頁面(*)?我知道我可以讓UIWebView
在NSURLConnection
檢查身份驗證(或並行)之後加載頁面,但我試圖避免爲每個頁面請求頁面標題兩次。
注意:代碼不完整,我已經提取了我認爲是該問題最相關的部分。