Sonntag, 24. Juli 2016

iOS Xcode - UIWebView readyState richtig abfangen

Ruft man innerhalb einer App (in diesem Beispiel Apple iOS) eine Webseite auf und möchte anschließend JavaScript Operationen ausführen muss man wissen, wann die Webseite in dem WebView fertig geladen wurde (readyState).

In dem nachfolgenden Beispiel wird der readyState abgefragt, bis dieser auf "complete" steht. Anschließend wird mittels JavaScript (JSBridge) eine Funktion innerhalb der fertig geladenen Webseite im WebView aufgerufen.

Ich verwenden dies in der App simplyEat.de (www.simplyeat.de) um per JSBridge über den LocationManager die aktuelle Position des Nutzers zu setzen. Danach werden Angebote aus seiner Umgebung in der WebView angezeigt.

Hier ein Beispiel wie dies unter iOS (Xcode) richtig funktioniert:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    offerUrl.delegate = self;
    self.title = offer.name;
    
    NSString *urlAddress = offer.url;
    //Create a URL object.
    NSURL *url = [NSURL URLWithString:urlAddress];
    //URL Requst Object
    NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
    //Load the request in the UIWebView.
    [self.offerUrl loadRequest:requestObj];  

}

- (void)webViewActuallyFinished {
    _webViewLoads--;
    if (_webViewLoads > 0) {
        return;
    }
    //Actually done loading
    
    if ([[self.offerUrl stringByEvaluatingJavaScriptFromString:@"document.readyState"] isEqualToString:@"complete"]) {
        
        // UIWebView object has fully loaded.

        NSString *param1 = [NSString stringWithFormat:@"{coords:{'latitude':%@", latitudeString];
        NSString *param2 = [NSString stringWithFormat:@",'longitude':%@", longitudeString];
        NSString *param3 = @"}}";
        
        NSString *param123 = [NSString stringWithFormat:@"%1$@ %2$@ %3$@", param1, param2, param3];
        NSString *param = [param123 stringByTrimmingCharactersInSet:
                           [NSCharacterSet whitespaceCharacterSet]];
        
        NSString * jsCallBack = [NSString stringWithFormat:@"geoCallBackSuccess(%@);",param];
        [self.offerUrl stringByEvaluatingJavaScriptFromString:jsCallBack];
        
        //NSLog(@"viewDidLoad - javascriptString: %@", jsCallBack);
        [self.offerUrl stringByEvaluatingJavaScriptFromString:jsCallBack];
    }
}

- (void)webViewDidFinishLoad:(UIWebView *)offerUrl {
    //NSLog(@"webViewDidFinishLoad");
    // Identify the “last” webViewDidFinishLoad message
    [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(webViewActuallyFinished) userInfo:nil repeats:NO];
}

- (void)webViewDidStartLoad:(UIWebView *)offerUrl {
    //NSLog(@"webViewDidStartLoad");
    _webViewLoads++;
}

-(void)webView:(UIWebView *)offerUrl didFailLoadWithError:(NSError *)error {
    NSLog(@"No internet connection");
    _webViewLoads--;
    
    NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:@"error.html" ofType:nil]];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [self.offerUrl loadRequest:request];
    
}

Keine Kommentare:

Kommentar veröffentlichen