Use JavaScriptCore in iOS to make objective-c and JavaScript calls to each other

Source: Internet
Author: User

I've recently seen a leaderboard that uses statistics on the programming languages of GitHub, and JavaScript is really a solo show, and it's hard to imagine that 20 years ago, the language was just a decorative language in the browser, something that could be done with a little effect or check to see if the form you want to submit to the server meets the requirements. Today's JavaScript is already a full-stack language, from client to server ubiquitous. Many programming languages provide interfaces for interacting with JavaScript, which is no exception in iOS development.
?? IOS7 Previously, there was only one way to invoke JavaScript in the app, through the UIWebView object's stringbyevaluatingjavascriptfromstring: method. Since UIWebView contains the CSS rendering engine and the JavaScript execution engine (which is plainly a mini-browser), this approach allows UIWebView to execute JavaScript code through its JavaScript runtime environment. But the things that can be done are very limited, so let's take a look at the following example.

-(void  ) Webviewdidfinishload: (uiwebview  *) WebView {// Get the title of the loaded page in UIWebView  nsstring  *title = [WebView    Stringbyevaluatingjavascriptfromstring: @ "Document.title" ]; nslog     (@ "%@" , title);    //get the link address of the loaded page in UIWebView  nsstring  *urlstr = [WebView stringbyevaluatingjavascriptfromstring: @ "Location.href" ]; nslog  (@ "%@" , Urlstr);}  

?? Starting with iOS7, we can use the JavaScriptCore framework to enable deep interaction between our objective-c code and JavaScript, Simply put, we can access variables in JavaScript or functions that call JavaScript in objective-c code, or you can use Objective-c objects and methods in JavaScript. We can look at a simple example first.

First add the JavaScriptCore header file.

#import <JavaScriptCore/JavaScriptCore.h>

The string is validated using JavaScript's regular expression in objective-c.

    //Create JavaScript Execution Environment (context)Jscontext *context = [[Jscontext alloc] init];NSString*funcode = @"var isvalidnumber = function (phone) {"         "var phonepattern =/^1[34578]\\d{9}$/;"         "return Phone.match (Phonepattern);"         "};";//Execute the above JavaScript code[Context Evaluatescript:funcode];//Get Isvalidnumber function and pass the parameter callJsvalue *jsfunction = context[@"Isvalidnumber"]; Jsvalue *value1 = [Jsfunction callwitharguments:@[@"13012345678"]];NSLog(@"%@", [value1 Tobool]? @"valid": @"Invalid");//EffectiveJsvalue *value2 = [Jsfunction callwitharguments:@[@"12345678899"]];NSLog(@"%@", [value2 Tobool]? @"valid": @"Invalid");//Invalid

Call the JavaScript function in objective-c to find the factorial.

    //Create JavaScript Execution Environment (context)Jscontext *context = [[Jscontext alloc] init];//You can pass a block to the JavaScript context    //It will be converted into a function in JavaScriptcontext[@"factorial"] = ^(intx) {Doubleresult =1.0; for(; x >1;        x--) {result *= x; }returnResult };//Perform a function to find factorial[Context evaluatescript:@"var num = factorial (5);"]; Jsvalue *num = context[@"num"];NSLog(@"5! = %@", num);//5! =

?? The correspondence between the types in JavaScript and objective-c is shown in the following table:

objective-c type javascript type
nil undefined
nsnul L null
nsstring string
nsnumber number, Boolean
nsdictionary object Object
nsarray array object
nsdate date Object
nsblock function Object
id wrapper object
class constructor Object

??
?? Let's look at one more example. We place a button in the root view controller and then navigate to the next view controller, which has a uiwebview loaded with a page with a button, we want to click the button and navigate to the previous view controller, to do this, You need to access objective-c objects and methods in JavaScript.

Code for the page:

<!doctype html><html>    <head>        <meta charset="Utf-8" />        <title>Test page</title>        <style type="Text/css"> #backButton {  display: inline-block;  width:px;             height:px; }                    </style>    </head>    <body>        <button id="Backbutton">Return</button>        <script type="Text/javascript"> var btn = document.getElementById ("Backbutton");            var cb =  function() { window.alert (' Hello ');            };        Btn.addeventlistener (' click ', CB, false);             </script>    </body></html>

Code for the second view controller:

 #import  "ViewController.h"    #import <JAVASCRIPTCORE/JAVASCRIPTCORE.H>    @protocol  myprotocol  <jsexport ; -(void ) Letsgoback;  @end   @interface   Secondviewcontroller : viewcontroller  < MyProtocol ;   @end   
 @interface secondviewcontroller () <uiwebviewdelegate>@property(Weak,nonatomic)Iboutlet UIWebView*MYWEBVIW;@end @implementation secondviewcontroller - (void) Viewdidload {[SuperViewdidload]; [_mywebviw loadrequest:[nsurlrequestrequestwithurl:[NsurlURLWithString: @"Http://localhost:8080/myweb/test.html"]]]; _mywebviw. Delegate= Self;} - (void) Webviewdidfinishload: (UIWebView*) WebView {//Get JavaScript Execution Environment in Web page via UIWebViewJscontext *context = [WebView valueforkeypath: @"DocumentView.webView.mainFrame.javaScriptContext"];//Set block callback to handle exception[Context setexceptionhandler:^ (Jscontext *ctx, Jsvalue *value) {NSLog(@"Error:%@", value);    }]; context[@"Callbackobj"] = Self;//The following code removes the button originally bound to the event callback to rebind the code back to the previous view controller    NSString*code = @"var btn = document.getElementById (' Backbutton ');"                    "Btn.removeeventlistener (' click ', CB);"                    "Btn.addeventlistener (' click ', function () {")                    "Callbackobj.letsgoback ();"                    "});"; [Context Evaluatescript:code];}//Implement the method in the Protocol- (void) Letsgoback {//Must go back to the main thread to refresh the user interface    Dispatch_async(Dispatch_get_main_queue (), ^{[ Self. NavigationcontrollerPopviewcontrolleranimated:YES]; });}@end

?? The complete code for the above example can be downloaded on GitHub.

Use JavaScriptCore in iOS to make objective-c and JavaScript calls to each other

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.