Can't set headers on my WKWebView POST request
I had the same problem with WKWebView, that I decided to use instead of UIWebView to avoid the pickers crash in iOS 8. There are two ways that I can think of:
- Use NSURLConnection to make the request and then fill the WKWebView with it's response data. You can find an example here:
https://stackoverflow.com/a/10077796/4116680 (You only needconnection:didReceiveData:
andconnectionDidFinishLoading:
from the delegate if you don't use a self signed SSL certificate) - Use a JavaScript to make the POST request. Here is an example:
Create file eg. "POSTRequestJS.html":
<html>
<head>
<script>
//POST request example:
//post('URL', {key: 'value'});
function post(path, params) {
var method = "post";
var form = document.createElement("form");
form.setAttribute("method", method);
form.setAttribute("action", path);
for(var key in params) {
if(params.hasOwnProperty(key)) {
var hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", key);
hiddenField.setAttribute("value", params[key]);
form.appendChild(hiddenField);
}
}
document.body.appendChild(form);
form.submit();
}
</script>
</head>
<body>
</body>
</html>
And in your code after where you want to load your request:
NSString *path = [[NSBundle mainBundle] pathForResource:@"POSTRequestJS" ofType:@"html"];
NSString *html = [[NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
WKWebView.navigationDelegate = self;
[WKWebView loadHTMLString:html baseURL:[[NSBundle mainBundle] bundleURL]];
Add method:
- (void)makePostRequest
{
NSString *postData = [NSString stringWithFormat: @"email=%@&password=%@", email, password];
NSString *urlString = @"http://materik.me/endpoint";
NSString *jscript = [NSString stringWithFormat:@"post('%@', {%@});", urlString, postData];
DLog(@"Javascript: %@", jscript);
[WKWebView evaluateJavaScript:jscript completionHandler:nil];
didMakePostRequest = YES;
}
And last add the WKNavigationDelegate:
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
if (!didMakePostRequest) {
[self makePostRequest];
}
}
Add request header to ALL outgoing requests within a WKWebView
It is impossible with current API - there is no point where you can handle all requests that made by WKWebView
. You can use UIWebView
+ custom url protocol (WKWebView
doesn't support it) and add your header to all requests for certain server as an alternative.
How to get headers from WKWbView finish loads
You need to set your view controller as the WKWebView Navigation Delegate WKNavigationDelegate
and implement its decidePolicyFor
method:
optional func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void)
Try like this:
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
let allHTTPHeaderFields = navigationAction.request.allHTTPHeaderFields ?? [:]
for (key, value) in allHTTPHeaderFields {
print("key:", key, "value:", value)
}
if navigationAction.navigationType == .linkActivated {
if let url = navigationAction.request.url,
let host = url.host, !host.hasPrefix("www.google.com"),
UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url)
print(url)
print("Redirected to browser. No need to open it locally")
decisionHandler(.cancel)
} else {
print("Open it locally")
decisionHandler(.allow)
}
} else {
print("not a user click")
decisionHandler(.allow)
}
}
How to add customize HTTP headers in UIWebView request, my UIWebView is based on Cordova project?
You have two options either create a NSMutableUrlRequest at the start and load that with webView loadReqest or take over the complete URL loading of your app with NSURLProtocol.
The most easiest way is the first choice as its only one extra lines of code:
[webView loadRequest:mRequest];
The second choice uses NSURLProtocol to take over URL loading of your app. this involves registering your own solution using creating a concrete class. the main method to override is canonicalRequestForRequest
.
I suggest you take a look at these two tutorials NSNipster and raywenderlich for guides.
Related Topics
How to Check If iOS App Is in Background
How to Apply Filter to Video Real-Time Using Swift
How to Subclass Uitableviewcontroller in Swift
How to Push Two View Controllers But Animate Transition Only for the Second One
Facebook Sdk 3.0: How to Receive User's E-Mail
Error: Module File's Minimum Deployment Target Is iOS8.3 V8.3
iOS Changing Uiscrollview Scrollbar Color to Different Colors
Uicollectionview Scrolling in Both Directions
Button Tap and Long Press Gesture
Can a Standard Accessory View Be in a Different Position Within a Uitableviewcell
How to Stop Firebase from Logging Status Updates When App Is Launched
Uitextview Link Tap Recognition Is Delayed
Firebase Dynamic Link Not Opening the App iOS
iOS 9.3:An Ssl Error Has Occurred and a Secure Connection to the Server Cannot Be Made
What Exactly Does 'Pod Repo Update' Do