The author of this article, Nate Cook, is an independent web and mobile application developer. He is the main maintainer of NSHipster after Mattt, a well-known and active Swift blogger, and the creator of SwiftDoc.org, a website that supports automatic generation of Swift online documentation. In this article, he introduces the methods and techniques of using JavaScript in Swift, which is very practical for iOS and web application engineers. The following is the translation: In the January 2015 programming language rankings released by RedMonk, Swift's adoption rate ranking soared rapidly, jumping from 68th when it was first released to 22nd, Objective-C still ranked ***0th, and JavaScript became the most popular programming language of the year with its native experience advantage on the iOS platform.
As early as 2013, Apple released OS X Mavericks and iOS 7, which both added JavaScriptCore framework, allowing developers to easily, quickly and safely write applications using JavaScript. Regardless of praise or criticism, JavaScript's dominance has become a fact. Developers flock to it, and JS tool resources are emerging in an endless stream for OS High-speed virtual machines such as X and iOS have also flourished. JSContext/JSValue JSContext is the running environment of JavaScript code. A Context is an environment in which JavaScript code is executed, also called a scope. When running JavaScript code in a browser, JSContext is equivalent to a window that can easily execute JavaScript code to create variables, perform calculations, and even define functions:
Dynamic languages like JavaScript require a dynamic type, so as shown in the first line of the code, different values in JSContext are encapsulated in JSValue objects, including strings, numbers, arrays, functions, and even Error, null, and undefined. JSValue contains a series of methods for obtaining Underlying Value, as shown in the following table: To retrieve the tripleNum value in the above example, just use the corresponding method:
Subscripting Values By using subscript notation in JSContext and JSValue instances, you can easily get the existing value in the context. Among them, JSContext can only put string subscripts into objects and arrays, while JSValue can be string or integer subscripts.
After all, the Swift language was born not long ago, so it cannot use subscript symbols as freely as Objective-C. Currently, Swift methods can only implement subscripts such as objectAtKeyedSubscript() and objectAtIndexedSubscript(). Calling Functions We can use the Foundation class as a parameter and directly call the JavaScript function encapsulated in JSValue from Objective-C/Swift code. Here, JavaScriptCore plays a connecting role again.
Exception Handling JSContext also has a unique skill, which is to check and record syntax, type, and runtime errors by setting the exceptionHandler property in the context. ExceptionHandler is a callback handler that mainly receives the reference of JSContext and handles exceptions.
JavaScript function calls Now that we know how to get different values and call functions from the JavaScript environment, how do we get custom objects and methods defined in Objective-C or Swift in the JavaScript environment? There are two main ways to get local client code from JSContext, namely Blocks and JSExport protocols. Blocks In JSContext, if the Objective-C code block is assigned to an identifier, JavaScriptCore will automatically encapsulate it in a JavaScript function, making it easier to use Foundation and Cocoa classes on JavaScript - this once again proves the powerful connection of JavaScriptCore. Now CFStringTransform can also be used on JavaScript, as shown below:
It should be noted that Swift's speedbump only applies to Objective-C blocks and is useless for Swift closures. To use a closure in a JSContext, there are two steps: first, declare it with @objc_block, and second, convert Swift's knuckle-whitening unsafeBitCast() function to AnyObject. Memory Management Code blocks can capture variable references, and strong references to all JSContext variables are retained in JSContext, so be careful to avoid circular strong reference problems. In addition, do not capture JSContext or any JSValues in code blocks. It is recommended to use [JSContext currentContext] to obtain the current Context object and pass the value as a parameter to the block according to specific needs. JSExport Protocol With the help of JSExport protocol, you can also use custom objects on JavaScript. Instance methods and class methods declared in JSExport protocol can automatically interact with JavaScript regardless of their attributes. The specific practice process will be introduced later in this article. JavaScriptCore Practice We can better understand how to use the above techniques through some examples. First, define a Person model that conforms to the JSExport subprotocol PersonJSExport, and then use JavaScript to create and fill in the instance in JSON. What is the use of NSJSONSerialization when there is an entire JVM? PersonJSExports and Person The PersonJSExports protocol implemented by the Person class specifies the available JavaScript properties. , class methods are required at creation time because JavaScriptCore does not apply initialization conversions and we cannot use var person = new Person() as we would with native JavaScript types.
Configuring JSContext After creating the Person class, you need to export it to the JavaScript environment and import the Mustache JS library to apply templates to the Person object.
JavaScript Data & Processing The following is a simple JSON example and how to create a new Person instance using JSON. Note: JavaScriptCore implements the interaction between Objective-C/Swift method names and JavaScript code. Because JavaScript does not have named parameters, any additional parameter names are Camel-Case and appended to the function name. In this example, the Objective-C method createWithFirstName:lastName: becomes createWithFirstNameLastName() in JavaScript.
Try it yourself Now you just need to load the JSON data, call it in JSContext, parse it into an array of Person objects, and render it with a Mustache template:
|
<<: Swift TIP: objc and dynamic
>>: Quickly understand Swift's classes and structures based on OC
Since its release, Model 3 has launched minor mod...
Three Management Axes - Introduction to Alibaba...
According to Reuters, three French Mercedes-Benz ...
Porsche's sales in China have fallen, and the...
When it comes to new media , everyone will think ...
As the global IPv4 addresses are about to run out...
In modern society, people's leisure and enter...
It’s about operations and growth. Time flies, and...
Most of our friends can tell you a thing or two a...
Author: Song Guohong, Chief Physician, Peking Uni...
This article will focus on operational activities...
On December 23, 2014, Christmas Eve, Google infor...
In the 5G smart era, I believe that everyone’s sm...
When it comes to Android phones, most people have...