2016-05-17 32 views
8

In parte come esercizio per imparare un po 'di programmazione iOS e in parte perché vorrei avere un client WhatsApp su iPad, sto provando a creare un'app che posso utilizzare personalmente come client WhatsApp per il mio iPad. Tutto ciò che fa è caricare il sito desktop web.whatsapp.com in un UIWebView in questo modo:Il sito Web UIWebView Desktop non funziona

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); 
} 

Questo funziona bene. In effetti, carica la webapp corretta, piuttosto che reindirizzare alla home page di whatsapp come di solito accade quando il server rileva un dispositivo mobile. Tuttavia, invece di me presentare con lo schermo QR Code per log in, mi presenta con questo:

enter image description here

Ora, se io uso WhatsApp web da Safari sul mio iPad (e richiedere la versione desktop), si funziona perfettamente. Come puoi vedere, sto richiedendo il sito Desktop per UIWebView impostando UserAgent. Ora, mi chiedo perché non funzionerebbe in UIWebView, e se forse ci fosse qualche altra intestazione o valore che deve essere impostato per convincere l'App a funzionare con il mio controllo UIWebView?

EDIT

ho cambiato a WKWebView convertendo il codice di Boris Verebsky da Objective-C per Swift. Tuttavia, mentre inizialmente vedevo lo stesso schermo di prima (dicendomi di usare un altro browser), dopo averlo cambiato e aver provato a farlo funzionare, mi ritrovo con uno schermo bianco vuoto. Non si vede più niente.

Blank screen

Questo è il mio codice completo nella sua forma attuale:

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. 
    } 


} 

Può darsi che la mia conversione da Objective-C a Swift non è corretta. Non ho familiarità con Objective-C, quindi è abbastanza probabile.

+0

Il codice è corretto. Il motivo per cui la visualizzazione vuota è la sicurezza del trasporto. O usare 'https: // web.whatsapp.com' come URL (nota HTTPS invece di HTTP), o aggiungi' NSAllowsArbitraryLoads: YES' nella tua applicazione info.plist. –

+0

@BorisVerebsky Grazie, ora funziona. Solo qualche altro problema da superare prima di poterlo chiamare finito! – Luke

risposta

8

Dopo aver controllato il programma utente, https://web.whatsapp.com controlla che il client supporti indexeddb, probabilmente con qualche JavaScript. È facile notare che se si rintracciano tutti i reindirizzamenti eseguiti dall'app, sarà possibile trovare il reindirizzamento su https://web.whatsapp.com/browsers.html?missing=indexeddb. Nel mio caso, ho utilizzato la semplice sottoclasse NSURLProtocol per registrare tutti i reindirizzamenti. Purtroppo, NSURLProtocol non funziona più con WKWebView.

UIWebView non implementa indexeddb. Per quanto ne so, non esiste un modo semplice per implementare me stesso il supporto indexeddb.

È possibile controllare facilmente il supporto indexeddb accedendo a html5test.com in UIWebView. Si vedrà qualcosa di simile:

html5test.com result for UIWebView

Ma WKWebView supporta IndexedDB: web.whatsapp

html5test.com result for WKWebView

Ho controllato.com in iOS WKWebView con user agent personalizzato, tratto dal mio desktop Safari utilizzando http://whatsmyuseragent.com e mostra il codice QR come previsto. Inoltre, la migrazione a WKWebView aggiungerà alcuni bonus come prestazioni e stabilità migliorate.

Ho usato seguente codice per la mia prova:

#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 

Anche se è Objective-C, dovrebbe essere abbastanza semplice per convertire in rapida.

UPD:

Motivo per cui si dispone di vista in bianco con WKWebView è la sicurezza dei trasporti. Utilizzare https://web.whatsapp.com come URL (notare HTTPS anziché HTTP) o aggiungere NSAllowsArbitraryLoads: YES nell'applicazione info.plist

+0

Ho modificato la mia domanda. Non sono sicuro che la mia conversione a velocità sia corretta. Non ho familiarità con l'obiettivo C. Potresti dare un'occhiata? Ora vedo uno schermo bianco vuoto. – Luke

+0

@Boris è un'ottima spiegazione .. Sto facendo lo stesso in Android, Hai qualche idea su questo – ASV

+0

In Android ho provato con un programma utente personalizzato, la prima volta che WebView carica il codice QR. La seconda volta in poi carica il WhatsApp. com page – ASV

4

Si dovrebbe davvero passare a utilizzare WKWebView e quindi è possibile semplicemente utilizzare customUserAgent per impostare direttamente la stringa agente desiderata sulla visualizzazione web.

+0

Grazie, darò un colpo! – Luke

+0

Provato, non funziona. Puoi darmi un esempio? –

+0

vuoi dire che l'agente non è impostato (verificato con uno strumento come charles proxy) o il sito Web non sta ancora facendo quello che vuoi? – Wain

Problemi correlati