UIWebView to view self signed websites (No private api, not NSURLConnection) - is it possible?Ignoring Invalid Server Certificates with UIWebViewUIWebView The certificate for this server is invalidUsing openssl to get the certificate from a serverAllow unverified ssl certificate in UIWebviewSwitching from http to https. Invalid certificateBypass kCFStreamErrorDomainSSL error for self-signed certificates on iOS 7in UiWebView - NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -108)Loading HTTPS in UIWebViewCall iOS webview HTTPS (self-signed certificate)Need to view website with a self-signed certificate and http authenticationHow to load a webpage (Https using a self signed certificate) on the UIWebView?Need to view website with a self-signed certificate and http authenticationUIWebView not loading https linkjavascript not working in UIWebview's button onsubmit where as safari works fine?Xamarin way to open self signed certificate webpage in UIWebViewAllow unverified ssl certificates in WKWebViewHow to call https url in uiwebview (swift)?Load self signed https url using UIWebview and NSURLSessionHow to load an URL in UIWebView with self-signed certificate?Swift 3: UIWebView connecting to a HTTPS server using a self-signed certificate

Will LSST make a significant increase in the rate of astronomical event alerts?

Should I leave my PhD after 3 years with a Masters?

How do campaign rallies gain candidates votes?

Character Frequency in a String

How may I shorten this shell script?

What is the difference between $path and $PATH (lowercase versus uppercase) with zsh?

How did C64 games handle music during gameplay?

Book with a female main character living in a convent who has to fight gods

Using "Kollege" as "university friend"?

What is the meaning of "you has the wind of me"?

Grid/table with lots of buttons

Can GPL and BSD licensed applications be used for government work?

Does static fire reduce reliability?

How can I receive packages while in France?

Is two-person D&D feasible for any edition?

Area of parallelogram = Area of square. Shear transform

How do I run a game when my PCs have different approaches to combat?

How important is a good quality camera for good photography?

How can I stop myself from micromanaging other PCs' actions?

What is "ass door"?

What exactly makes a General Products hull nearly indestructible?

"I you already know": is this proper English?

High income, sudden windfall

What to do when you reach a conclusion and find out later on that someone else already did?



UIWebView to view self signed websites (No private api, not NSURLConnection) - is it possible?


Ignoring Invalid Server Certificates with UIWebViewUIWebView The certificate for this server is invalidUsing openssl to get the certificate from a serverAllow unverified ssl certificate in UIWebviewSwitching from http to https. Invalid certificateBypass kCFStreamErrorDomainSSL error for self-signed certificates on iOS 7in UiWebView - NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -108)Loading HTTPS in UIWebViewCall iOS webview HTTPS (self-signed certificate)Need to view website with a self-signed certificate and http authenticationHow to load a webpage (Https using a self signed certificate) on the UIWebView?Need to view website with a self-signed certificate and http authenticationUIWebView not loading https linkjavascript not working in UIWebview's button onsubmit where as safari works fine?Xamarin way to open self signed certificate webpage in UIWebViewAllow unverified ssl certificates in WKWebViewHow to call https url in uiwebview (swift)?Load self signed https url using UIWebview and NSURLSessionHow to load an URL in UIWebView with self-signed certificate?Swift 3: UIWebView connecting to a HTTPS server using a self-signed certificate






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








49















There's a load of questions which ask this: Can I get UIWebView to view a self signed HTTPS website?



And the answers always involve either:



  1. Use the private api call for NSURLRequest: allowsAnyHTTPSCertificateForHost

  2. Use NSURLConnection instead and the delegate canAuthenticateAgainstProtectionSpace etc

For me, these won't do.
(1) - means I can't submit to the app store successfully.
(2) - using NSURLConnection means the CSS, images and other things that have to be fetched from the server after receiving the initial HTML page do not load.



Does anyone know how to use UIWebView to view a self-signed https webpage please, which does not involve the two methods above?



Or - If using NSURLConnection can in fact be used to render a webpage complete with CSS, images and everything else - that would be great!



Cheers,

Stretch.










share|improve this question
























  • stackoverflow.com/questions/16783416/… Dest url is http://web.hnair.nethow can i fixed.

    – Eric
    May 28 '13 at 3:56











  • Why use SSL in production code when the certificate in question is invalid - I seem to miss the point.

    – Till
    May 31 '13 at 0:05






  • 6





    Enterprise software containing an SSL web interface is deployed at a customer site on an internal network - it is not possible to get a certificate for these websites, they have to be self signed.

    – Stretch
    May 31 '13 at 5:14


















49















There's a load of questions which ask this: Can I get UIWebView to view a self signed HTTPS website?



And the answers always involve either:



  1. Use the private api call for NSURLRequest: allowsAnyHTTPSCertificateForHost

  2. Use NSURLConnection instead and the delegate canAuthenticateAgainstProtectionSpace etc

For me, these won't do.
(1) - means I can't submit to the app store successfully.
(2) - using NSURLConnection means the CSS, images and other things that have to be fetched from the server after receiving the initial HTML page do not load.



Does anyone know how to use UIWebView to view a self-signed https webpage please, which does not involve the two methods above?



Or - If using NSURLConnection can in fact be used to render a webpage complete with CSS, images and everything else - that would be great!



Cheers,

Stretch.










share|improve this question
























  • stackoverflow.com/questions/16783416/… Dest url is http://web.hnair.nethow can i fixed.

    – Eric
    May 28 '13 at 3:56











  • Why use SSL in production code when the certificate in question is invalid - I seem to miss the point.

    – Till
    May 31 '13 at 0:05






  • 6





    Enterprise software containing an SSL web interface is deployed at a customer site on an internal network - it is not possible to get a certificate for these websites, they have to be self signed.

    – Stretch
    May 31 '13 at 5:14














49












49








49


45






There's a load of questions which ask this: Can I get UIWebView to view a self signed HTTPS website?



And the answers always involve either:



  1. Use the private api call for NSURLRequest: allowsAnyHTTPSCertificateForHost

  2. Use NSURLConnection instead and the delegate canAuthenticateAgainstProtectionSpace etc

For me, these won't do.
(1) - means I can't submit to the app store successfully.
(2) - using NSURLConnection means the CSS, images and other things that have to be fetched from the server after receiving the initial HTML page do not load.



Does anyone know how to use UIWebView to view a self-signed https webpage please, which does not involve the two methods above?



Or - If using NSURLConnection can in fact be used to render a webpage complete with CSS, images and everything else - that would be great!



Cheers,

Stretch.










share|improve this question
















There's a load of questions which ask this: Can I get UIWebView to view a self signed HTTPS website?



And the answers always involve either:



  1. Use the private api call for NSURLRequest: allowsAnyHTTPSCertificateForHost

  2. Use NSURLConnection instead and the delegate canAuthenticateAgainstProtectionSpace etc

For me, these won't do.
(1) - means I can't submit to the app store successfully.
(2) - using NSURLConnection means the CSS, images and other things that have to be fetched from the server after receiving the initial HTML page do not load.



Does anyone know how to use UIWebView to view a self-signed https webpage please, which does not involve the two methods above?



Or - If using NSURLConnection can in fact be used to render a webpage complete with CSS, images and everything else - that would be great!



Cheers,

Stretch.







iphone ios uiwebview






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jul 20 '12 at 6:14







Stretch

















asked Jul 20 '12 at 5:03









StretchStretch

2,5941 gold badge19 silver badges36 bronze badges




2,5941 gold badge19 silver badges36 bronze badges












  • stackoverflow.com/questions/16783416/… Dest url is http://web.hnair.nethow can i fixed.

    – Eric
    May 28 '13 at 3:56











  • Why use SSL in production code when the certificate in question is invalid - I seem to miss the point.

    – Till
    May 31 '13 at 0:05






  • 6





    Enterprise software containing an SSL web interface is deployed at a customer site on an internal network - it is not possible to get a certificate for these websites, they have to be self signed.

    – Stretch
    May 31 '13 at 5:14


















  • stackoverflow.com/questions/16783416/… Dest url is http://web.hnair.nethow can i fixed.

    – Eric
    May 28 '13 at 3:56











  • Why use SSL in production code when the certificate in question is invalid - I seem to miss the point.

    – Till
    May 31 '13 at 0:05






  • 6





    Enterprise software containing an SSL web interface is deployed at a customer site on an internal network - it is not possible to get a certificate for these websites, they have to be self signed.

    – Stretch
    May 31 '13 at 5:14

















stackoverflow.com/questions/16783416/… Dest url is http://web.hnair.nethow can i fixed.

– Eric
May 28 '13 at 3:56





stackoverflow.com/questions/16783416/… Dest url is http://web.hnair.nethow can i fixed.

– Eric
May 28 '13 at 3:56













Why use SSL in production code when the certificate in question is invalid - I seem to miss the point.

– Till
May 31 '13 at 0:05





Why use SSL in production code when the certificate in question is invalid - I seem to miss the point.

– Till
May 31 '13 at 0:05




6




6





Enterprise software containing an SSL web interface is deployed at a customer site on an internal network - it is not possible to get a certificate for these websites, they have to be self signed.

– Stretch
May 31 '13 at 5:14






Enterprise software containing an SSL web interface is deployed at a customer site on an internal network - it is not possible to get a certificate for these websites, they have to be self signed.

– Stretch
May 31 '13 at 5:14













9 Answers
9






active

oldest

votes


















76














Finally I got it!



What you can do is this:



Initiate your request using UIWebView as normal. Then - in webView:shouldStartLoadWithRequest - we reply NO, and instead start an NSURLConnection with the same request.



Using NSURLConnection, you can communicate with a self-signed server, as we have the ability to control the authentication through the extra delegate methods which are not available to a UIWebView. So using connection:didReceiveAuthenticationChallenge we can authenticate against the self signed server.



Then, in connection:didReceiveData, we cancel the NSURLConnection request, and start the same request again using UIWebView - which will work now, because we've already got through the server authentication :)



Here are the relevant code snippets below.



Note: Instance variables you will see are of the following type:
UIWebView *_web
NSURLConnection *_urlConnection
NSURLRequest *_request



