Search code examples
javascriptiosobjective-cwkwebview

WKWebView evaluate JavaScript return value


I need to change a function to evaluate JavaScript from UIWebView to WKWebView. I need to return result of evaluating in this function.

Now, I am calling:

[wkWebView evaluateJavaScript:call completionHandler:^(NSString *result, NSError *error)
{
    NSLog(@"Error %@",error);
    NSLog(@"Result %@",result);
}];

But I need get result like return value, like in UIWebView. Can you suggest a solution?


Solution

  • Update: This is not working on iOS 12+ anymore.


    I solved this problem by waiting for result until result value is returned.

    I used NSRunLoop for waiting, but I'm not sure it's best way or not...

    Here is the category extension source code that I'm using now:

    @interface WKWebView(SynchronousEvaluateJavaScript)
    - (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;
    @end
    
    @implementation WKWebView(SynchronousEvaluateJavaScript)
    
    - (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 distantFuture]];
        }
    
        return resultString;
    }
    @end
    

    Example code:

    NSString *userAgent = [_webView stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
    
    NSLog(@"userAgent: %@", userAgent);