Integrate javascript code on ios project
1. Introduction
The unfinished research had to write a report, ?, confess that if you want to write well, you have to be born like this for 2 months so it is weak, you are reading it and try to bear it, it's not my fault : v. After a period of self-app making, I found that the 1 app uploading me takes a lot of time affecting the process of distributing and earning money from product. So I want to find a way to update the app and limit the new version of app len appstore -> I am researching integrating javascript into ios and then modifying some parts of the app with javascript to make it easier Easy to update the code.
2. JavaScripCore Framework
Introduced by Apple from WWDC 2013, javascriptcore lets you integrate the script into the app, previously with only C api for Mac and now javascriptcore build on top both on mac and ios, making programming simple and fewer errors.
To reflect component in javascript Apple defines the following basic classes:
JSVirtualMachine : js code is run on the machine that tells js to be defined by class. JSVirtualMachine itself does not support multithread, if you want to run multithreading, you must create multiple JSVirtualMachine. Each JSVirtualMachine Object has its own set of heap and barbage collector, and there is no other JSVirtualMachine contact.
JSContext : Corresponding to the Global object in javascript, unlike JSVirtualMachine, you can freely pass objects between JSContext.
JSValue : All values obtained from JSContext are JSValue . JSValue encapsulates all Javascript data types. Each JSValue is tied to the JSContext object.
3. Practice
- To use javascript code you do the following:
- JSContext initialization
- Javascript Load Code from String file
- Get Object from javascriptCode
- Run object with callWithArguments function
1 2 3 4 5 6 7 8 9 10 11 | @IBAction func changeColor (sender: AnyObject) { let path = NSBundle.mainBundle (). pathForResource ("color", ofType: "js") let context = JSContext () context.setObject (ViewController.self, forKeyedSubscript: "ViewController") due to { try context.evaluateScript (NSString (contentsOfFile: path!, encoding: NSUTF8StringEncoding) as String) let randomColorScript = context.objectForKeyedSubscript ("getRandomColor") print (randomColorScript.callWithArguments ([self])) } catch { } |
To use apple code in javascript you have 2 ways:
- With block: with objC, the visibility is visible in the code with swift code you have to declare @objc for swift block
- With class: Use JSExportProtocol Declare a protocol extend from JSExportProtocol
1 2 3 4 5 6 7 8 | @objc protocol ViewControllerExportJS: JSExport { var color: String {get set} func changeBackgroundColor (hex: String) static func twoParametersExample (hex: String, hax: String) } ViewController class: UIViewController, ViewControllerExportJS { .... |
In the javascript file you can use the following:
1 2 3 4 5 6 7 8 9 | function getRandomColor (controller) { var letters = '0123456789ABCDEF'; var color = '#'; for (var i = 0; i <6; i ++) { color + = letters [Math.floor (Math.random () * 16)]; } ViewController.twoParametersExampleHax (color, color); controller.changeBackgroundColor (color) } |
- Note that the function has 2 or more paramter. Since javascript does not have a reminding parameter, you append the method name in the swift twoParametersExample (hex: String, hax: String) to a method with the name twoParametersExampleHax in js (this is not available on raywenderlich: v)
4. Conclusion
It seems that running code on javascript is delayed a bit on processing time. You can test by project example in this article. http://www.mediafire.com/download/ztgly24x1aucd6i/JavascriptCoreTest.zip Refer to: https://www.raywenderlich.com/124075/javascriptcore-tutorial