(I use an instance var for _request as in my case it's a POST with lots of login details, but you could change to use the request passed in as arguments to the methods if you needed.)



#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", [[request URL] absoluteString], _authenticated);

if (!_authenticated)
_authenticated = NO;

_urlConnection = [[NSURLConnection alloc] initWithRequest:_request delegate:self];

[_urlConnection start];

return NO;


return YES;



#pragma mark - NURLConnection delegate

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

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

if ([challenge previousFailureCount] == 0)

_authenticated = YES;

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

[challenge.sender useCredential:credential forAuthenticationChallenge: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;
[_web loadRequest:_request];

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


// 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.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];



I hope this helps others with the same issue I was having!






share|improve this answer


















  • 1





    Nice one, +1. But what about the other resources (css, javascript fetching data)?

    – lawicko
    Jul 26 '12 at 9:02











  • ah - well, that's the beauty of UIWebView - it does all that for you. The NSURLConnection won't automatically fetch from embedded links etc - however here it is only used now to get past the authentication (then we cancel the NSURLConnection), then a new UIWebViewRequest is created to handle everything else :)

    – Stretch
    Jul 26 '12 at 22:44







  • 1





    Other answers might be more up to date, but voting this up for excellent explanation.

    – zambrey
    May 22 '15 at 23:43






  • 1





    No chance this gets rewritten into swift...

    – Kevrone
    Sep 22 '15 at 13:47






  • 1





    @Kevrone see my answer below

    – spirographer
    Oct 8 '15 at 1:22


















65














Stretch's answer appears to be a great workaround, but it uses deprecated APIs. So, I thought it might be worthy of an upgrade to the code.



For this code sample, I added the routines to the ViewController which contains my UIWebView. I made my UIViewController a UIWebViewDelegate and a NSURLConnectionDataDelegate. Then I added 2 data members: _Authenticated and _FailedRequest. With that, the code looks like this:



-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 
BOOL result = _Authenticated;
if (!_Authenticated)
_FailedRequest = request;
[[NSURLConnection alloc] initWithRequest:request delegate:self];

return result;


-(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
NSURL* baseURL = [_FailedRequest URL];
if ([challenge.protectionSpace.host isEqualToString:baseURL.host])
NSLog(@"trusting connection to host %@", challenge.protectionSpace.host);
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
else
NSLog(@"Not trusting connection to host %@", challenge.protectionSpace.host);

[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];


-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)pResponse
_Authenticated = YES;
[connection cancel];
[_WebView loadRequest:_FailedRequest];



I set _Authenticated to NO when I load the view and don't reset it. This seems to allow the UIWebView to make multiple requests to the same site. I did not try switching sites and trying to come back. That may cause the need for resetting _Authenticated. Also, if you are switching sites, you should keep a dictionary (one entry for each host) for _Authenticated instead of a BOOL.






share|improve this answer




















  • 2





    good work, thanks for that :)

    – Stretch
    Feb 25 '13 at 23:14






  • 2





    Theres a typo in your code baseURL should be: [_FailedRequest URL]

    – João Nunes
    Mar 16 '13 at 11:54






  • 4





    This works but sometimes it just fails. It's pretty weird. All those delegate method is called just like when it works, but I got "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “mysite.com” which could put your confidential information at risk." I used NSURLConnection +sendAsynchronousRequest:queue:completionHandler: method.

    – Hlung
    Sep 5 '13 at 7:49







  • 1





    @Darren, if you have a way to monitor the network traffic, look for a CRL download. There is a good chance that it is checking for a revoked certificate and the download is timing out.

    – Prof Von Lemongargle
    Sep 28 '14 at 4:09







  • 1





    @LuongHuyDuc initWithRequest docs: Returns an initialized URL connection and begins to load the data for the URL request. This is equivalent to calling initWithRequest:delegate:startImmediately: and passing YES for startImmediately.

    – earnshavian
    Aug 11 '15 at 15:47



















16














This is the Panacea!




BOOL _Authenticated;
NSURLRequest *_FailedRequest;

#pragma UIWebViewDelegate

-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
BOOL result = _Authenticated;
if (!_Authenticated)
_FailedRequest = request;
NSURLConnection *urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[urlConnection start];

return result;


#pragma NSURLConnectionDelegate

-(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
NSURL* baseURL = [NSURL URLWithString:@"your url"];
if ([challenge.protectionSpace.host isEqualToString:baseURL.host])
NSLog(@"trusting connection to host %@", challenge.protectionSpace.host);
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
else
NSLog(@"Not trusting connection to host %@", challenge.protectionSpace.host);

[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];


-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)pResponse
_Authenticated = YES;
[connection cancel];
[self.webView loadRequest:_FailedRequest];


- (void)viewDidLoad
[super viewDidLoad];

NSURL *url = [NSURL URLWithString:@"your url"];
NSURLRequest *requestURL = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:requestURL];

// Do any additional setup after loading the view.






share|improve this answer




















  • 2





    You should change your NSURL* baseURL = [NSURL URLWithString:@"your url"]; to NSURL* baseURL = [_FailedRequest URL]; in willSendRequestForAuthenticationChallenge to allow any url at all, not just the original url that was loaded.

    – Brad Parks
    Jun 26 '15 at 12:47












  • @Wilson Aguiar does this code can deploy to App Store? thanks

    – dianyi
    Apr 19 '17 at 1:10


















7














If you want to access a private server with a self-signed certificate just for testing you don't have to write code. You can manually do a system-wide import of the certificate.



To do this, you need to download the server certificate with mobile safari, which then prompts for an import.



This would be usable under the following circumstances:



  • the number of test devices is small

  • you're trusting the certificate of the server

If you don't have access to the server certificate, you can fallback to the following method for extracting it from any HTTPS-server (at least on Linux/Mac, windows guys will have to download an OpenSSL binary somewhere):



echo "" | openssl s_client -connect $server:$port -prexit 2>/dev/null | sed -n -e '/BEGIN CERTIFICATE/,/END CERTIFICATE/ p' >server.pem


Note, that depending on the OpenSSL version, the certificate may be doubled in the file, so best have a look at it with a text editor. Put the file somewhere on the network or use the



python -m SimpleHTTPServer 8000



shortcut to access it from your mobile safari at http://$your_device_ip:8000/server.pem.






share|improve this answer




















  • 2





    this should be the accepted answer

    – nexuzzz
    May 15 '15 at 16:24











  • This is hardly something a user of your app should be expected to do.

    – Scenario
    Feb 28 '17 at 19:06


















4














This is a clever workaround. However, a possibly better (although more code intensive) solution would be to use an NSURLProtocol as demonstrated in Apple's CustomHTTPProtocol sample code. From the README:



"CustomHTTPProtocol shows how to use an NSURLProtocol subclass to intercept the NSURLConnections made by a high-level subsystem that does not otherwise expose its network connections. In this specific case, it intercepts the HTTPS requests made by a web view and overrides server trust evaluation, allowing you to browse a site whose certificate is not trusted by default."



Checkout the full example:
https://developer.apple.com/library/ios/samplecode/CustomHTTPProtocol/Introduction/Intro.html






share|improve this answer























  • That's cool, but it breaks 302 redirects in the web view.

    – davidgoli
    Feb 27 '14 at 1:09











  • And it involves a thousand lines of code. Really, Apple? You can't even give us a Swift 3 sample?

    – Scenario
    Feb 28 '17 at 19:05



















3














This is a swift 2.0 compatible equivalent that works for me. I have not converted this code to use NSURLSession instead of NSURLConnection, and suspect that it would add a lot of complexity to get it right.



var authRequest : NSURLRequest? = nil
var authenticated = false
var trustedDomains = [:] // set up as necessary

func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool
if !authenticated
authRequest = request
let urlConnection: NSURLConnection = NSURLConnection(request: request, delegate: self)!
urlConnection.start()
return false

else if isWebContent(request.URL!) // write your method for this
return true

return processData(request) // write your method for this


func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge)
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust
let challengeHost = challenge.protectionSpace.host
if let _ = trustedDomains[challengeHost]
challenge.sender!.useCredential(NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!), forAuthenticationChallenge: challenge)


challenge.sender!.continueWithoutCredentialForAuthenticationChallenge(challenge)


func connection(connection: NSURLConnection, didReceiveResponse response: NSURLResponse)
authenticated = true
connection.cancel()
webview!.loadRequest(authRequest!)






share|improve this answer























  • still not getting data every time prints "NSURLConnection finished with error - code -1202 , TIC SSL Trust Error [30:0x1c036c600]: 3:0 , NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813) , Task <DC36F3A2-F4EC-4928-9D94-098AA09A8DC5>.<0> HTTP load failed (error code: -1202

    – krishan kumar
    Nov 10 '18 at 5:45



















2














Here the working code of swift 2.0



var authRequest : NSURLRequest? = nil
var authenticated = false


func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool
if !authenticated
authRequest = request
let urlConnection: NSURLConnection = NSURLConnection(request: request, delegate: self)!
urlConnection.start()
return false

return true


func connection(connection: NSURLConnection, didReceiveResponse response: NSURLResponse)
authenticated = true
connection.cancel()
webView!.loadRequest(authRequest!)


func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge)

let host = "www.example.com"

if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust &&
challenge.protectionSpace.host == host
let credential = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!)
challenge.sender!.useCredential(credential, forAuthenticationChallenge: challenge)
else
challenge.sender!.performDefaultHandlingForAuthenticationChallenge!(challenge)







