1. 程式人生 > >關於使用UIWebView載入HTTPS站點出現NSURLErrorDomain code=-1202

關於使用UIWebView載入HTTPS站點出現NSURLErrorDomain code=-1202

最近在做push 資訊到facebook中。當使用UIWebview載入https的站點時webview總是會報NSURLErrorDomain code=-1202,導致網頁載入失敗。自己列印錯誤和網上搜索是因為證書失效,https使用超文字安全傳輸協議,即超文字傳輸協議(HTTP)和SSL/TLS的組合用以提供加密通訊及對網路伺服器身份的鑑定。當我們的伺服器使用自我簽名證書時,而UIWebView不允許使用自簽名證書,所以導致載入失敗。我們可以使用NSURLConnection通過它的代理canAuthenticateAgainstProtectionSpace可以允許這種情況,從而通過它進行認證。

#import <UIKit/UIKit.h>

#import "MyObject.h"

@interface ViewController :UIViewController<UIWebViewDelegate,NSURLConnectionDelegate>

{

UIWebView *_web;

NSURLConnection *_urlConnection;

NSURLRequest *_request;

BOOL _authenticated;

}

@end


@interfaceViewController ()

@end

@implementation

ViewController

@synthesize myobject;

- (void)viewDidLoad

{

    [superviewDidLoad];

_web = [[UIWebViewalloc] initWithFrame:CGRectMake(0,0,768,1024)];

_web.delegate =self;

_web.autoresizingMask =UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight;

    [self.viewaddSubview:_web];

NSURL* _loadingURL =[

NSURLURLWithString:@"https://m.facebook.com/dialog/feed?link=http%3A%2F%2Fwww.facebook.com%2FeNGage.OnePub&description=Werwr4w532545245&access_token=BAAC117qbwhQBAFtqiZAmWH8hOtkJLOcC0OTgmYJxX5IybPlPp2ozoZBewaJXBtOagJ5bJItZCZBJ8o8Sal0c52Tt4h2XbPf2f5osEo1ZB2lQh0hF969zeOpoPu1BsS5Hgtr00U55gYb7ZABsvcFohG&caption=Page%201&name=eNGage&picture=http%3A%2F%2Fc1345842.cdn.cloudfiles.rackspacecloud.com%2Fassets%2Fapps%2Ficons%2F001%2F002%2F707%2Foriginal.png%3F1324531970&actions=%5B%7B%22name%22%3A%22Find%20out%20more%20about%20eNGage%22%2C%22link%22%3A%22http%3A%2F%2Fwww.facebook.com%2FeNGage.OnePub%22%7D%5D&app_id=199938153366036&redirect_uri=fbconnect%3A%2F%2Fsuccess&sdk=2&display=touch"];

//_loadingURL=[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[_loadingURL host]];

_request = [NSMutableURLRequestrequestWithURL:_loadingURL];

    [_webloadRequest:_request];

// Do any additional setup after loading the view, typically from a nib.

//        UIImageView *uimage=[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"image27.png"]];

//    [self.view addSubview:uimage];

//    MyObject *object=[[MyObject alloc]init];

//    MyObject *object1=[object retain];

//self.myobject=object;

//myobject = object;

//NSLog(@"******retainCount:%d",[myobject retainCount]);

//NSLog(@"******self.retainCount:%d",[self.myobject retainCount]);

//[object release];

}

- (void)didReceiveMemoryWarning

{

    [superdidReceiveMemoryWarning];

// Dispose of any resources that can be recreated.

}

#pragma mark - Webview delegate

// Note: This method is particularly important. As the server is using a self signed certificate,

// we cannot use just UIWebView - as it doesn't allow for using self-certs. Instead, we stop the

// request in this method below, create an NSURLConnection (which can allow self-certs via the delegate methods

// which UIWebView does not have), authenticate using NSURLConnection, then use another UIWebView to complete

// the loading and viewing of the page. See connection:didReceiveAuthenticationChallenge to see how this works.

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;

{

NSLog(@"Did start loading: %@ auth:%d", [[requestURL]absoluteString],_authenticated);

if (!_authenticated) {

_authenticated =NO;

_urlConnection = [[NSURLConnectionalloc] initWithRequest:_requestdelegate:self];

        [_urlConnectionstart];

returnNO;

    }

returnYES;

}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {

// 102 == WebKitErrorFrameLoadInterruptedByPolicyChange

NSLog(@"***********error:%@,errorcode=%d,errormessage:%@",error.domain,error.code,error.description);

if (!([error.domainisEqualToString:@"WebKitErrorDomain"] && error.code ==102)) {

//[self dismissWithError:error animated:YES];

    }

}

#pragma mark - NURLConnection delegate

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;

{

NSLog(@"WebController Got auth challange via NSURLConnection");

if ([challengepreviousFailureCount] ==0)

    {

_authenticated =YES;

NSURLCredential *credential = [NSURLCredentialcredentialForTrust:challenge.protectionSpace.serverTrust];

        [challenge.senderuseCredential:credentialforAuthenticationChallenge:challenge];

    } else

    {

        [[challenge sender]cancelAuthenticationChallenge:challenge];

    }

}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;

{

NSLog(@"WebController received response via NSURLConnection");

// remake a webview call now that authentication has passed ok.

_authenticated =YES;

    [_webloadRequest:_request];

// Cancel the URL connection otherwise we double up (webview + url connection, same url = no good!)

    [_urlConnectioncancel];

}

// We use this method is to accept an untrusted site which unfortunately we need to do, as our PVM servers are self signed.

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace

{

return [protectionSpace.authenticationMethodisEqualToString:NSURLAuthenticationMethodServerTrust];

}

@end