0

I am using following function to evaluate javascript, but running this method on the main thread blocks the app. The while loop never ends. Is there any another way to do this or any fix in this method?

- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script
        {
            __block NSString *resultString = nil;
            __block BOOL finished = NO;

            [self evaluateJavaScript:script completionHandler:^(id result, NSError *error) {
                if (error == nil) {
                    if (result != nil) {
                        resultString = [NSString stringWithFormat:@"%@", result];
                    }
                } else {
                    NSLog(@"evaluateJavaScript error : %@", error.localizedDescription);
                }
                finished = YES;
            }];

            while (!finished)
            {
                [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:NSDate .distantPast];
            }

            return resultString;
        }
jvarela
  • 3,744
  • 1
  • 22
  • 43
amey rane
  • 167
  • 1
  • 8
  • Did you find a solution to this? I'm running into the same problem. I need to synchronously get the result of a JavaScript call in WKWebView. Here is another approach that I found: https://stackoverflow.com/a/17921058/901334 – Mark Apr 08 '21 at 09:48

1 Answers1

0

When you call -[NSRunLoop runMode:beforeDate:], that call will block while the run loop waits for input.

You need to create an NSPort and add it as an input source for the NSRunLoop before running it. Inside your asynchronous evaluateJavaScript callback, create an NSPortMessage and then send it to the NSPort. This will cause the -[NSRunLoop runMode:beforeDate:] call to return, triggering your finished check.

However, perhaps you can back up and post what problem you are trying to solve? It is preferable to avoid synchronous inter-process communication like this to keep your app's main thread as free as possible. This is likely why WKWebView does not expose a synchronous variant of evaluateJavaScript.

Supersheep
  • 236
  • 2
  • 7