Apple introduced JavaScriptCore.framework with iOS 7 SDK, before that there was only one function -stringByEvaluatingJavaScriptFromString: available on UIWebView to execute JavaScript in iOS via Web Views.

Ways to execute JavaScript in iOS

1. Writing JavaScript code in Objective C or Swift code.

import JavaScriptCore framework

#import <JavaScriptCore/JavaScriptCore.h>

You are going to use two important Classes from this framework

  • JSContext

JSContext represents a JavaScript execution environment. JavaScript execution takes place within a context. You provide your JavaScript code in the form of NSString for execution.

  • JSValue

A JSValue is a reference to a value within the JavaScript object space of a JSVirtualMachine. All instances of JSValue originate from a JSContext and hold a strong reference to this JSContext. JSValue holds JavaScript values, variable and functions you can convert these to Objective C type data by using function available on JSValue. E.g toString, toArray, toBool etc.

Example

NSString * jsCode = @"2+3";
JSContext *context = [[JSContext alloc] init];
JSValue * value = [context evaluateScript:jsCode];
NSLog(@"SUM = %d", [value toInt32]);
2. Using .js file.

Avoid rewriting if you already have .js source files from server app or reuse same .js files across multiple platform.

Example

Create file Demo.js with following content, and add it in project.

function HelloJS(name) 
{
   return "Hello, " + name + "!";
}

Now write following code to invoke HelloJS function from Demo.js in objective c code.

//Get JS file content in string format
NSString *path = [[NSBundle mainBundle] pathForResource:@"Demo" ofType:@"js"];
NSString *jsScript = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];

//Initialize context with script
JSContext *context = [[JSContext alloc] init];
[context evaluateScript: jsScript];

//Set function name to invoke
JSValue *function = context[@"HelloJS"];

//Call fuction with parameter
JSValue* result = [function callWithArguments:@[@"World"]];

NSLog(@"Output : %@",[result toString]);
3. Web views using JavaScript
  1. Load your html file into web view with source attribute set to .js file (e.g )
  2. Set delegate of web view to self.
  3. When web view finishes loading call methods in your myscript.js

Example

- (void) webViewDidFinishLoad:(UIWebView *)webView
{
    //Execute javascript method 
    [_webView stringByEvaluatingJavaScriptFromString:@"methodName();"];
}

UIWebview vs WKWebview

WKWebview

Cons

  • JSContext is not accessible in WKWebview adding limitations on using js.
  • Available from iOS 8.
  • Not directly available on storyboard.

Pros

  • Fast compared to UIWebview.
  • Apple may force to use this as default, better stick to this now.

UIWebview

  • JSContext is available.
  • Available on all iOS versions.
  • No need to create instance programmatically.

Calling iOS code from javascript

Example

Add following code in your html or js file

<script type='text/javascript'>
       function testFunction()
        {
            window.location  = 'webToNativeCall://SomeStringForEventName_Parameter1_Parameter2';
        }
</script>

Now in your swift code set webview delegate and you can check for url scheme if scheme is 'webToNativeCall' then it is your callback workaround event.

 public func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool
    {
        if requestUrl.scheme == "webToNativeCall"
        {
            //parse request url scheme with '_' for eventname and parameters etc.
            return false
        }

        return true
    }

Previous Post Next Post