从NSURLConnectionDataDelegate设置内容时,UIWebView重新加载baseUrl

时间:2014-01-10 08:15:43

标签: ios uiwebview nsurlconnection

我正在尝试创建一个基于UIWebView的应用程序。其主要目的是使用NTLM或基本身份验证为少数网站提供身份验证,而无需用户在更改密码时为每个网站输入用户名/密码(网站共享用户/密码数据库)。

为了做到这一点,我“覆盖”加载UIWebView的页面数据,这样我就可以拦截HTTP响应代码并在每次检测到{时都要求用户输入密码{1}}回复。

我已设置401 Unauthorized来处理请求:

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的{​​{1}}数据后,UIWebView会将页面集重新加载为NSURLConnectionDataDelegate(至少在模拟器中 - 我还没有尝试过实际设备上的代码。

是否有人知道如何将数据设置为UIWebView以便不重新加载页面(*)?

*)我知道在baseURL检查身份验证(或并行)之后我可以让UIWebView加载页面,但我试图避免请求页面每页标题两次。

注意:代码不完整,我已经提取了我认为是此问题最相关的部分。

1 个答案:

答案 0 :(得分:1)

实施NSURLProtocol课程。它本质上是一个抽象类,允许子类定义HTTP方案的URL加载行为

查看本教程here