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?
evaluateJavaScript:inFrame:inContentWorld:completionHandler: Evaluates the specified JavaScript string in the specified frame and content world.
A WKWebView object is a platform-native view that you use to incorporate web content seamlessly into your app's UI. A web view supports a full web-browsing experience, and presents HTML, CSS, and JavaScript content alongside your app's native views.
You can implement WKWebView in Objective-C, here is simple example to initiate a WKWebView : WKWebViewConfiguration *theConfiguration = [[WKWebViewConfiguration alloc] init]; WKWebView *webView = [[WKWebView alloc] initWithFrame:self. view. frame configuration:theConfiguration]; webView.
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);
This solution also works if the javascript's code raise NSError:
- (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; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With