redak105 redak105 - 5 months ago 501
iOS Question

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?

Answer

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 *)stringByEvaluatingJavaScript:(NSString *)script;
@end

@implementation WKWebView(SynchronousEvaluateJavaScript)

- (NSString *)stringByEvaluatingJavaScript:(NSString *)script
{
    __block NSString *resultString = nil;

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

    while (resultString == nil)
    {
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    }

    return resultString;
}

Example code)

NSString *userAgent = [_webView stringByEvaluatingJavaScript:@"navigator.userAgent"];

NSLog(@"userAgent: %@", userAgent);