share|improve this answer






























    1














    To build off of @spirographer's answer, I put something together for a Swift 2.0 use case with NSURLSession. However, this is still NOT working. See more below.



    func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool 
    let result = _Authenticated
    if !result
    let sessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
    let session = NSURLSession(configuration: sessionConfiguration, delegate: self, delegateQueue: NSOperationQueue.mainQueue())
    let task = session.dataTaskWithRequest(request)
    (data, response, error) -> Void in
    if error == nil
    if (!self._Authenticated)
    self._Authenticated = true;
    let pageData = NSString(data: data!, encoding: NSUTF8StringEncoding)
    self.webView.loadHTMLString(pageData as! String, baseURL: request.URL!)

    else
    self.webView.loadRequest(request)



    task.resume()
    return false

    return result


    func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void)
    completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!))



    I will get back the initial HTML response, so the page renders the plain HTML, but there is no CSS styles applied to it (seems like the request to get CSS is denied). I see a bunch of these errors:



    NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)


    It seems like any request made with webView.loadRequest is done not within the session, which is why the connection is rejected. I do have Allow Arbitrary Loads set in Info.plist. What confuses me is why NSURLConnection would work (seemingly the same idea), but not NSURLSession.






    share|improve this answer

























    • You should not be posting code with var names like "_Authenticated".

      – Scenario
      Feb 28 '17 at 19:09











    • @Scenario Why's that?

      – Tri Nguyen
      Mar 1 '17 at 18:46


















    0














    First thing UIWebView is deprecated



    use WKWebView instead (available from iOS8)



    set webView.navigationDelegate = self



    implement



    extension ViewController: WKNavigationDelegate 

    func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
    let trust = challenge.protectionSpace.serverTrust!
    let exceptions = SecTrustCopyExceptions(trust)
    SecTrustSetExceptions(trust, exceptions)
    completionHandler(.useCredential, URLCredential(trust: trust))





    And add this in plist with domains you want to allow



    <key>NSAppTransportSecurity</key>
    <dict>
    <key>NSExceptionDomains</key>
    <dict>
    <key>localhost</key>
    <dict>
    <key>NSTemporaryExceptionAllowsInsecureHTTPSLoads</key>
    <false/>
    <key>NSIncludesSubdomains</key>
    <true/>
    <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
    <true/>
    <key>NSTemporaryExceptionMinimumTLSVersion</key>
    <string>1.0</string>
    <key>NSTemporaryExceptionRequiresForwardSecrecy</key>
    <false/>
    </dict>
    </dict>
    </dict>





    share|improve this answer

























      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "1"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f11573164%2fuiwebview-to-view-self-signed-websites-no-private-api-not-nsurlconnection-i%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      9 Answers
      9






      active

      oldest

      votes








      9 Answers
      9






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      76














      Finally I got it!



      What you can do is this:



      Initiate your request using UIWebView as normal. Then - in webView:shouldStartLoadWithRequest - we reply NO, and instead start an NSURLConnection with the same request.



      Using NSURLConnection, you can communicate with a self-signed server, as we have the ability to control the authentication through the extra delegate methods which are not available to a UIWebView. So using connection:didReceiveAuthenticationChallenge we can authenticate against the self signed server.



      Then, in connection:didReceiveData, we cancel the NSURLConnection request, and start the same request again using UIWebView - which will work now, because we've already got through the server authentication :)



      Here are the relevant code snippets below.



      Note: Instance variables you will see are of the following type:
      UIWebView *_web
      NSURLConnection *_urlConnection
      NSURLRequest *_request



      (I use an instance var for _request as in my case it's a POST with lots of login details, but you could change to use the request passed in as arguments to the methods if you needed.)



      #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", [[request URL] absoluteString], _authenticated);

      if (!_authenticated)
      _authenticated = NO;

      _urlConnection = [[NSURLConnection alloc] initWithRequest:_request delegate:self];

      [_urlConnection start];

      return NO;


      return YES;



      #pragma mark - NURLConnection delegate

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

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

      if ([challenge previousFailureCount] == 0)

      _authenticated = YES;

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

      [challenge.sender useCredential:credential forAuthenticationChallenge: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;
      [_web loadRequest:_request];

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


      // 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.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];



      I hope this helps others with the same issue I was having!






      share|improve this answer


















      • 1





        Nice one, +1. But what about the other resources (css, javascript fetching data)?

        – lawicko
        Jul 26 '12 at 9:02











      • ah - well, that's the beauty of UIWebView - it does all that for you. The NSURLConnection won't automatically fetch from embedded links etc - however here it is only used now to get past the authentication (then we cancel the NSURLConnection), then a new UIWebViewRequest is created to handle everything else :)

        – Stretch
        Jul 26 '12 at 22:44







      • 1





        Other answers might be more up to date, but voting this up for excellent explanation.

        – zambrey
        May 22 '15 at 23:43






      • 1





        No chance this gets rewritten into swift...

        – Kevrone
        Sep 22 '15 at 13:47






      • 1





        @Kevrone see my answer below

        – spirographer
        Oct 8 '15 at 1:22















      76














      Finally I got it!



      What you can do is this:



      Initiate your request using UIWebView as normal. Then - in webView:shouldStartLoadWithRequest - we reply NO, and instead start an NSURLConnection with the same request.



      Using NSURLConnection, you can communicate with a self-signed server, as we have the ability to control the authentication through the extra delegate methods which are not available to a UIWebView. So using connection:didReceiveAuthenticationChallenge we can authenticate against the self signed server.



      Then, in connection:didReceiveData, we cancel the NSURLConnection request, and start the same request again using UIWebView - which will work now, because we've already got through the server authentication :)



      Here are the relevant code snippets below.



      Note: Instance variables you will see are of the following type:
      UIWebView *_web
      NSURLConnection *_urlConnection
      NSURLRequest *_request



      (I use an instance var for _request as in my case it's a POST with lots of login details, but you could change to use the request passed in as arguments to the methods if you needed.)



      #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", [[request URL] absoluteString], _authenticated);

      if (!_authenticated)
      _authenticated = NO;

      _urlConnection = [[NSURLConnection alloc] initWithRequest:_request delegate:self];

      [_urlConnection start];

      return NO;


      return YES;



      #pragma mark - NURLConnection delegate

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

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

      if ([challenge previousFailureCount] == 0)

      _authenticated = YES;

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

      [challenge.sender useCredential:credential forAuthenticationChallenge: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;
      [_web loadRequest:_request];

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


      // 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.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];



      I hope this helps others with the same issue I was having!






      share|improve this answer


















      • 1





        Nice one, +1. But what about the other resources (css, javascript fetching data)?

        – lawicko
        Jul 26 '12 at 9:02











      • ah - well, that's the beauty of UIWebView - it does all that for you. The NSURLConnection won't automatically fetch from embedded links etc - however here it is only used now to get past the authentication (then we cancel the NSURLConnection), then a new UIWebViewRequest is created to handle everything else :)

        – Stretch
        Jul 26 '12 at 22:44







      • 1





        Other answers might be more up to date, but voting this up for excellent explanation.

        – zambrey
        May 22 '15 at 23:43






      • 1





        No chance this gets rewritten into swift...

        – Kevrone
        Sep 22 '15 at 13:47






      • 1





        @Kevrone see my answer below

        – spirographer
        Oct 8 '15 at 1:22













      76












      76








      76







      Finally I got it!



      What you can do is this:



      Initiate your request using UIWebView as normal. Then - in webView:shouldStartLoadWithRequest - we reply NO, and instead start an NSURLConnection with the same request.



      Using NSURLConnection, you can communicate with a self-signed server, as we have the ability to control the authentication through the extra delegate methods which are not available to a UIWebView. So using connection:didReceiveAuthenticationChallenge we can authenticate against the self signed server.



      Then, in connection:didReceiveData, we cancel the NSURLConnection request, and start the same request again using UIWebView - which will work now, because we've already got through the server authentication :)



      Here are the relevant code snippets below.



      Note: Instance variables you will see are of the following type:
      UIWebView *_web
      NSURLConnection *_urlConnection
      NSURLRequest *_request



      (I use an instance var for _request as in my case it's a POST with lots of login details, but you could change to use the request passed in as arguments to the methods if you needed.)



      #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", [[request URL] absoluteString], _authenticated);

      if (!_authenticated)
      _authenticated = NO;

      _urlConnection = [[NSURLConnection alloc] initWithRequest:_request delegate:self];

      [_urlConnection start];

      return NO;


      return YES;



      #pragma mark - NURLConnection delegate

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

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

      if ([challenge previousFailureCount] == 0)

      _authenticated = YES;

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

      [challenge.sender useCredential:credential forAuthenticationChallenge: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;
      [_web loadRequest:_request];

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


      // 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.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];



      I hope this helps others with the same issue I was having!






      share|improve this answer













      Finally I got it!



      What you can do is this:



      Initiate your request using UIWebView as normal. Then - in webView:shouldStartLoadWithRequest - we reply NO, and instead start an NSURLConnection with the same request.



      Using NSURLConnection, you can communicate with a self-signed server, as we have the ability to control the authentication through the extra delegate methods which are not available to a UIWebView. So using connection:didReceiveAuthenticationChallenge we can authenticate against the self signed server.



      Then, in connection:didReceiveData, we cancel the NSURLConnection request, and start the same request again using UIWebView - which will work now, because we've already got through the server authentication :)



      Here are the relevant code snippets below.



      Note: Instance variables you will see are of the following type:
      UIWebView *_web
      NSURLConnection *_urlConnection
      NSURLRequest *_request



      (I use an instance var for _request as in my case it's a POST with lots of login details, but you could change to use the request passed in as arguments to the methods if you needed.)



      #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", [[request URL] absoluteString], _authenticated);

      if (!_authenticated)
      _authenticated = NO;

      _urlConnection = [[NSURLConnection alloc] initWithRequest:_request delegate:self];

      [_urlConnection start];

      return NO;


      return YES;



      #pragma mark - NURLConnection delegate

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

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

      if ([challenge previousFailureCount] == 0)

      _authenticated = YES;

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

      [challenge.sender useCredential:credential forAuthenticationChallenge: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;
      [_web loadRequest:_request];

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


      // 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.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];



      I hope this helps others with the same issue I was having!







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Jul 26 '12 at 7:06









      StretchStretch

      2,5941 gold badge19 silver badges36 bronze badges




      2,5941 gold badge19 silver badges36 bronze badges







      • 1





        Nice one, +1. But what about the other resources (css, javascript fetching data)?

        – lawicko
        Jul 26 '12 at 9:02











      • ah - well, that's the beauty of UIWebView - it does all that for you. The NSURLConnection won't automatically fetch from embedded links etc - however here it is only used now to get past the authentication (then we cancel the NSURLConnection), then a new UIWebViewRequest is created to handle everything else :)

        – Stretch
        Jul 26 '12 at 22:44







      • 1





        Other answers might be more up to date, but voting this up for excellent explanation.

        – zambrey
        May 22 '15 at 23:43






      • 1





        No chance this gets rewritten into swift...

        – Kevrone
        Sep 22 '15 at 13:47






      • 1





        @Kevrone see my answer below

        – spirographer
        Oct 8 '15 at 1:22












      • 1





        Nice one, +1. But what about the other resources (css, javascript fetching data)?

        – lawicko
        Jul 26 '12 at 9:02











      • ah - well, that's the beauty of UIWebView - it does all that for you. The NSURLConnection won't automatically fetch from embedded links etc - however here it is only used now to get past the authentication (then we cancel the NSURLConnection), then a new UIWebViewRequest is created to handle everything else :)

        – Stretch
        Jul 26 '12 at 22:44







      • 1





        Other answers might be more up to date, but voting this up for excellent explanation.

        – zambrey
        May 22 '15 at 23:43






      • 1





        No chance this gets rewritten into swift...

        – Kevrone
        Sep 22 '15 at 13:47






      • 1





        @Kevrone see my answer below

        – spirographer
        Oct 8 '15 at 1:22







      1




      1





      Nice one, +1. But what about the other resources (css, javascript fetching data)?

      – lawicko
      Jul 26 '12 at 9:02





      Nice one, +1. But what about the other resources (css, javascript fetching data)?

      – lawicko
      Jul 26 '12 at 9:02













      ah - well, that's the beauty of UIWebView - it does all that for you. The NSURLConnection won't automatically fetch from embedded links etc - however here it is only used now to get past the authentication (then we cancel the NSURLConnection), then a new UIWebViewRequest is created to handle everything else :)

      – Stretch
      Jul 26 '12 at 22:44






      ah - well, that's the beauty of UIWebView - it does all that for you. The NSURLConnection won't automatically fetch from embedded links etc - however here it is only used now to get past the authentication (then we cancel the NSURLConnection), then a new UIWebViewRequest is created to handle everything else :)

      – Stretch
      Jul 26 '12 at 22:44





      1




      1





      Other answers might be more up to date, but voting this up for excellent explanation.

      – zambrey
      May 22 '15 at 23:43





      Other answers might be more up to date, but voting this up for excellent explanation.

      – zambrey
      May 22 '15 at 23:43




      1




      1





      No chance this gets rewritten into swift...

      – Kevrone
      Sep 22 '15 at 13:47





      No chance this gets rewritten into swift...

      – Kevrone
      Sep 22 '15 at 13:47




      1




      1





      @Kevrone see my answer below

      – spirographer
      Oct 8 '15 at 1:22





      @Kevrone see my answer below

      – spirographer
      Oct 8 '15 at 1:22













      65














      Stretch's answer appears to be a great workaround, but it uses deprecated APIs. So, I thought it might be worthy of an upgrade to the code.



      For this code sample, I added the routines to the ViewController which contains my UIWebView. I made my UIViewController a UIWebViewDelegate and a NSURLConnectionDataDelegate. Then I added 2 data members: _Authenticated and _FailedRequest. With that, the code looks like this:



      -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 
      BOOL result = _Authenticated;
      if (!_Authenticated)
      _FailedRequest = request;
      [[NSURLConnection alloc] initWithRequest:request delegate:self];

      return result;


      -(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
      if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
      NSURL* baseURL = [_FailedRequest URL];
      if ([challenge.protectionSpace.host isEqualToString:baseURL.host])
      NSLog(@"trusting connection to host %@", challenge.protectionSpace.host);
      [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
      else
      NSLog(@"Not trusting connection to host %@", challenge.protectionSpace.host);

      [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];


      -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)pResponse
      _Authenticated = YES;
      [connection cancel];
      [_WebView loadRequest:_FailedRequest];



      I set _Authenticated to NO when I load the view and don't reset it. This seems to allow the UIWebView to make multiple requests to the same site. I did not try switching sites and trying to come back. That may cause the need for resetting _Authenticated. Also, if you are switching sites, you should keep a dictionary (one entry for each host) for _Authenticated instead of a BOOL.






      share|improve this answer




















      • 2





        good work, thanks for that :)

        – Stretch
        Feb 25 '13 at 23:14






      • 2





        Theres a typo in your code baseURL should be: [_FailedRequest URL]

        – João Nunes
        Mar 16 '13 at 11:54






      • 4





        This works but sometimes it just fails. It's pretty weird. All those delegate method is called just like when it works, but I got "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “mysite.com” which could put your confidential information at risk." I used NSURLConnection +sendAsynchronousRequest:queue:completionHandler: method.

        – Hlung
        Sep 5 '13 at 7:49







      • 1





        @Darren, if you have a way to monitor the network traffic, look for a CRL download. There is a good chance that it is checking for a revoked certificate and the download is timing out.

        – Prof Von Lemongargle
        Sep 28 '14 at 4:09







      • 1





        @LuongHuyDuc initWithRequest docs: Returns an initialized URL connection and begins to load the data for the URL request. This is equivalent to calling initWithRequest:delegate:startImmediately: and passing YES for startImmediately.

        – earnshavian
        Aug 11 '15 at 15:47
















      65














      Stretch's answer appears to be a great workaround, but it uses deprecated APIs. So, I thought it might be worthy of an upgrade to the code.



      For this code sample, I added the routines to the ViewController which contains my UIWebView. I made my UIViewController a UIWebViewDelegate and a NSURLConnectionDataDelegate. Then I added 2 data members: _Authenticated and _FailedRequest. With that, the code looks like this:



      -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 
      BOOL result = _Authenticated;
      if (!_Authenticated)
      _FailedRequest = request;
      [[NSURLConnection alloc] initWithRequest:request delegate:self];

      return result;


      -(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
      if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
      NSURL* baseURL = [_FailedRequest URL];
      if ([challenge.protectionSpace.host isEqualToString:baseURL.host])
      NSLog(@"trusting connection to host %@", challenge.protectionSpace.host);
      [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
      else
      NSLog(@"Not trusting connection to host %@", challenge.protectionSpace.host);

      [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];


      -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)pResponse
      _Authenticated = YES;
      [connection cancel];
      [_WebView loadRequest:_FailedRequest];



      I set _Authenticated to NO when I load the view and don't reset it. This seems to allow the UIWebView to make multiple requests to the same site. I did not try switching sites and trying to come back. That may cause the need for resetting _Authenticated. Also, if you are switching sites, you should keep a dictionary (one entry for each host) for _Authenticated instead of a BOOL.






      share|improve this answer




















      • 2





        good work, thanks for that :)

        – Stretch
        Feb 25 '13 at 23:14






      • 2





        Theres a typo in your code baseURL should be: [_FailedRequest URL]

        – João Nunes
        Mar 16 '13 at 11:54






      • 4





        This works but sometimes it just fails. It's pretty weird. All those delegate method is called just like when it works, but I got "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “mysite.com” which could put your confidential information at risk." I used NSURLConnection +sendAsynchronousRequest:queue:completionHandler: method.

        – Hlung
        Sep 5 '13 at 7:49







      • 1





        @Darren, if you have a way to monitor the network traffic, look for a CRL download. There is a good chance that it is checking for a revoked certificate and the download is timing out.

        – Prof Von Lemongargle
        Sep 28 '14 at 4:09







      • 1





        @LuongHuyDuc initWithRequest docs: Returns an initialized URL connection and begins to load the data for the URL request. This is equivalent to calling initWithRequest:delegate:startImmediately: and passing YES for startImmediately.

        – earnshavian
        Aug 11 '15 at 15:47














      65












      65








      65







      Stretch's answer appears to be a great workaround, but it uses deprecated APIs. So, I thought it might be worthy of an upgrade to the code.



      For this code sample, I added the routines to the ViewController which contains my UIWebView. I made my UIViewController a UIWebViewDelegate and a NSURLConnectionDataDelegate. Then I added 2 data members: _Authenticated and _FailedRequest. With that, the code looks like this:



      -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 
      BOOL result = _Authenticated;
      if (!_Authenticated)
      _FailedRequest = request;
      [[NSURLConnection alloc] initWithRequest:request delegate:self];

      return result;


      -(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
      if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
      NSURL* baseURL = [_FailedRequest URL];
      if ([challenge.protectionSpace.host isEqualToString:baseURL.host])
      NSLog(@"trusting connection to host %@", challenge.protectionSpace.host);
      [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
      else
      NSLog(@"Not trusting connection to host %@", challenge.protectionSpace.host);

      [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];


      -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)pResponse
      _Authenticated = YES;
      [connection cancel];
      [_WebView loadRequest:_FailedRequest];



      I set _Authenticated to NO when I load the view and don't reset it. This seems to allow the UIWebView to make multiple requests to the same site. I did not try switching sites and trying to come back. That may cause the need for resetting _Authenticated. Also, if you are switching sites, you should keep a dictionary (one entry for each host) for _Authenticated instead of a BOOL.






      share|improve this answer















      Stretch's answer appears to be a great workaround, but it uses deprecated APIs. So, I thought it might be worthy of an upgrade to the code.



      For this code sample, I added the routines to the ViewController which contains my UIWebView. I made my UIViewController a UIWebViewDelegate and a NSURLConnectionDataDelegate. Then I added 2 data members: _Authenticated and _FailedRequest. With that, the code looks like this:



      -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 
      BOOL result = _Authenticated;
      if (!_Authenticated)
      _FailedRequest = request;
      [[NSURLConnection alloc] initWithRequest:request delegate:self];

      return result;


      -(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
      if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
      NSURL* baseURL = [_FailedRequest URL];
      if ([challenge.protectionSpace.host isEqualToString:baseURL.host])
      NSLog(@"trusting connection to host %@", challenge.protectionSpace.host);
      [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
      else
      NSLog(@"Not trusting connection to host %@", challenge.protectionSpace.host);

      [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];


      -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)pResponse
      _Authenticated = YES;
      [connection cancel];
      [_WebView loadRequest:_FailedRequest];



      I set _Authenticated to NO when I load the view and don't reset it. This seems to allow the UIWebView to make multiple requests to the same site. I did not try switching sites and trying to come back. That may cause the need for resetting _Authenticated. Also, if you are switching sites, you should keep a dictionary (one entry for each host) for _Authenticated instead of a BOOL.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Jun 22 '17 at 8:02









      GeneCode

      5,7676 gold badges35 silver badges66 bronze badges




      5,7676 gold badges35 silver badges66 bronze badges










      answered Feb 25 '13 at 18:59









      Prof Von LemongargleProf Von Lemongargle

      3,21524 silver badges24 bronze badges




      3,21524 silver badges24 bronze badges







      • 2





        good work, thanks for that :)

        – Stretch
        Feb 25 '13 at 23:14






      • 2





        Theres a typo in your code baseURL should be: [_FailedRequest URL]

        – João Nunes
        Mar 16 '13 at 11:54






      • 4





        This works but sometimes it just fails. It's pretty weird. All those delegate method is called just like when it works, but I got "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “mysite.com” which could put your confidential information at risk." I used NSURLConnection +sendAsynchronousRequest:queue:completionHandler: method.

        – Hlung
        Sep 5 '13 at 7:49







      • 1





        @Darren, if you have a way to monitor the network traffic, look for a CRL download. There is a good chance that it is checking for a revoked certificate and the download is timing out.

        – Prof Von Lemongargle
        Sep 28 '14 at 4:09







      • 1





        @LuongHuyDuc initWithRequest docs: Returns an initialized URL connection and begins to load the data for the URL request. This is equivalent to calling initWithRequest:delegate:startImmediately: and passing YES for startImmediately.

        – earnshavian
        Aug 11 '15 at 15:47













      • 2





        good work, thanks for that :)

        – Stretch
        Feb 25 '13 at 23:14






      • 2





        Theres a typo in your code baseURL should be: [_FailedRequest URL]

        – João Nunes
        Mar 16 '13 at 11:54






      • 4





        This works but sometimes it just fails. It's pretty weird. All those delegate method is called just like when it works, but I got "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “mysite.com” which could put your confidential information at risk." I used NSURLConnection +sendAsynchronousRequest:queue:completionHandler: method.

        – Hlung
        Sep 5 '13 at 7:49







      • 1





        @Darren, if you have a way to monitor the network traffic, look for a CRL download. There is a good chance that it is checking for a revoked certificate and the download is timing out.

        – Prof Von Lemongargle
        Sep 28 '14 at 4:09







      • 1





        @LuongHuyDuc initWithRequest docs: Returns an initialized URL connection and begins to load the data for the URL request. This is equivalent to calling initWithRequest:delegate:startImmediately: and passing YES for startImmediately.

        – earnshavian
        Aug 11 '15 at 15:47








      2




      2





      good work, thanks for that :)

      – Stretch
      Feb 25 '13 at 23:14





      good work, thanks for that :)

      – Stretch
      Feb 25 '13 at 23:14




      2




      2





      Theres a typo in your code baseURL should be: [_FailedRequest URL]

      – João Nunes
      Mar 16 '13 at 11:54





      Theres a typo in your code baseURL should be: [_FailedRequest URL]

      – João Nunes
      Mar 16 '13 at 11:54




      4




      4





      This works but sometimes it just fails. It's pretty weird. All those delegate method is called just like when it works, but I got "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “mysite.com” which could put your confidential information at risk." I used NSURLConnection +sendAsynchronousRequest:queue:completionHandler: method.

      – Hlung
      Sep 5 '13 at 7:49






      This works but sometimes it just fails. It's pretty weird. All those delegate method is called just like when it works, but I got "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “mysite.com” which could put your confidential information at risk." I used NSURLConnection +sendAsynchronousRequest:queue:completionHandler: method.

      – Hlung
      Sep 5 '13 at 7:49





      1




      1





      @Darren, if you have a way to monitor the network traffic, look for a CRL download. There is a good chance that it is checking for a revoked certificate and the download is timing out.

      – Prof Von Lemongargle
      Sep 28 '14 at 4:09






      @Darren, if you have a way to monitor the network traffic, look for a CRL download. There is a good chance that it is checking for a revoked certificate and the download is timing out.

      – Prof Von Lemongargle
      Sep 28 '14 at 4:09





      1




      1





      @LuongHuyDuc initWithRequest docs: Returns an initialized URL connection and begins to load the data for the URL request. This is equivalent to calling initWithRequest:delegate:startImmediately: and passing YES for startImmediately.

      – earnshavian
      Aug 11 '15 at 15:47






      @LuongHuyDuc initWithRequest docs: Returns an initialized URL connection and begins to load the data for the URL request. This is equivalent to calling initWithRequest:delegate:startImmediately: and passing YES for startImmediately.

      – earnshavian
      Aug 11 '15 at 15:47












      16














      This is the Panacea!




      BOOL _Authenticated;
      NSURLRequest *_FailedRequest;

      #pragma UIWebViewDelegate

      -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
      BOOL result = _Authenticated;
      if (!_Authenticated)
      _FailedRequest = request;
      NSURLConnection *urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
      [urlConnection start];

      return result;


      #pragma NSURLConnectionDelegate

      -(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
      if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
      NSURL* baseURL = [NSURL URLWithString:@"your url"];
      if ([challenge.protectionSpace.host isEqualToString:baseURL.host])
      NSLog(@"trusting connection to host %@", challenge.protectionSpace.host);
      [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
      else
      NSLog(@"Not trusting connection to host %@", challenge.protectionSpace.host);

      [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];


      -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)pResponse
      _Authenticated = YES;
      [connection cancel];
      [self.webView loadRequest:_FailedRequest];


      - (void)viewDidLoad
      [super viewDidLoad];

      NSURL *url = [NSURL URLWithString:@"your url"];
      NSURLRequest *requestURL = [NSURLRequest requestWithURL:url];
      [self.webView loadRequest:requestURL];

      // Do any additional setup after loading the view.






      share|improve this answer




















      • 2





        You should change your NSURL* baseURL = [NSURL URLWithString:@"your url"]; to NSURL* baseURL = [_FailedRequest URL]; in willSendRequestForAuthenticationChallenge to allow any url at all, not just the original url that was loaded.

        – Brad Parks
        Jun 26 '15 at 12:47












      • @Wilson Aguiar does this code can deploy to App Store? thanks

        – dianyi
        Apr 19 '17 at 1:10















      16














      This is the Panacea!




      BOOL _Authenticated;
      NSURLRequest *_FailedRequest;

      #pragma UIWebViewDelegate

      -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
      BOOL result = _Authenticated;
      if (!_Authenticated)
      _FailedRequest = request;
      NSURLConnection *urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
      [urlConnection start];

      return result;


      #pragma NSURLConnectionDelegate

      -(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
      if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
      NSURL* baseURL = [NSURL URLWithString:@"your url"];
      if ([challenge.protectionSpace.host isEqualToString:baseURL.host])
      NSLog(@"trusting connection to host %@", challenge.protectionSpace.host);
      [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
      else
      NSLog(@"Not trusting connection to host %@", challenge.protectionSpace.host);

      [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];


      -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)pResponse
      _Authenticated = YES;
      [connection cancel];
      [self.webView loadRequest:_FailedRequest];


      - (void)viewDidLoad
      [super viewDidLoad];

      NSURL *url = [NSURL URLWithString:@"your url"];
      NSURLRequest *requestURL = [NSURLRequest requestWithURL:url];
      [self.webView loadRequest:requestURL];

      // Do any additional setup after loading the view.






      share|improve this answer




















      • 2





        You should change your NSURL* baseURL = [NSURL URLWithString:@"your url"]; to NSURL* baseURL = [_FailedRequest URL]; in willSendRequestForAuthenticationChallenge to allow any url at all, not just the original url that was loaded.

        – Brad Parks
        Jun 26 '15 at 12:47












      • @Wilson Aguiar does this code can deploy to App Store? thanks

        – dianyi
        Apr 19 '17 at 1:10













      16












      16








      16







      This is the Panacea!




      BOOL _Authenticated;
      NSURLRequest *_FailedRequest;

      #pragma UIWebViewDelegate

      -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
      BOOL result = _Authenticated;
      if (!_Authenticated)
      _FailedRequest = request;
      NSURLConnection *urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
      [urlConnection start];

      return result;


      #pragma NSURLConnectionDelegate

      -(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
      if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
      NSURL* baseURL = [NSURL URLWithString:@"your url"];
      if ([challenge.protectionSpace.host isEqualToString:baseURL.host])
      NSLog(@"trusting connection to host %@", challenge.protectionSpace.host);
      [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
      else
      NSLog(@"Not trusting connection to host %@", challenge.protectionSpace.host);

      [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];


      -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)pResponse
      _Authenticated = YES;
      [connection cancel];
      [self.webView loadRequest:_FailedRequest];


      - (void)viewDidLoad
      [super viewDidLoad];

      NSURL *url = [NSURL URLWithString:@"your url"];
      NSURLRequest *requestURL = [NSURLRequest requestWithURL:url];
      [self.webView loadRequest:requestURL];

      // Do any additional setup after loading the view.






      share|improve this answer















      This is the Panacea!




      BOOL _Authenticated;
      NSURLRequest *_FailedRequest;

      #pragma UIWebViewDelegate

      -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
      BOOL result = _Authenticated;
      if (!_Authenticated)
      _FailedRequest = request;
      NSURLConnection *urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
      [urlConnection start];

      return result;


      #pragma NSURLConnectionDelegate

      -(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
      if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
      NSURL* baseURL = [NSURL URLWithString:@"your url"];
      if ([challenge.protectionSpace.host isEqualToString:baseURL.host])
      NSLog(@"trusting connection to host %@", challenge.protectionSpace.host);
      [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
      else
      NSLog(@"Not trusting connection to host %@", challenge.protectionSpace.host);

      [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];


      -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)pResponse
      _Authenticated = YES;
      [connection cancel];
      [self.webView loadRequest:_FailedRequest];


      - (void)viewDidLoad
      [super viewDidLoad];

      NSURL *url = [NSURL URLWithString:@"your url"];
      NSURLRequest *requestURL = [NSURLRequest requestWithURL:url];
      [self.webView loadRequest:requestURL];

      // Do any additional setup after loading the view.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Feb 12 '14 at 14:55









      phemt.latd

      1,67818 silver badges31 bronze badges




      1,67818 silver badges31 bronze badges










      answered Feb 12 '14 at 14:28









      Wilson AguiarWilson Aguiar

      2013 silver badges3 bronze badges




      2013 silver badges3 bronze badges







      • 2





        You should change your NSURL* baseURL = [NSURL URLWithString:@"your url"]; to NSURL* baseURL = [_FailedRequest URL]; in willSendRequestForAuthenticationChallenge to allow any url at all, not just the original url that was loaded.

        – Brad Parks
        Jun 26 '15 at 12:47












      • @Wilson Aguiar does this code can deploy to App Store? thanks

        – dianyi
        Apr 19 '17 at 1:10












      • 2





        You should change your NSURL* baseURL = [NSURL URLWithString:@"your url"]; to NSURL* baseURL = [_FailedRequest URL]; in willSendRequestForAuthenticationChallenge to allow any url at all, not just the original url that was loaded.

        – Brad Parks
        Jun 26 '15 at 12:47












      • @Wilson Aguiar does this code can deploy to App Store? thanks

        – dianyi
        Apr 19 '17 at 1:10







      2




      2





      You should change your NSURL* baseURL = [NSURL URLWithString:@"your url"]; to NSURL* baseURL = [_FailedRequest URL]; in willSendRequestForAuthenticationChallenge to allow any url at all, not just the original url that was loaded.

      – Brad Parks
      Jun 26 '15 at 12:47






      You should change your NSURL* baseURL = [NSURL URLWithString:@"your url"]; to NSURL* baseURL = [_FailedRequest URL]; in willSendRequestForAuthenticationChallenge to allow any url at all, not just the original url that was loaded.

      – Brad Parks
      Jun 26 '15 at 12:47














      @Wilson Aguiar does this code can deploy to App Store? thanks

      – dianyi
      Apr 19 '17 at 1:10





      @Wilson Aguiar does this code can deploy to App Store? thanks

      – dianyi
      Apr 19 '17 at 1:10











      7














      If you want to access a private server with a self-signed certificate just for testing you don't have to write code. You can manually do a system-wide import of the certificate.



      To do this, you need to download the server certificate with mobile safari, which then prompts for an import.



      This would be usable under the following circumstances:



      • the number of test devices is small

      • you're trusting the certificate of the server

      If you don't have access to the server certificate, you can fallback to the following method for extracting it from any HTTPS-server (at least on Linux/Mac, windows guys will have to download an OpenSSL binary somewhere):



      echo "" | openssl s_client -connect $server:$port -prexit 2>/dev/null | sed -n -e '/BEGIN CERTIFICATE/,/END CERTIFICATE/ p' >server.pem


      Note, that depending on the OpenSSL version, the certificate may be doubled in the file, so best have a look at it with a text editor. Put the file somewhere on the network or use the



      python -m SimpleHTTPServer 8000



      shortcut to access it from your mobile safari at http://$your_device_ip:8000/server.pem.






      share|improve this answer




















      • 2





        this should be the accepted answer

        – nexuzzz
        May 15 '15 at 16:24











      • This is hardly something a user of your app should be expected to do.

        – Scenario
        Feb 28 '17 at 19:06















      7














      If you want to access a private server with a self-signed certificate just for testing you don't have to write code. You can manually do a system-wide import of the certificate.



      To do this, you need to download the server certificate with mobile safari, which then prompts for an import.



      This would be usable under the following circumstances:



      • the number of test devices is small

      • you're trusting the certificate of the server

      If you don't have access to the server certificate, you can fallback to the following method for extracting it from any HTTPS-server (at least on Linux/Mac, windows guys will have to download an OpenSSL binary somewhere):



      echo "" | openssl s_client -connect $server:$port -prexit 2>/dev/null | sed -n -e '/BEGIN CERTIFICATE/,/END CERTIFICATE/ p' >server.pem


      Note, that depending on the OpenSSL version, the certificate may be doubled in the file, so best have a look at it with a text editor. Put the file somewhere on the network or use the



      python -m SimpleHTTPServer 8000



      shortcut to access it from your mobile safari at http://$your_device_ip:8000/server.pem.






      share|improve this answer




















      • 2





        this should be the accepted answer

        – nexuzzz
        May 15 '15 at 16:24











      • This is hardly something a user of your app should be expected to do.

        – Scenario
        Feb 28 '17 at 19:06













      7












      7








      7







      If you want to access a private server with a self-signed certificate just for testing you don't have to write code. You can manually do a system-wide import of the certificate.



      To do this, you need to download the server certificate with mobile safari, which then prompts for an import.



      This would be usable under the following circumstances:



      • the number of test devices is small

      • you're trusting the certificate of the server

      If you don't have access to the server certificate, you can fallback to the following method for extracting it from any HTTPS-server (at least on Linux/Mac, windows guys will have to download an OpenSSL binary somewhere):



      echo "" | openssl s_client -connect $server:$port -prexit 2>/dev/null | sed -n -e '/BEGIN CERTIFICATE/,/END CERTIFICATE/ p' >server.pem


      Note, that depending on the OpenSSL version, the certificate may be doubled in the file, so best have a look at it with a text editor. Put the file somewhere on the network or use the



      python -m SimpleHTTPServer 8000



      shortcut to access it from your mobile safari at http://$your_device_ip:8000/server.pem.






      share|improve this answer















      If you want to access a private server with a self-signed certificate just for testing you don't have to write code. You can manually do a system-wide import of the certificate.



      To do this, you need to download the server certificate with mobile safari, which then prompts for an import.



      This would be usable under the following circumstances:



      • the number of test devices is small

      • you're trusting the certificate of the server

      If you don't have access to the server certificate, you can fallback to the following method for extracting it from any HTTPS-server (at least on Linux/Mac, windows guys will have to download an OpenSSL binary somewhere):



      echo "" | openssl s_client -connect $server:$port -prexit 2>/dev/null | sed -n -e '/BEGIN CERTIFICATE/,/END CERTIFICATE/ p' >server.pem


      Note, that depending on the OpenSSL version, the certificate may be doubled in the file, so best have a look at it with a text editor. Put the file somewhere on the network or use the



      python -m SimpleHTTPServer 8000



      shortcut to access it from your mobile safari at http://$your_device_ip:8000/server.pem.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited May 23 '17 at 11:47









      Community

      11 silver badge




      11 silver badge










      answered Oct 18 '14 at 10:14









      zliwzliw

      4766 silver badges10 bronze badges




      4766 silver badges10 bronze badges







      • 2





        this should be the accepted answer

        – nexuzzz
        May 15 '15 at 16:24











      • This is hardly something a user of your app should be expected to do.

        – Scenario
        Feb 28 '17 at 19:06












      • 2





        this should be the accepted answer

        – nexuzzz
        May 15 '15 at 16:24











      • This is hardly something a user of your app should be expected to do.

        – Scenario
        Feb 28 '17 at 19:06







      2




      2





      this should be the accepted answer

      – nexuzzz
      May 15 '15 at 16:24





      this should be the accepted answer

      – nexuzzz
      May 15 '15 at 16:24













      This is hardly something a user of your app should be expected to do.

      – Scenario
      Feb 28 '17 at 19:06





      This is hardly something a user of your app should be expected to do.

      – Scenario
      Feb 28 '17 at 19:06











      4














      This is a clever workaround. However, a possibly better (although more code intensive) solution would be to use an NSURLProtocol as demonstrated in Apple's CustomHTTPProtocol sample code. From the README:



      "CustomHTTPProtocol shows how to use an NSURLProtocol subclass to intercept the NSURLConnections made by a high-level subsystem that does not otherwise expose its network connections. In this specific case, it intercepts the HTTPS requests made by a web view and overrides server trust evaluation, allowing you to browse a site whose certificate is not trusted by default."



      Checkout the full example:
      https://developer.apple.com/library/ios/samplecode/CustomHTTPProtocol/Introduction/Intro.html






      share|improve this answer























      • That's cool, but it breaks 302 redirects in the web view.

        – davidgoli
        Feb 27 '14 at 1:09











      • And it involves a thousand lines of code. Really, Apple? You can't even give us a Swift 3 sample?

        – Scenario
        Feb 28 '17 at 19:05
















      4














      This is a clever workaround. However, a possibly better (although more code intensive) solution would be to use an NSURLProtocol as demonstrated in Apple's CustomHTTPProtocol sample code. From the README:



      "CustomHTTPProtocol shows how to use an NSURLProtocol subclass to intercept the NSURLConnections made by a high-level subsystem that does not otherwise expose its network connections. In this specific case, it intercepts the HTTPS requests made by a web view and overrides server trust evaluation, allowing you to browse a site whose certificate is not trusted by default."



      Checkout the full example:
      https://developer.apple.com/library/ios/samplecode/CustomHTTPProtocol/Introduction/Intro.html






      share|improve this answer























      • That's cool, but it breaks 302 redirects in the web view.

        – davidgoli
        Feb 27 '14 at 1:09











      • And it involves a thousand lines of code. Really, Apple? You can't even give us a Swift 3 sample?

        – Scenario
        Feb 28 '17 at 19:05














      4












      4








      4







      This is a clever workaround. However, a possibly better (although more code intensive) solution would be to use an NSURLProtocol as demonstrated in Apple's CustomHTTPProtocol sample code. From the README:



      "CustomHTTPProtocol shows how to use an NSURLProtocol subclass to intercept the NSURLConnections made by a high-level subsystem that does not otherwise expose its network connections. In this specific case, it intercepts the HTTPS requests made by a web view and overrides server trust evaluation, allowing you to browse a site whose certificate is not trusted by default."



      Checkout the full example:
      https://developer.apple.com/library/ios/samplecode/CustomHTTPProtocol/Introduction/Intro.html






      share|improve this answer













      This is a clever workaround. However, a possibly better (although more code intensive) solution would be to use an NSURLProtocol as demonstrated in Apple's CustomHTTPProtocol sample code. From the README:



      "CustomHTTPProtocol shows how to use an NSURLProtocol subclass to intercept the NSURLConnections made by a high-level subsystem that does not otherwise expose its network connections. In this specific case, it intercepts the HTTPS requests made by a web view and overrides server trust evaluation, allowing you to browse a site whose certificate is not trusted by default."



      Checkout the full example:
      https://developer.apple.com/library/ios/samplecode/CustomHTTPProtocol/Introduction/Intro.html







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Dec 2 '13 at 19:07









      AlexAlex

      411 bronze badge




      411 bronze badge












      • That's cool, but it breaks 302 redirects in the web view.

        – davidgoli
        Feb 27 '14 at 1:09











      • And it involves a thousand lines of code. Really, Apple? You can't even give us a Swift 3 sample?

        – Scenario
        Feb 28 '17 at 19:05


















      • That's cool, but it breaks 302 redirects in the web view.

        – davidgoli
        Feb 27 '14 at 1:09











      • And it involves a thousand lines of code. Really, Apple? You can't even give us a Swift 3 sample?

        – Scenario
        Feb 28 '17 at 19:05

















      That's cool, but it breaks 302 redirects in the web view.

      – davidgoli
      Feb 27 '14 at 1:09





      That's cool, but it breaks 302 redirects in the web view.

      – davidgoli
      Feb 27 '14 at 1:09













      And it involves a thousand lines of code. Really, Apple? You can't even give us a Swift 3 sample?

      – Scenario
      Feb 28 '17 at 19:05






      And it involves a thousand lines of code. Really, Apple? You can't even give us a Swift 3 sample?

      – Scenario
      Feb 28 '17 at 19:05












      3














      This is a swift 2.0 compatible equivalent that works for me. I have not converted this code to use NSURLSession instead of NSURLConnection, and suspect that it would add a lot of complexity to get it right.



      var authRequest : NSURLRequest? = nil
      var authenticated = false
      var trustedDomains = [:] // set up as necessary

      func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool
      if !authenticated
      authRequest = request
      let urlConnection: NSURLConnection = NSURLConnection(request: request, delegate: self)!
      urlConnection.start()
      return false

      else if isWebContent(request.URL!) // write your method for this
      return true

      return processData(request) // write your method for this


      func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge)
      if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust
      let challengeHost = challenge.protectionSpace.host
      if let _ = trustedDomains[challengeHost]
      challenge.sender!.useCredential(NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!), forAuthenticationChallenge: challenge)


      challenge.sender!.continueWithoutCredentialForAuthenticationChallenge(challenge)


      func connection(connection: NSURLConnection, didReceiveResponse response: NSURLResponse)
      authenticated = true
      connection.cancel()
      webview!.loadRequest(authRequest!)






      share|improve this answer























      • still not getting data every time prints "NSURLConnection finished with error - code -1202 , TIC SSL Trust Error [30:0x1c036c600]: 3:0 , NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813) , Task <DC36F3A2-F4EC-4928-9D94-098AA09A8DC5>.<0> HTTP load failed (error code: -1202

        – krishan kumar
        Nov 10 '18 at 5:45
















      3














      This is a swift 2.0 compatible equivalent that works for me. I have not converted this code to use NSURLSession instead of NSURLConnection, and suspect that it would add a lot of complexity to get it right.



      var authRequest : NSURLRequest? = nil
      var authenticated = false
      var trustedDomains = [:] // set up as necessary

      func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool
      if !authenticated
      authRequest = request
      let urlConnection: NSURLConnection = NSURLConnection(request: request, delegate: self)!
      urlConnection.start()
      return false

      else if isWebContent(request.URL!) // write your method for this
      return true

      return processData(request) // write your method for this


      func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge)
      if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust
      let challengeHost = challenge.protectionSpace.host
      if let _ = trustedDomains[challengeHost]
      challenge.sender!.useCredential(NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!), forAuthenticationChallenge: challenge)


      challenge.sender!.continueWithoutCredentialForAuthenticationChallenge(challenge)


      func connection(connection: NSURLConnection, didReceiveResponse response: NSURLResponse)
      authenticated = true
      connection.cancel()
      webview!.loadRequest(authRequest!)






      share|improve this answer























      • still not getting data every time prints "NSURLConnection finished with error - code -1202 , TIC SSL Trust Error [30:0x1c036c600]: 3:0 , NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813) , Task <DC36F3A2-F4EC-4928-9D94-098AA09A8DC5>.<0> HTTP load failed (error code: -1202

        – krishan kumar
        Nov 10 '18 at 5:45














      3












      3








      3







      This is a swift 2.0 compatible equivalent that works for me. I have not converted this code to use NSURLSession instead of NSURLConnection, and suspect that it would add a lot of complexity to get it right.



      var authRequest : NSURLRequest? = nil
      var authenticated = false
      var trustedDomains = [:] // set up as necessary

      func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool
      if !authenticated
      authRequest = request
      let urlConnection: NSURLConnection = NSURLConnection(request: request, delegate: self)!
      urlConnection.start()
      return false

      else if isWebContent(request.URL!) // write your method for this
      return true

      return processData(request) // write your method for this


      func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge)
      if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust
      let challengeHost = challenge.protectionSpace.host
      if let _ = trustedDomains[challengeHost]
      challenge.sender!.useCredential(NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!), forAuthenticationChallenge: challenge)


      challenge.sender!.continueWithoutCredentialForAuthenticationChallenge(challenge)


      func connection(connection: NSURLConnection, didReceiveResponse response: NSURLResponse)
      authenticated = true
      connection.cancel()
      webview!.loadRequest(authRequest!)






      share|improve this answer













      This is a swift 2.0 compatible equivalent that works for me. I have not converted this code to use NSURLSession instead of NSURLConnection, and suspect that it would add a lot of complexity to get it right.



      var authRequest : NSURLRequest? = nil
      var authenticated = false
      var trustedDomains = [:] // set up as necessary

      func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool
      if !authenticated
      authRequest = request
      let urlConnection: NSURLConnection = NSURLConnection(request: request, delegate: self)!
      urlConnection.start()
      return false

      else if isWebContent(request.URL!) // write your method for this
      return true

      return processData(request) // write your method for this


      func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge)
      if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust
      let challengeHost = challenge.protectionSpace.host
      if let _ = trustedDomains[challengeHost]
      challenge.sender!.useCredential(NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!), forAuthenticationChallenge: challenge)


      challenge.sender!.continueWithoutCredentialForAuthenticationChallenge(challenge)


      func connection(connection: NSURLConnection, didReceiveResponse response: NSURLResponse)
      authenticated = true
      connection.cancel()
      webview!.loadRequest(authRequest!)







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Oct 8 '15 at 1:18









      spirographerspirographer

      5153 silver badges18 bronze badges




      5153 silver badges18 bronze badges












      • still not getting data every time prints "NSURLConnection finished with error - code -1202 , TIC SSL Trust Error [30:0x1c036c600]: 3:0 , NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813) , Task <DC36F3A2-F4EC-4928-9D94-098AA09A8DC5>.<0> HTTP load failed (error code: -1202

        – krishan kumar
        Nov 10 '18 at 5:45


















      • still not getting data every time prints "NSURLConnection finished with error - code -1202 , TIC SSL Trust Error [30:0x1c036c600]: 3:0 , NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813) , Task <DC36F3A2-F4EC-4928-9D94-098AA09A8DC5>.<0> HTTP load failed (error code: -1202

        – krishan kumar
        Nov 10 '18 at 5:45

















      still not getting data every time prints "NSURLConnection finished with error - code -1202 , TIC SSL Trust Error [30:0x1c036c600]: 3:0 , NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813) , Task <DC36F3A2-F4EC-4928-9D94-098AA09A8DC5>.<0> HTTP load failed (error code: -1202

      – krishan kumar
      Nov 10 '18 at 5:45






      still not getting data every time prints "NSURLConnection finished with error - code -1202 , TIC SSL Trust Error [30:0x1c036c600]: 3:0 , NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813) , Task <DC36F3A2-F4EC-4928-9D94-098AA09A8DC5>.<0> HTTP load failed (error code: -1202

      – krishan kumar
      Nov 10 '18 at 5:45












      2














      Here the working code of swift 2.0



      var authRequest : NSURLRequest? = nil
      var authenticated = false


      func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool
      if !authenticated
      authRequest = request
      let urlConnection: NSURLConnection = NSURLConnection(request: request, delegate: self)!
      urlConnection.start()
      return false

      return true


      func connection(connection: NSURLConnection, didReceiveResponse response: NSURLResponse)
      authenticated = true
      connection.cancel()
      webView!.loadRequest(authRequest!)


      func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge)

      let host = "www.example.com"

      if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust &&
      challenge.protectionSpace.host == host
      let credential = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!)
      challenge.sender!.useCredential(credential, forAuthenticationChallenge: challenge)
      else
      challenge.sender!.performDefaultHandlingForAuthenticationChallenge!(challenge)







      share|improve this answer



























        2














        Here the working code of swift 2.0



        var authRequest : NSURLRequest? = nil
        var authenticated = false


        func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool
        if !authenticated
        authRequest = request
        let urlConnection: NSURLConnection = NSURLConnection(request: request, delegate: self)!
        urlConnection.start()
        return false

        return true


        func connection(connection: NSURLConnection, didReceiveResponse response: NSURLResponse)
        authenticated = true
        connection.cancel()
        webView!.loadRequest(authRequest!)


        func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge)

        let host = "www.example.com"

        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust &&
        challenge.protectionSpace.host == host
        let credential = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!)
        challenge.sender!.useCredential(credential, forAuthenticationChallenge: challenge)
        else
        challenge.sender!.performDefaultHandlingForAuthenticationChallenge!(challenge)







        share|improve this answer

























          2












          2








          2







          Here the working code of swift 2.0



          var authRequest : NSURLRequest? = nil
          var authenticated = false


          func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool
          if !authenticated
          authRequest = request
          let urlConnection: NSURLConnection = NSURLConnection(request: request, delegate: self)!
          urlConnection.start()
          return false

          return true


          func connection(connection: NSURLConnection, didReceiveResponse response: NSURLResponse)
          authenticated = true
          connection.cancel()
          webView!.loadRequest(authRequest!)


          func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge)

          let host = "www.example.com"

          if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust &&
          challenge.protectionSpace.host == host
          let credential = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!)
          challenge.sender!.useCredential(credential, forAuthenticationChallenge: challenge)
          else
          challenge.sender!.performDefaultHandlingForAuthenticationChallenge!(challenge)







          share|improve this answer













          Here the working code of swift 2.0



          var authRequest : NSURLRequest? = nil
          var authenticated = false


          func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool
          if !authenticated
          authRequest = request
          let urlConnection: NSURLConnection = NSURLConnection(request: request, delegate: self)!
          urlConnection.start()
          return false

          return true


          func connection(connection: NSURLConnection, didReceiveResponse response: NSURLResponse)
          authenticated = true
          connection.cancel()
          webView!.loadRequest(authRequest!)


          func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge)

          let host = "www.example.com"

          if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust &&
          challenge.protectionSpace.host == host
          let credential = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!)
          challenge.sender!.useCredential(credential, forAuthenticationChallenge: challenge)
          else
          challenge.sender!.performDefaultHandlingForAuthenticationChallenge!(challenge)








          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Jan 7 '16 at 7:27









          Velu LoganathanVelu Loganathan

          17611 bronze badges




          17611 bronze badges





















              1














              To build off of @spirographer's answer, I put something together for a Swift 2.0 use case with NSURLSession. However, this is still NOT working. See more below.



              func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool 
              let result = _Authenticated
              if !result
              let sessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
              let session = NSURLSession(configuration: sessionConfiguration, delegate: self, delegateQueue: NSOperationQueue.mainQueue())
              let task = session.dataTaskWithRequest(request)
              (data, response, error) -> Void in
              if error == nil
              if (!self._Authenticated)
              self._Authenticated = true;
              let pageData = NSString(data: data!, encoding: NSUTF8StringEncoding)
              self.webView.loadHTMLString(pageData as! String, baseURL: request.URL!)

              else
              self.webView.loadRequest(request)



              task.resume()
              return false

              return result


              func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void)
              completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!))



              I will get back the initial HTML response, so the page renders the plain HTML, but there is no CSS styles applied to it (seems like the request to get CSS is denied). I see a bunch of these errors:



              NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)


              It seems like any request made with webView.loadRequest is done not within the session, which is why the connection is rejected. I do have Allow Arbitrary Loads set in Info.plist. What confuses me is why NSURLConnection would work (seemingly the same idea), but not NSURLSession.






              share|improve this answer

























              • You should not be posting code with var names like "_Authenticated".

                – Scenario
                Feb 28 '17 at 19:09











              • @Scenario Why's that?

                – Tri Nguyen
                Mar 1 '17 at 18:46















              1














              To build off of @spirographer's answer, I put something together for a Swift 2.0 use case with NSURLSession. However, this is still NOT working. See more below.



              func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool 
              let result = _Authenticated
              if !result
              let sessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
              let session = NSURLSession(configuration: sessionConfiguration, delegate: self, delegateQueue: NSOperationQueue.mainQueue())
              let task = session.dataTaskWithRequest(request)
              (data, response, error) -> Void in
              if error == nil
              if (!self._Authenticated)
              self._Authenticated = true;
              let pageData = NSString(data: data!, encoding: NSUTF8StringEncoding)
              self.webView.loadHTMLString(pageData as! String, baseURL: request.URL!)

              else
              self.webView.loadRequest(request)



              task.resume()
              return false

              return result


              func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void)
              completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!))



              I will get back the initial HTML response, so the page renders the plain HTML, but there is no CSS styles applied to it (seems like the request to get CSS is denied). I see a bunch of these errors:



              NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)


              It seems like any request made with webView.loadRequest is done not within the session, which is why the connection is rejected. I do have Allow Arbitrary Loads set in Info.plist. What confuses me is why NSURLConnection would work (seemingly the same idea), but not NSURLSession.






              share|improve this answer

























              • You should not be posting code with var names like "_Authenticated".

                – Scenario
                Feb 28 '17 at 19:09











              • @Scenario Why's that?

                – Tri Nguyen
                Mar 1 '17 at 18:46













              1












              1








              1







              To build off of @spirographer's answer, I put something together for a Swift 2.0 use case with NSURLSession. However, this is still NOT working. See more below.



              func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool 
              let result = _Authenticated
              if !result
              let sessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
              let session = NSURLSession(configuration: sessionConfiguration, delegate: self, delegateQueue: NSOperationQueue.mainQueue())
              let task = session.dataTaskWithRequest(request)
              (data, response, error) -> Void in
              if error == nil
              if (!self._Authenticated)
              self._Authenticated = true;
              let pageData = NSString(data: data!, encoding: NSUTF8StringEncoding)
              self.webView.loadHTMLString(pageData as! String, baseURL: request.URL!)

              else
              self.webView.loadRequest(request)



              task.resume()
              return false

              return result


              func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void)
              completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!))



              I will get back the initial HTML response, so the page renders the plain HTML, but there is no CSS styles applied to it (seems like the request to get CSS is denied). I see a bunch of these errors:



              NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)


              It seems like any request made with webView.loadRequest is done not within the session, which is why the connection is rejected. I do have Allow Arbitrary Loads set in Info.plist. What confuses me is why NSURLConnection would work (seemingly the same idea), but not NSURLSession.






              share|improve this answer















              To build off of @spirographer's answer, I put something together for a Swift 2.0 use case with NSURLSession. However, this is still NOT working. See more below.



              func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool 
              let result = _Authenticated
              if !result
              let sessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
              let session = NSURLSession(configuration: sessionConfiguration, delegate: self, delegateQueue: NSOperationQueue.mainQueue())
              let task = session.dataTaskWithRequest(request)
              (data, response, error) -> Void in
              if error == nil
              if (!self._Authenticated)
              self._Authenticated = true;
              let pageData = NSString(data: data!, encoding: NSUTF8StringEncoding)
              self.webView.loadHTMLString(pageData as! String, baseURL: request.URL!)

              else
              self.webView.loadRequest(request)



              task.resume()
              return false

              return result


              func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void)
              completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!))



              I will get back the initial HTML response, so the page renders the plain HTML, but there is no CSS styles applied to it (seems like the request to get CSS is denied). I see a bunch of these errors:



              NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)


              It seems like any request made with webView.loadRequest is done not within the session, which is why the connection is rejected. I do have Allow Arbitrary Loads set in Info.plist. What confuses me is why NSURLConnection would work (seemingly the same idea), but not NSURLSession.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited May 23 '17 at 12:26









              Community

              11 silver badge




              11 silver badge










              answered May 31 '16 at 16:36









              Tri NguyenTri Nguyen

              2,1574 gold badges25 silver badges53 bronze badges




              2,1574 gold badges25 silver badges53 bronze badges












              • You should not be posting code with var names like "_Authenticated".

                – Scenario
                Feb 28 '17 at 19:09











              • @Scenario Why's that?

                – Tri Nguyen
                Mar 1 '17 at 18:46

















              • You should not be posting code with var names like "_Authenticated".

                – Scenario
                Feb 28 '17 at 19:09











              • @Scenario Why's that?

                – Tri Nguyen
                Mar 1 '17 at 18:46
















              You should not be posting code with var names like "_Authenticated".

              – Scenario
              Feb 28 '17 at 19:09





              You should not be posting code with var names like "_Authenticated".

              – Scenario
              Feb 28 '17 at 19:09













              @Scenario Why's that?

              – Tri Nguyen
              Mar 1 '17 at 18:46





              @Scenario Why's that?

              – Tri Nguyen
              Mar 1 '17 at 18:46











              0














              First thing UIWebView is deprecated



              use WKWebView instead (available from iOS8)



              set webView.navigationDelegate = self



              implement



              extension ViewController: WKNavigationDelegate 

              func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
              let trust = challenge.protectionSpace.serverTrust!
              let exceptions = SecTrustCopyExceptions(trust)
              SecTrustSetExceptions(trust, exceptions)
              completionHandler(.useCredential, URLCredential(trust: trust))





              And add this in plist with domains you want to allow



              <key>NSAppTransportSecurity</key>
              <dict>
              <key>NSExceptionDomains</key>
              <dict>
              <key>localhost</key>
              <dict>
              <key>NSTemporaryExceptionAllowsInsecureHTTPSLoads</key>
              <false/>
              <key>NSIncludesSubdomains</key>
              <true/>
              <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
              <true/>
              <key>NSTemporaryExceptionMinimumTLSVersion</key>
              <string>1.0</string>
              <key>NSTemporaryExceptionRequiresForwardSecrecy</key>
              <false/>
              </dict>
              </dict>
              </dict>





              share|improve this answer



























                0














                First thing UIWebView is deprecated



                use WKWebView instead (available from iOS8)



                set webView.navigationDelegate = self



                implement



                extension ViewController: WKNavigationDelegate 

                func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
                let trust = challenge.protectionSpace.serverTrust!
                let exceptions = SecTrustCopyExceptions(trust)
                SecTrustSetExceptions(trust, exceptions)
                completionHandler(.useCredential, URLCredential(trust: trust))





                And add this in plist with domains you want to allow



                <key>NSAppTransportSecurity</key>
                <dict>
                <key>NSExceptionDomains</key>
                <dict>
                <key>localhost</key>
                <dict>
                <key>NSTemporaryExceptionAllowsInsecureHTTPSLoads</key>
                <false/>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
                <true/>
                <key>NSTemporaryExceptionMinimumTLSVersion</key>
                <string>1.0</string>
                <key>NSTemporaryExceptionRequiresForwardSecrecy</key>
                <false/>
                </dict>
                </dict>
                </dict>





                share|improve this answer

























                  0












                  0








                  0







                  First thing UIWebView is deprecated



                  use WKWebView instead (available from iOS8)



                  set webView.navigationDelegate = self



                  implement



                  extension ViewController: WKNavigationDelegate 

                  func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
                  let trust = challenge.protectionSpace.serverTrust!
                  let exceptions = SecTrustCopyExceptions(trust)
                  SecTrustSetExceptions(trust, exceptions)
                  completionHandler(.useCredential, URLCredential(trust: trust))





                  And add this in plist with domains you want to allow



                  <key>NSAppTransportSecurity</key>
                  <dict>
                  <key>NSExceptionDomains</key>
                  <dict>
                  <key>localhost</key>
                  <dict>
                  <key>NSTemporaryExceptionAllowsInsecureHTTPSLoads</key>
                  <false/>
                  <key>NSIncludesSubdomains</key>
                  <true/>
                  <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
                  <true/>
                  <key>NSTemporaryExceptionMinimumTLSVersion</key>
                  <string>1.0</string>
                  <key>NSTemporaryExceptionRequiresForwardSecrecy</key>
                  <false/>
                  </dict>
                  </dict>
                  </dict>





                  share|improve this answer













                  First thing UIWebView is deprecated



                  use WKWebView instead (available from iOS8)



                  set webView.navigationDelegate = self



                  implement



                  extension ViewController: WKNavigationDelegate 

                  func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
                  let trust = challenge.protectionSpace.serverTrust!
                  let exceptions = SecTrustCopyExceptions(trust)
                  SecTrustSetExceptions(trust, exceptions)
                  completionHandler(.useCredential, URLCredential(trust: trust))





                  And add this in plist with domains you want to allow



                  <key>NSAppTransportSecurity</key>
                  <dict>
                  <key>NSExceptionDomains</key>
                  <dict>
                  <key>localhost</key>
                  <dict>
                  <key>NSTemporaryExceptionAllowsInsecureHTTPSLoads</key>
                  <false/>
                  <key>NSIncludesSubdomains</key>
                  <true/>
                  <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
                  <true/>
                  <key>NSTemporaryExceptionMinimumTLSVersion</key>
                  <string>1.0</string>
                  <key>NSTemporaryExceptionRequiresForwardSecrecy</key>
                  <false/>
                  </dict>
                  </dict>
                  </dict>






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Mar 26 at 16:11









                  Yatheesha B LYatheesha B L

                  9,6815 gold badges37 silver badges42 bronze badges




                  9,6815 gold badges37 silver badges42 bronze badges



























                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f11573164%2fuiwebview-to-view-self-signed-websites-no-private-api-not-nsurlconnection-i%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

                      Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

                      Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript