Note: This question is still unanswered!
I use a UIWebView
to load the following URLs:
https://buchung.salonmeister.de/ort/301655/menue/#offerId=907601&venueId=301655
https://buchung.salonmeister.de/place/#offer-details-page?id=907599&venueId=301655
http://feratel.lueneburger-heide.de/lhg/de/accommodation/detail/LUH/8634e147-e13d-40f5-8954-2ac40cfea2a7/romantik_hotel_bergström?customHeader=true
http://feratel.lueneburger-heide.de/lhg/de/accommodation/detail/LUH/8af6d1fd-af6d-4765-8025-9eb8fa05ea42/hotel%20undeloher%20hof?customHeader=true
Note that the above urls are not my urls so I cannot change their content.
When trying to load I get the following error from func webView(webView: UIWebView, didFailLoadWithError error: NSError)
:
Error Domain=NSURLErrorDomain Code=-999 "The operation couldn’t be completed. (NSURLErrorDomain error -999.)" UserInfo=0x7ff7d0fd6f20 {NSErrorFailingURLStringKey=https://buchung.salonmeister.de/ort/301655/menue/#offerId=907601&venueId=301655, NSErrorFailingURLKey=https://buchung.salonmeister.de/ort/301655/menue/#offerId=907601&venueId=301655}
I tested the code below on iOS7 and iOS8. Mobile Safari loads this page without any problems but in my UIWebView I see nothing.
Here is the code I use:
class ViewController: UIViewController, UIWebViewDelegate, NSURLConnectionDataDelegate {
@IBOutlet weak var webView: UIWebView!
var request: NSURLRequest!
var urlString: String!
private var isDone: Bool = false
private var failedRequest: NSURLRequest!
override func viewDidLoad() {
super.viewDidLoad()
urlString = "https://buchung.salonmeister.de/ort/301655/menue/#offerId=907601&venueId=301655"
request = NSURLRequest(URL: NSURL(string: urlString)!)
webView.delegate = self
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
self.webView.loadRequest(self.request)
}
// MARK: UIWebViewDelegate
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
println("shouldStartLoadWithRequest()")
if !isDone {
isDone = false
println("shouldStartLoadWithRequest() 111")
failedRequest = request
webView.stopLoading()
var connection = NSURLConnection(request: request, delegate: self, startImmediately: true)
connection!.start()
// NSURLConnection(request: request, delegate: self)
return false
}
println("shouldStartLoadWithRequest() -----------------------")
return true
}
func webViewDidStartLoad(webView: UIWebView) {
println("webViewDidStartLoad()")
}
func webViewDidFinishLoad(aWebView: UIWebView) {
println("webViewDidFinishLoad()")
}
func webView(webView: UIWebView, didFailLoadWithError error: NSError) {
println("webView(): didFailLoadWithError(): \(error)")
}
// MARK: NSURLConnectionDataDelegate
func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge) {
println("connection willSendRequestForAuthenticationChallenge")
if challenge.previousFailureCount == 0 {
self.isDone = true
println("x1")
let credential: NSURLCredential = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!)
challenge.sender.useCredential(credential, forAuthenticationChallenge: challenge)
}
else {
println("x2")
challenge.sender.cancelAuthenticationChallenge(challenge)
}
}
func connection(connection: NSURLConnection, didReceiveResponse response: NSURLResponse) {
println("connection didReceiveResponse")
self.isDone = true
connection.cancel()
self.webView.loadRequest(self.failedRequest)
}
func connection(connection: NSURLConnection, canAuthenticateAgainstProtectionSpace protectionSpace: NSURLProtectionSpace) -> Bool {
println("connection canAuthenticateAgainstProtectionSpace")
return protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust
}
}
I created a sample project with the above code here: https://github.com/confile/UIWebView-https-url
How do I get my UIWebView
load the url correctly?
I ran your code. It worked fine approximately 50% of the time, and showed the -999 error the other times.
That error code is NSURLErrorCancelled
, as per URL Loading System Error Codes in Apple's Foundation Constants Reference. So something is cancelling the page load.
I printed the page content that was received, using this:
println(aWebView.stringByEvaluatingJavaScriptFromString("document.body.innerHTML"));
I see that the Javascript in the page contains this:
if (mobilePath) {
document.body.style.display = 'none';
document.location = mobilePath;
}
My guess is that this Javascript starts to run as soon as the content is loaded. This results in a race condition where sometimes the page is immediately redirected to a different document.location
, and so the first page load is cancelled before it loads completely.
You should change the server so that it does not send this Javascript.
Alternatively, if you just want to load the website like a normal website, then you can let UIWebView handle the redirects for you. In the case of this site, I got it working properly by setting the User-agent to pretend to be mobile Safari. I also removed shouldStartLoadWithRequest
because it was only interfering with things.
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
var request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
var userAgent = ["UserAgent": "mozilla/5.0 (iphone; cpu iphone os 7_0_2 like mac os x) applewebkit/537.51.1 (khtml, like gecko) version/7.0 mobile/11a501 safari/9537.53"]
NSUserDefaults.standardUserDefaults().registerDefaults(userAgent as [NSObject : AnyObject])
self.webView.loadRequest(request)
}
If I don't have the code to pretend to be mobile Safari, then the page content loads but it doesn't do the right thing. It just stops at a spinner. I presume that the website is sending different Javascript depending on which rendering engine it thinks it is talking to. If you don't specify any User-agent then you are at the mercy of whatever their web designer has done in terms of specifying the default behavior.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With