4

I'm using the below code to set a custom HTTP header on requests sent from my UIWebView. The problem is that I'm seeing the page load for a second and then it goes to a white/blank screen. I've tested with different URLs but the behavior is the same. Any ideas?

func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
        var headerIsPresent = false
        let headerFields = request.allHTTPHeaderFields
        for headerField in headerFields?.keys.array as [String] {
            if headerField == "X-Test-App" {
                headerIsPresent = true
            }
        }

        if headerIsPresent {
            return true
        } else {
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
                dispatch_async(dispatch_get_main_queue(), {
                let url = request.URL
                var newRequest: NSMutableURLRequest = request as NSMutableURLRequest

                // set new header
                newRequest.addValue("MyValue", forHTTPHeaderField: "X-Test-App")

                // reload the request
                self.webView.loadRequest(newRequest)
                })
            })
            return false
        }
    }
7
  • um, I haven't done much with swift, but that looks recursive...maybe put a debug break in there? Commented Jan 13, 2015 at 20:47
  • 1
    It is recursive, but shouldn't be an issue because they're checking for the presence of the header before adding it (and recursing) Commented Jan 13, 2015 at 20:51
  • I believe that shouldStartLoadWithRequest will only be invoked on page loads, not on resource loads, you might verify that that isn't the problem. Commented Jan 13, 2015 at 20:51
  • How could I only invoke it on page loads? Commented Jan 13, 2015 at 20:52
  • You can also replace all the code at the top with a single line using contains. var headerIsPresent = contains(request.allHTTPHeaderFields?.keys.array as [String], "X-Test-App") but that's unrelated to your problem. Commented Jan 13, 2015 at 20:57

3 Answers 3

7

Based on David's comments, I used the following solution:

func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
        let headerFields = request.allHTTPHeaderFields
        var headerIsPresent = contains(request.allHTTPHeaderFields?.keys.array as [String], "X-Test-App")

        if headerIsPresent || navigationType == UIWebViewNavigationType.Other {
            return true
        } else {
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
                dispatch_async(dispatch_get_main_queue(), {
                    let url = request.URL
                    var newRequest: NSMutableURLRequest = request as NSMutableURLRequest
                    // set new header
                    newRequest.addValue("MyValue", forHTTPHeaderField: "X-Test-App")

                    // reload the request
                    self.webView.loadRequest(newRequest)
                })
            })
            return false
        }
    }
Sign up to request clarification or add additional context in comments.

4 Comments

Just curious, as I am in the same position and would like to add custom headers to several webviews (but keep from having to put the same code in each view controller), where did you add this function? In a particular view controller, or did you override webView at a lower level somehow?
I put it in just a single view controller called WebViewController, which I re-used for several different screens within the app.
may I ask why add navigationType == UIWebViewNavigationType.Other
How about WKWebView?
1

I think there is a syntactic error with the line var headerIsPresent... Might be due to updated String characters API in Swift?

I used map instead of array and then call contains() on the result.

let headerIsPresent = request.allHTTPHeaderFields?.keys.map({$0}).contains("YOUR_HEADER_NAME")            

Comments

1

If you are looking for code in swift:

    _ = request.allHTTPHeaderFields
    let headerIsPresent = request.allHTTPHeaderFields?.keys.contains("doerlist")

    if headerIsPresent! || navigationType == UIWebViewNavigationType.other {
        return true
    } else {

        DispatchQueue.global(qos: .background).async {
            DispatchQueue.main.async {
                let newRequest: NSMutableURLRequest = request as! NSMutableURLRequest
                newRequest.addValue("doerlist-a61444ea-6fef-4366-a39e-e029e6d521ef", forHTTPHeaderField: "doerlist")
                self.webView.loadRequest(newRequest as URLRequest)
            }
        }

        return false
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.