Wkwebview Blank After 'Successful' Https Nsurlrequest

WKWebView blank after 'successful' HTTPS NSURLRequest

To detect errors you should make sure you implement didFailNavigation:withError and didFailProvisionalNavigation:withError.

From the links that work, they seem to be https URLs. The one that does not is an http URL. Implementing the above error methods should tell you what is wrong.

There is a new security feature in iOS9 which fails to load HTTP URLs unless the server conforms to specific set of rules or you setup xcode to override the new feature. You can override the new feature by adding the following into your Info.plist file. Just paste the following at the bottom:

<key>NSAppTransportSecurity</key>  
<dict>
<key>NSAllowsArbitraryLoads</key><true/>
</dict>

This overrides all of the new functionality. You can however perform more specific overrides. The Apple tech note on the changes is here: https://developer.apple.com/library/prerelease/ios/technotes/App-Transport-Security-Technote/index.html

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

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!

Xcode 7 UIWebView doesn't load url

Xcode 7 with iOS9 now force you to not use HTTP call, but HTTPS ones.

this is a security point enhanced in AppTransportSecurity.

Try this:

  • Go to your info.plist
  • Add a dictionary called NSAppTransportSecurity
  • Add a boolean attribute to this one, called NSAllowsArbitraryLoads
  • Pass it to TRUE

Reload your app.

I advice you that if Apple want to block HTTP (unsecured) calls is for a good reason. http://www.originoftime.net/index-cn has a HTTPS one but the server certificate seems to be self-signed.

Let me know if this workaround work for you

Cheers from france

How to check if WkWebView finish loading in Objective-C?

I think the WKNavigationDelegate's webView:didFinishNavigation: delegate callback is what you're looking for.

Configure and present your activity indicator when you start to load and then stop and remove it from view when the callback is called.

WKWebView Content loaded function never get called

You are not setting the navigationDelegate. Set it and it should be fine.

class ViewController: UIViewController, WKNavigationDelegate {

override func viewDidLoad() {
super.viewDidLoad()

let noLayoutFormatOptions = NSLayoutFormatOptions(rawValue: 0)

let webView = WKWebView(frame: CGRectZero, configuration: WKWebViewConfiguration())
webView.setTranslatesAutoresizingMaskIntoConstraints(false)
webView.navigationDelegate = self
view.addSubview(webView)

view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[webView]|", options: noLayoutFormatOptions, metrics: nil, views: ["webView": webView]))

view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[webView]|", options: noLayoutFormatOptions, metrics: nil, views: ["webView": webView]))

let url = NSURL(string: "http://google.com")
let request = NSURLRequest(URL: url)
webView.loadRequest(request)
}

func webView(webView: WKWebView!, didFinishNavigation navigation: WKNavigation!) {
print("Finished navigating to url \(webView.url)");
}

}

And here is a bit better version with Swift 3.

class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

let configuration = WKWebViewConfiguration()
let webView = WKWebView(frame: .zero, configuration: configuration)
webView.translatesAutoresizingMaskIntoConstraints = false
webView.navigationDelegate = self
view.addSubview(webView)

[webView.topAnchor.constraint(equalTo: view.topAnchor),
webView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
webView.leftAnchor.constraint(equalTo: view.leftAnchor),
webView.rightAnchor.constraint(equalTo: view.rightAnchor)].forEach { anchor in
anchor.isActive = true
}

if let url = URL(string: "https://google.com/search?q=westworld") {
webView.load(URLRequest(url: url))
}
}

}

extension ViewController: WKNavigationDelegate {

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("Finished navigating to url \(webView.url)")
}

}

Xamarin form: WkWebView not loading website

Solution:

Have a look at this part of code in custom renderer:

if (e.NewElement != null) {
string fileName = Path.Combine (NSBundle.MainBundle.BundlePath, string.Format ("Content/{0}", "index.html"));
Control.LoadRequest (new NSUrlRequest (new NSUrl (fileName, false)));
}

The url here is combining a local path in the app. So, it will load a local Html successfully and won't work when your change to new NSUrlRequest (new NSUrl ("http://www.google.com", false))).

So, if you want to load a website, you should change the code to :

if (e.NewElement != null) {
//string fileName = Path.Combine (NSBundle.MainBundle.BundlePath, string.Format ("Content/{0}", Element.Uri));
//Control.LoadRequest (new NSUrlRequest (new NSUrl (fileName, false)));

//test
//Control.LoadRequest(new NSUrlRequest(new NSUrl("https://preview.pro.ant.design/user/login")));

Control.LoadRequest (new NSUrlRequest (new NSUrl (Element.Uri)));
}


Related Topics



Leave a reply



Submit