UIWebView User-Agent is not properly set for custom value

1.7k views Asked by At

If we want to change the value of user agent from

Mozilla/5.0 (iPhone; CPU iPhone OS 10_1 like Mac OS X) AppleWebKit/602.2.14 (KHTML, like Gecko) Mobile/14B72

to

Mozilla/5.0 (iPad; CPU OS 10_1 like Mac OS X) AppleWebKit/602.2.14 (KHTML, like Gecko) Mobile/14B72

i.e. On iPhone app, my app needs to set the User-Agent of iPad.

My code looks like

class ViewController: UIViewController, UIWebViewDelegate {
    @IBOutlet weak var webView: UIWebView!
    var userAgent:String = ""
    override func viewDidLoad() {
        super.viewDidLoad()
        userAgent = self.webView.stringByEvaluatingJavaScript(from: "navigator.userAgent")!

        let range = userAgent.range(of: "iPhone")

        if range != nil {
            userAgent = userAgent.replacingCharacters(in: range!, with: "iPad")
            userAgent = userAgent.replacingOccurrences(of: "iPhone", with: "")
        }
        userAgent = userAgent.replacingOccurrences(of: "  ", with: " ")

        UserDefaults.standard.register(defaults: ["UserAgent": userAgent])

    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        self.webView.loadRequest(URLRequest(url: URL(string: "http://www.google.com")!))
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
        let userAgent = request.allHTTPHeaderFields!["User-Agent"]
        print("\(userAgent)")
        return true
    }

}

In above case the User-Agent is not set and keeps default value

Instead of logic to manipulate the string to look like iPad's User-Agent, If I change and set hard coded value in viewDidLoad like

UserDefaults.standard.register(defaults: ["UserAgent": “Mozilla/5.0 (iPad; CPU OS 10_1 like Mac OS X) AppleWebKit/602.2.14 (KHTML, like Gecko) Mobile/14B72”])

then also it is not updated.

But if I hard code like

UserDefaults.standard.register(defaults: ["UserAgent": “MyValue”])

then it is properly set

Any idea, what went wrong here?

2

There are 2 answers

2
agenc On

If you call to get iOS browser user agent value with js code, iOS will creat and send value at this time. So you can not update user agent after create. Try to write all user agents as manually without calling by javascript like this:

    let manuelUserAgent = "Mozilla/5.0 (iPad; CPU OS 10_1 like Mac OS X) AppleWebKit/602.2.14 (KHTML, like Gecko) Mobile/14B72"

    let newUserAgent = "\(manuelUserAgent) YourOpt.Text"

    UserDefaults.standard.register(defaults: ["UserAgent": newUserAgent])
0
David Munoz On

There is an interesting workout for this that it helped me in a similar project:

  • It is true that once you get the value of a http header you can not modify it later on (is it a bug?)

  • because of that you cant obtain the current value and modify it

  • That is true for one instance of a webview object. That is why you can add a temporal object with the "hidden" property with true value, so it wont appear in your GUI and then obtain the value from this object so you can modify it on the original object:

     @IBOutlet var tmpWebView: UIWebView!
    
     @IBOutlet var webview: UIWebView!
    
     var newAgent = tmpWebView.stringByEvaluatingJavaScript(from: "navigator.userAgent")! + " Added new string"
     UserDefaults.standard.register(defaults: ["UserAgent": newAgent])