8

Partly as an exercise for learning a little iOS programming, and partly because I wish I had a WhatsApp client on iPad, I am trying to create an app that I can personally use as a WhatsApp client for my iPad. All it does is load up the web.whatsapp.com desktop site in a UIWebView like so:

override func viewDidLoad() {
    NSUserDefaults.standardUserDefaults().registerDefaults(["UserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/601.5.17 (KHTML, like Gecko) Version/9.1 Safari/601.5.17"])
    super.viewDidLoad()

    self.webView.frame = self.view.bounds
    self.webView.scalesPageToFit = true

    // Do any additional setup after loading the view, typically from a nib.
    let url = NSURL(string: "https://web.whatsapp.com")
    let requestObj = NSMutableURLRequest(URL: url!)
    webView.loadRequest(requestObj)
    //webView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
}

This works okay. It does in fact load the correct webapp, rather than redirecting to the whatsapp home page as would usually happen when the server detects a mobile device. However, rather than presenting me with the QR Code screen for log in, it presents me with this:

enter image description here

Now, if I use WhatsApp Web from Safari on my iPad (and requesting Desktop version), it works perfectly fine. As you can see, I am requesting the Desktop site for my UIWebView by setting the UserAgent. Now, I am wondering why it would not work in the UIWebView, and whether perhaps there is some other header or value that needs to be set in order to convince the App to work within my UIWebView control?

EDIT

I have changed to WKWebView by converting Boris Verebsky's code from Objective-C to Swift. However, whilst at first I was seeing the same screen as before (telling me to use another browser), after changing it around and trying to get it to work I find myself with a blank white screen. Nothing is showing up anymore.

Blank screen

This is my full code as it currently stands:

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate {

    @IBOutlet var webView: WKWebView!

    override func viewDidLoad() {

        super.viewDidLoad()
        self.webView = WKWebView(frame: self.view.bounds)

        if #available(iOS 9.0, *) {
            self.webView.customUserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/601.5.17 (KHTML, like Gecko) Version/9.1 Safari/601.5.17"
        } else {
            // Fallback on earlier versions
            NSUserDefaults.standardUserDefaults().registerDefaults(["UserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/601.5.17 (KHTML, like Gecko) Version/9.1 Safari/601.5.17"])
        }
        self.view!.addSubview(self.webView)
        self.webView.navigationDelegate = self

        // Do any additional setup after loading the view, typically from a nib.
        let url: NSURL = NSURL(string: "http://web.whatsapp.com")!
        let urlRequest: NSURLRequest = NSURLRequest(URL: url)
        webView.loadRequest(urlRequest)
    }

    func webView(webView: WKWebView, decidePolicyForNavigationAction: WKNavigationAction, decisionHandler: WKNavigationActionPolicy -> Void) {
        decisionHandler(.Allow)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

It may be that my conversion from Objective-C to Swift is incorrect. I am unfamiliar with Objective-C, so that is quite likely.

Luke
  • 2,434
  • 9
  • 39
  • 64
  • Your code is correct. Reason why you have blank view is transport security. Either use `https://web.whatsapp.com` as URL (note HTTPS instead of HTTP), or add `NSAllowsArbitraryLoads: YES` in your application info.plist. – Borys Verebskyi Jun 30 '16 at 20:35
  • @BorisVerebsky Thanks, it now works. Just a few other problems to overcome before I can call it finished! – Luke Jul 01 '16 at 12:05
  • which permission required for http://web.whatsapp.com page load – Ramani Hitesh May 18 '18 at 10:09
  • me try but not load http://web.whatsapp.com page please any one know help me – Ramani Hitesh May 18 '18 at 10:09

2 Answers2

10

After checking user agent, https://web.whatsapp.com checks that client supports indexeddb, probably by some JavaScript. It's easy to notice - if you will trace all redirects your app performed, then you will find redirect to https://web.whatsapp.com/browsers.html?missing=indexeddb. In my case, I've used simple NSURLProtocol subclass to log all redirects. Sadly, NSURLProtocol no longer works with WKWebView.

UIWebView doesn't implement indexeddb at all. As far as I know, there is no easy way to implement indexeddb support myself.

You can easily check indexeddb support by accessing html5test.com in UIWebView. You will see something like:

html5test.com result for UIWebView

But WKWebView does support indexeddb:

html5test.com result for WKWebView

I've checked web.whatsapp.com loading in iOS WKWebView with custom user agent, taken from my desktop Safari using http://whatsmyuseragent.com, and it shows QR code as you expected. Moreover, migration to WKWebView will add some bonuses like improved performance and stability.

I've used following code for my test:

#import <WebKit/WebKit.h>

@interface ViewController () <WKNavigationDelegate>
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds];
    self.webView.customUserAgent = @"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/601.6.17 (KHTML, like Gecko) Version/9.1.1 Safari/601.6.17";
    [self.view addSubview:self.webView];

    self.webView.navigationDelegate = self;

    NSURL *url = [NSURL URLWithString:@"http://web.whatsapp.com"];
    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
    [self.webView loadRequest:urlRequest];
}

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(nonnull WKNavigationAction *)navigationAction decisionHandler:(nonnull void (^)(WKNavigationActionPolicy))decisionHandler {
    decisionHandler(WKNavigationActionPolicyAllow);
}

@end

Although it's Objective-C, it should be pretty straightforward to convert into swift.

UPD:

Reason why you have blank view with WKWebView is transport security. Either use https://web.whatsapp.com as URL (note HTTPS instead of HTTP), or add NSAllowsArbitraryLoads: YES in your application info.plist

Borys Verebskyi
  • 4,160
  • 6
  • 28
  • 42
  • I have edited my question. I am not sure my conversion to swift was correct. I am not familiar with Objective C. Could you please take a look? I am now seeing a blank white screen. – Luke Jun 30 '16 at 15:03
  • @Boris that's a great explanation.. Am doing the same in android, Do you have any idea about this – Vignesh Dec 22 '17 at 19:16
  • In android i tried with custom user agent, at first time the webView loads QR code Page second time onwards it loads the WhatsApp.com page – Vignesh Dec 22 '17 at 19:18
  • Last few weeks i tried a lot but couldn't find a solution – Vignesh Dec 22 '17 at 19:19
4

You should really switch to use WKWebView and then you can simply use customUserAgent to directly set your desired agent string on the web view.

Wain
  • 118,658
  • 15
  • 128
  • 151
  • Thanks, I'll give that a shot! – Luke Jun 21 '16 at 12:40
  • you mean the agent isn't set (verified with a tool like charles proxy) or the website still isn't doing what you want ? – Wain Jun 22 '16 at 09:08
  • I mean, I have already set agent, but still it don't work. Now, even web page is not loading. – Ravi_Parmar Jun 23 '16 at 04:32
  • Did you check what agent is actually sent in the request using a proxy tool? You'll need to show the code you've used if you see nothing at all. Include details from which delegate methods are called – Wain Jun 23 '16 at 06:46
  • You I already checked with proxy tool. can it be so because I am creating a mac app. Do you have working Demo.if yes, Can you share the same with me. my ID is raviparmar213@gmail.com – Ravi_Parmar Jun 23 '16 at 12:36
  • i haven't used it on OS X, i only do iOS work really, and I haven't had cause to change the agent. you did say this was for iPad though... I haven't read of any issues with setting `customUserAgent` – Wain Jun 23 '16 at 13:02