I have built an app that includes a WKWebView, and the website that the web view loads supports multiple languages. How can I change the Accept-Language
header in a WKWebView, or other HTTP headers for that matter?
-
1This is kind of a duplicate of http://stackoverflow.com/questions/28984212/how-to-add-httpheader-in-request-globally-for-ios-swift/37474812#37474812 See my answer on that question and it will work. I have tested Accept-Language and it can be overridden. – Gabriel Cartier May 27 '16 at 04:25
-
2That solution only works for the initial request, not for sub-resources. – mservidio Aug 28 '16 at 02:57
-
This can be achieved by [intercepting the HTTP requests](https://stackoverflow.com/a/67228256/192373), but this may be like using a cannon to kill a fly. – Alex Cohn Dec 14 '21 at 09:13
3 Answers
I've got it working in a way, but only get requests will have the custom header. As jbelkins answered in the linked so from Gabriel Cartiers comment to your question, you will have to manipulate the request and load it anew.
I've got it working for GET-Requests like this:
(it's in xamarin 0> c#, but i think you will get the idea)
i've created a private field
private bool _headerIsSet
which i check every time a request is made in the deligate method:
[Foundation.Export("webView:decidePolicyForNavigationAction:decisionHandler:")]
public void DecidePolicy(WKWebView webView, WKNavigationAction navigationAction, Action<WKNavigationActionPolicy> decisionHandler)
{
var request = navigationAction.Request;
// check if the header is set and if not, create a muteable copy of the original request
if (!_headerIsSet && request is NSMuteableUrlRequest muteableRequest);
{
// define your custom header name and value
var keys = new object[] {headerKeyString};
var values = new object[] {headerValueString};
var headerDict = NSDictionary.FromObjectsAndKeys(values, keys);
// set the headers of the new request to the created dict
muteableRequest.Headers = headerDict;
_headerIsSet = true;
// attempt to load the newly created request
webView.LoadRequest(muteableRequest);
// abort the old one
decisionHandler(WKNavigationActionPolicy.Cancel);
// exit this whole method
return;
}
else
{
_headerIsSet = false;
decisionHandler(WKNavigationActionPolicy.Allow);
}
}
As i said, this only works for GET-Requests. Somehow, POST-Requests don't contain the body data of the original request (request.Body and request.BodyStream are null), so the muteableRequest (which is a muteable copy of the original request) won't contain the body data of the original request.
I hope this will help you or others that approach the same problem.
Edit: For your needs, set "Accept-Language" as the key

- 359
- 4
- 10
-
This workaround has another problem except being limited to `GET`. It also assumes that the request it will intercept, replaces the whole content of the WebView. This isn't always true: if such secondary request is intended to change some elements of the page, e.g. an image displayed there, the result will be far from what was intended. – Alex Cohn Dec 10 '21 at 14:15
-
@AlexCohn I'm not sure about that, did you encounter such a behavior? DecidePolicy should only be called if a navigation action is happening, e.g. the page changes – DerDingens Dec 10 '21 at 14:55
-
This is exactly the problem: ajax requests, image requests, etc. are not handled by this approach. – Alex Cohn Dec 14 '21 at 08:56
-
Oh okay, misunderstood your point there, true that won't be handled this way – DerDingens Dec 14 '21 at 11:53
-
This can be achieved by [intercepting the HTTP requests](https://stackoverflow.com/a/67228256/192373), but this may be like using a cannon to kill a fly. – Alex Cohn Dec 15 '21 at 17:08
Simply can set needed language ISO 639-1 code in URL request like below, so that we can get user preferred or locale language response from server side.
Swift 4 & above
var request = URLRequest(url: URL(string: "YourUrlStr"))
request.setValue("en", forHTTPHeaderField: "Accept-Language")
wkWebView.load(request)
Objective-C
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:YourUrlStr]];
[request setValue:@"en" forHTTPHeaderField:@"Accept-Language"];
[wkWebView loadRequest:urlRequest];

- 116
- 3
WKWebView supports localization out of the box. You will not be required set the 'Accept-Language' header field.
For some reason if you are required to, this is how it can be done.
Create a 'URLRequest' an instance of URL initialized with the desired website
var request = URLRequest(url: url)
Maintain a mapping of locales required and set the 'Accept-Language' header field accordingly
request.setValue("de-de", forHTTPHeaderField: "Accept-Language")
Load the 'URLRequest' using an instance of 'WKWebView'
webview.load(request)
- Similarly any header field can be changed

- 1,456
- 1
- 16
- 29