Skip to content

Commit b5512c4

Browse files
author
Eric Lange
authored
Update README.md
1 parent 169e004 commit b5512c4

File tree

1 file changed

+234
-34
lines changed

1 file changed

+234
-34
lines changed

README.md

Lines changed: 234 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,256 @@
1-
The LiquidCore Project
2-
----------------------
1+
# The LiquidCore Project
32

4-
LiquidCore enables [Node.js] virtual machines to run inside Android and iOS apps. It provides a complete runtime environment, including a virtual file system.
3+
[![Download](https://img.shields.io/npm/dt/liquidcore.svg)](https://www.npmjs.com/package/liquidcore)
54

6-
LiquidCore also provides a convenient way for Android developers to [execute raw JavaScript](https://github.com/LiquidPlayer/LiquidCore/wiki/LiquidCore-as-a-Native-Javascript-Engine) inside of their apps, as iOS developers can already do natively with JavaScriptCore.
5+
[![NPM](https://nodei.co/npm/liquidcore.png)](https://nodei.co/npm/liquidcore/)
76

8-
For a description of how to use LiquidCore, please see the appropriate README for [Android](https://github.com/LiquidPlayer/LiquidCore/tree/master/doc/AndroidREADME.md) or [iOS](https://github.com/LiquidPlayer/LiquidCore/tree/master/doc/iOSREADME.md).
7+
LiquidCore enables [Node.js](https://nodejs.org) virtual machines to run inside Android and iOS apps. It provides a complete runtime environment, including a virtual file system.
98

10-
Version
11-
-------
12-
[0.6.2](https://github.com/LiquidPlayer/LiquidCore/releases/tag/0.6.2)
9+
LiquidCore also provides a convenient way for Android developers to [execute raw JavaScript](https://github.com/LiquidPlayer/LiquidCore/wiki/LiquidCore-as-a-Raw-JavaScript-engine-for-Android-(v.-0.7.0-)) inside of their apps, as iOS developers can already do natively with JavaScriptCore.
1310

14-
[![Release](https://jitpack.io/v/LiquidPlayer/LiquidCore.svg)](https://jitpack.io/#LiquidPlayer/LiquidCore)
15-
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
11+
## Installation
1612

17-
API Documentation
18-
-----------------
19-
**Android Javadocs**: [Version 0.6.2](https://liquidplayer.github.io/LiquidCoreAndroid/0.6.2/index.html)
13+
#### Step 1: Make sure your project is configured for use with `npm`
14+
In the root directory of your project, you must have a `package.json` file. If you do not already
15+
have one, you can create it by running:
2016

21-
**iOS Objective-C/Swift**: [Version 0.6.2](https://liquidplayer.github.io/LiquidCoreiOS/0.6.2/index.html)
17+
```bash
18+
$ npm init
19+
```
20+
and following the steps in the wizard.
2221

23-
Architecture
24-
------------
22+
#### Step 2: Install LiquidCore and configure `package.json`
2523

26-
### Android
24+
```bash
25+
$ npm i liquidcore
26+
$ node node_modules/liquidcore/lib/cli.js init
27+
```
2728

28-
![Android architecture diagram](https://github.com/LiquidPlayer/LiquidCore/raw/master/doc/ArchitectureAndroid.png)
29+
The `init` step will add some utility scripts and the `liquidcore` object to your `package.json` file. It will also create an example service called `example.js`, which will get packaged into your app. You can change / add files to be packaged by editing the `liquidcore.entry` property in your `package.json`.
2930

30-
LiquidCore for Android includes the Node.js runtime and V8 backend. In addition, it provides three APIs for apps to interact with:
31+
#### Step 3: Configure your mobile app project
3132

32-
* **[Java / JavaScript JNI](https://github.com/LiquidPlayer/LiquidCore/wiki/README-Android-(0.6.2)#java--javascript-api) API**, which provides a convenient way to run raw JavaScript code from within Java, without the need for a clunky `WebView`.
33-
* **Node [`Process`](https://github.com/LiquidPlayer/LiquidCore/wiki/README-Android-(0.6.2)#node-process) API**, which allows developers to launch fast isolated instances of the Node.js runtime.
34-
* **[`MicroService`](https://github.com/LiquidPlayer/LiquidCore/wiki/README-Android-(0.6.2)#the-microservice) API**, which is an abstraction of a Node.js process and supports dynamic code fetching and native add-ons.
33+
<table ><tbody><tr><td>
3534

36-
Native add-ons enable extending the basic runtime environment with additional native functionality. Add-ons have access to all the above APIs, plus the ability to use [WebKit's JavaScriptCore API](https://developer.apple.com/documentation/javascriptcore?language=objc) running on top of V8. This allows projects that depend on JavaScriptCore, like [React Native](https://facebook.github.io/react-native/), to use LiquidCore directly.
35+
#### Android
3736

38-
### iOS
37+
</td><td>
3938

40-
![iOS architecture diagram](https://github.com/LiquidPlayer/LiquidCore/raw/master/doc/ArchitectureiOS.png)
39+
#### iOS
4140

42-
LiquidCore for iOS includes the Node.js runtime, but without the V8 backend. Instead, it marshalls calls to V8 through an interpreter to Apple's JavaScriptCore engine. It provides two APIs for apps to interact with:
41+
</td></tr><tr><td>
4342

44-
* **Node [`LCProcess`](https://github.com/LiquidPlayer/LiquidCore/wiki/README-iOS-(0.6.2)#node-lcprocess) API**, which allows developers to launch fast isolated instances of the Node.js runtime.
45-
* **[`LCMicroService`](https://github.com/LiquidPlayer/LiquidCore/wiki/README-iOS-(0.6.2)#the-lcmicroservice) API**, which is an abstraction of a Node.js process and supports dynamic code fetching and native add-ons.
43+
```bash
44+
$ npm run gradle-config -- --module=<app>
45+
```
4646

47-
Native add-ons enable extending the basic runtime environment with additional native functionality. Add-ons have access to the above APIs, plus the ability to use the V8 API. This allows projects that depend on V8, such native Node modules to use LiquidCore directly.
47+
where `<app>` is the name of your application module (the default in Android Studio is 'app').
48+
</td><td>
4849

49-
License
50-
-------
50+
```bash
51+
$ npm run pod-config -- --target=<target> --podfile=<podfile>
52+
```
5153

52-
Copyright (c) 2014 - 2019 LiquidPlayer
54+
where `<target>` is your XCode project target, and `<podfile>` is the path of your application's `Podfile`
55+
</td></tr></tbody>
56+
</table>
5357

54-
Distributed under the MIT License. See [LICENSE.md](LICENSE.md) for terms and conditions.
58+
Note: On iOS, LiquidCore requires the use of [Cocoapods](https://cocoapods.org/), so make sure you've set up your project to use a [`Podfile`](https://guides.cocoapods.org/using/the-podfile.html) first.
5559

56-
[Node.js]:https://nodejs.org/
60+
## Automatic Bundling
61+
62+
One of the newest features in 0.7.0+ is the ability to automatically bundle JavaScript files in the application build process. This is configured in the `gradle-config` and/or `pod-config` steps above. The bundling options are stored in the local `package.json` file in the `liquidcore` property. A typical file `liquidcore` object may look something like this:
63+
64+
```json
65+
"liquidcore": {
66+
"entry": [
67+
"example.js",
68+
"index.js"
69+
],
70+
"gradle_options": {
71+
"module": "app"
72+
},
73+
"bundler_output": {
74+
"android": "app/src/main/res/raw",
75+
"ios": ".liquidcore/ios_bundle"
76+
},
77+
"bundler_options": {
78+
"minify": false
79+
},
80+
"pod_options": {
81+
"dev": true,
82+
"target": "TestApp"
83+
}
84+
}
85+
```
86+
87+
To include a new bundle, simply put the entry point JavaScript file in the `entry` array property. LiquidCore will generate one bundle for each `entry` during the build process.
88+
89+
If you have a non-standard configuration for your app, you may have to change some of these values. For example, `bundler_output` for Android assumes that your resources directory is at `<app-module>/src/main/res`. This is the Android Studio default. If you have changed this to something else, you will need to update this property.
90+
91+
Bundling is a convenient way to test and package your JavaScript projects. The bundler uses [Metro](https://facebook.github.io/metro/) to package up all of your required node modules into a single file that can be packaged as a resource in your app. If you are running on the Android Emulator or iOS Simulator, you can run a local server on your development machine and hot-edit your JavaScript code by `npm run server` in your project root. If you are using the `Bundle` API (described below), and your app is built in debug mode, it will first attempt to get the bundles from the server. If the server is not available, it will use the automated bundle packaged at build time. In release mode, it will always use the packaged bundle.
92+
93+
## Usage
94+
95+
### The `MicroService` API
96+
97+
A micro service is nothing more than an independent Node.js instance whose startup code is referenced by a URI. For example:
98+
99+
<table ><tbody><tr><td>
100+
101+
#### Android Kotlin
102+
103+
</td><td>
104+
105+
#### iOS Swift
106+
107+
</td></tr><tr><td>
108+
109+
```kotlin
110+
val uri = MicroService.Bundle(androidContext, "example")
111+
val service = MicroService(androidContext, uri)
112+
service.start()
113+
```
114+
115+
</td><td>
116+
117+
```swift
118+
import LiquidCore
119+
...
120+
let url = LCMicroService.bundle("example")
121+
let service = LCMicroService(url: url!)
122+
service?.start()
123+
```
124+
125+
</td></tr></tbody>
126+
</table>
127+
128+
The service URI can either refer to a server URL or a local resource. For services that are automatically bundled with your app by LiquidCore, you can use the `MicroService.Bundle()` or `LCMicroService.bundle()` methods to generate the correct URI. Any javascript entry files referenced in your `package.json` in `liquidcore.entry` will get bundled automatically with each build. By default, the initialization script creates and packages `example.js`, but you can easily change this.
129+
130+
A micro service can communicate with the host app once the Node.js environment is set up. This can be determined by adding a start listener in the constructor:
131+
132+
<table ><tbody><tr><td>
133+
134+
#### Android Kotlin
135+
</td><td>
136+
137+
#### iOS Swift
138+
</td></tr><tr><td>
139+
140+
```kotlin
141+
val uri = MicroService.Bundle(androidContext, "example")
142+
val startListener = MicroService.ServiceStartListener {
143+
// .. The environment is live, but the startup
144+
// JS code (from the URI) has not been executed yet.
145+
}
146+
val service = MicroService(androidContext, uri,
147+
startListener)
148+
service.start()
149+
```
150+
</td><td>
151+
152+
```swift
153+
let service = LCMicroService(url:url!,
154+
delegate:self)
155+
service?.start()
156+
...
157+
func onStart(_ service: LCMicroService) {
158+
// .. The environment is live, but the
159+
// startup JS code (from the URI) has
160+
// not been executed yet.
161+
}
162+
```
163+
</td></tr></tbody>
164+
</table>
165+
166+
A micro service communicates with the host through a simple [`EventEmitter`](https://nodejs.org/docs/latest-v10.x/api/events.html) interface, eponymously called `LiquidCore`. For example, in your JavaScript startup code:
167+
168+
```javascript
169+
LiquidCore.emit('my_event', {foo: "hello, world", bar: 5, l337 : ['a', 'b'] })
170+
```
171+
172+
On the app side, the host app can listen for events:
173+
174+
<table ><tbody><tr><td>
175+
176+
#### Android Kotlin
177+
</td><td>
178+
179+
#### iOS Swift
180+
</td></tr><tr><td>
181+
182+
```kotlin
183+
val listener = MicroService.EventListener {
184+
service, event, payload ->
185+
android.util.Log.i("Event:" + event,
186+
payload.getString("foo"))
187+
// logs: I/Event:my_event: hello, world
188+
}
189+
service.addEventListener("my_event", listener)
190+
```
191+
192+
</td><td>
193+
194+
```swift
195+
service.addEventListener("my_event", listener:self)
196+
...
197+
func onEvent(_ service: LCMicroService, event: String,
198+
payload: Any?) {
199+
var p = (payload as! Dictionary<String,AnyObject>)
200+
NSLog(format:"Event: %@: %@", args:event, p["foo"]);
201+
// logs: Event:my_event: hello, world
202+
}
203+
```
204+
</td></tr></tbody>
205+
</table>
206+
207+
Similarly, the micro service can listen for events from the host:
208+
209+
<table ><tbody><tr><td>
210+
211+
#### Android Kotlin
212+
</td><td>
213+
214+
#### iOS Swift
215+
</td></tr><tr><td>
216+
217+
```kotlin
218+
val payload = JSONObject()
219+
payload.put("hallo", "die Weld")
220+
service.emit("host_event", payload)
221+
```
222+
223+
</td><td>
224+
225+
```swift
226+
var payload = ["hallo" : "die Weld"]
227+
service.emitObject("host_event", object:payload)
228+
```
229+
230+
</td></tr></tbody>
231+
</table>
232+
233+
Then, in Javascript:
234+
235+
```javascript
236+
LiquidCore.on('host_event', function(msg) {
237+
console.log('Hallo, ' + msg.hallo)
238+
})
239+
```
240+
241+
LiquidCore creates a convenient virtual file system so that instances of micro services do not unintentionally or maliciously interfere with each other or the rest of the Android/iOS filesystem. The file system is described in detail [here](https://github.com/LiquidPlayer/LiquidCore/wiki/LiquidCore-File-System).
242+
243+
## API Documentation
244+
245+
[**Android Javadocs (liquidcore-Nodejs)**](https://liquidplayer.github.io/LiquidCoreAndroid/index.html)
246+
247+
[**Android Javadocs (liquidcore-V8)**](https://liquidplayer.github.io/LiquidV8/index.html)
248+
249+
[**iOS Objective-C/Swift**](https://liquidplayer.github.io/LiquidCoreiOS/index.html)
250+
251+
252+
## License
253+
254+
Copyright (c) 2014 - 2020 LiquidPlayer
255+
256+
Distributed under the MIT License. See [LICENSE.md](https://github.com/LiquidPlayer/LiquidCore/blob/master/LICENSE.md) for terms and conditions.

0 commit comments

Comments
 (0)