UIWebView stringByEvaluatingJavaScriptFromString in the background

In an iOS application, I run a fairly large script on UIWebViewwith stringByEvaluatingJavaScriptFromString(large in terms of javascript line length). After javascript is called, there is a short pause, causing for some time other elements on the screen.

Placing a javascript call in a function called in the background with self performSelectorInBackgroundinterrupts the application. Is there a safe way to call to run this in the background thread or otherwise prevent the transition from the section?

+5
source share
4 answers

No, Webviews and the Webkit JavaScript engine are single-threaded and cannot be used in the background thread.

JavaScript JavaScript, (JS-, Obj-C):

var i = 0;
var operation = function() {

    switch (i) {
    case 0:
       //do first part of code
       break;
    case 1:
       //do second part of code
       break;
    case 2:
       //do third part of code
       break;
    etc...
    }

    //prepare to execute next block
    i++;
    if (i < TOTAL_PARTS) {
        setTimeout(operation, 0);
    }
};
operation();

script

+3

, . ajax, . :

__block NSString *message;
    dispatch_queue_t q = dispatch_queue_create("sign up Q", NULL);
    dispatch_async(q, ^{
        NSString *function = [[NSString alloc] initWithFormat: @"signup(\'%@\',\'%@\',\'%@\')",self.email.text,self.password.text,self.name.text];

        dispatch_async(dispatch_get_main_queue(), ^{
            NSString *result = [self.webView stringByEvaluatingJavaScriptFromString:function];
            NSLog(@"%@",result);

            if ([result isEqualToString:@"1"]) {
                message = [NSString stringWithFormat:@"Welcome %@",self.name.text];
                [self.activityIndicator stopAnimating];
                [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
            }

            else {
                message = [NSString stringWithFormat:@"%@ is a registered user",self.name.text];
                [self.activityIndicator stopAnimating];
                [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
            }

            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Message" message:message delegate:self cancelButtonTitle:@"Okay" otherButtonTitles: nil];
            [alertView show];
        });
    });

. , , JS-, ...

+3

, UIWebView, . , performSelectorInBackground .

+2

You can try putting this challenge in NSOperation. Since you are working with a user interface element, be sure to use [NSQperueQueue mainQueue].

0
source

All Articles