Skip to content

Commit f58fe17

Browse files
react-native: create SuspendResume sample
1 parent c239c31 commit f58fe17

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+2587
-3
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ This is a collection of samples showcasing the use of [Node.js on Mobile](https:
55
It contains the following samples:
66
* Android: [Native Gradle Sample](https://github.com/janeasystems/nodejs-mobile-samples/tree/master/android/native-gradle)
77
* iOS: [Native Xcode Sample](https://github.com/janeasystems/nodejs-mobile-samples/tree/master/ios/native-xcode)
8-
8+
* React-Native: [Suspend Resume Sample](https://github.com/janeasystems/nodejs-mobile-samples/tree/master/react-native/SuspendResume)

ios/native-xcode/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ To run the sample on iOS you need:
1212

1313
## How to run
1414
- Clone this project.
15-
- Download the Node.js on Mobile shared library from [here](https://github.com/janeasystems/nodejs-mobile/releases/download/nodejs-mobile-v0.1.1/nodejs-mobile-v0.1.1-ios.zip).
15+
- Download the Node.js on Mobile shared library from [here](https://github.com/janeasystems/nodejs-mobile/releases/download/nodejs-mobile-v0.1.2/nodejs-mobile-v0.1.2-ios.zip).
1616
- Copy the `libnode.framework` file inside the zip to this project's `libnode/` folder (there's a `copy-libnode.framework-here` empty file inside the project's folder for convenience).
1717
- In Xcode import the `ios/native-xcode/native-xcode.xcodeproj` project.
1818
- Select one physical iOS device as the run target.
@@ -40,7 +40,7 @@ Using the Xcode 9's "Create a new Xcode Project" wizard, create a new Project wi
4040
#### Copy `libnode.framework` to the project structure:
4141

4242
Create the `libnode/` folder path in the project's root folder, next to the `native-xcode.xcodeproj` package.
43-
Download the [Node.js on Mobile release](https://github.com/janeasystems/nodejs-mobile/releases/download/nodejs-mobile-v0.1.1/nodejs-mobile-v0.1.1-ios.zip), unzip it and copy `libnode.framework` to `libnode/`.
43+
Download the [Node.js on Mobile release](https://github.com/janeasystems/nodejs-mobile/releases/download/nodejs-mobile-v0.1.2/nodejs-mobile-v0.1.2-ios.zip), unzip it and copy `libnode.framework` to `libnode/`.
4444

4545
#### Embed the `libnode.framework` in the binary.
4646

react-native/SuspendResume/.babelrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"presets": ["react-native"]
3+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
[android]
3+
target = Google Inc.:Google APIs:23
4+
5+
[maven_repositories]
6+
central = https://repo1.maven.org/maven2
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
[ignore]
2+
; We fork some components by platform
3+
.*/*[.]android.js
4+
5+
; Ignore "BUCK" generated dirs
6+
<PROJECT_ROOT>/\.buckd/
7+
8+
; Ignore unexpected extra "@providesModule"
9+
.*/node_modules/.*/node_modules/fbjs/.*
10+
11+
; Ignore duplicate module providers
12+
; For RN Apps installed via npm, "Libraries" folder is inside
13+
; "node_modules/react-native" but in the source repo it is in the root
14+
.*/Libraries/react-native/React.js
15+
.*/Libraries/react-native/ReactNative.js
16+
17+
[include]
18+
19+
[libs]
20+
node_modules/react-native/Libraries/react-native/react-native-interface.js
21+
node_modules/react-native/flow
22+
flow/
23+
24+
[options]
25+
emoji=true
26+
27+
module.system=haste
28+
29+
munge_underscores=true
30+
31+
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
32+
33+
suppress_type=$FlowIssue
34+
suppress_type=$FlowFixMe
35+
suppress_type=$FixMe
36+
37+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(4[0-9]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
38+
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(4[0-9]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
39+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
40+
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
41+
42+
unsafe.enable_getters_and_setters=true
43+
44+
[version]
45+
^0.49.1
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.pbxproj -text

react-native/SuspendResume/.gitignore

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# OSX
2+
#
3+
.DS_Store
4+
5+
# Xcode
6+
#
7+
build/
8+
*.pbxuser
9+
!default.pbxuser
10+
*.mode1v3
11+
!default.mode1v3
12+
*.mode2v3
13+
!default.mode2v3
14+
*.perspectivev3
15+
!default.perspectivev3
16+
xcuserdata
17+
*.xccheckout
18+
*.moved-aside
19+
DerivedData
20+
*.hmap
21+
*.ipa
22+
*.xcuserstate
23+
project.xcworkspace
24+
25+
# Android/IntelliJ
26+
#
27+
build/
28+
.idea
29+
.gradle
30+
local.properties
31+
*.iml
32+
33+
# node.js
34+
#
35+
node_modules/
36+
npm-debug.log
37+
yarn-error.log
38+
39+
# BUCK
40+
buck-out/
41+
\.buckd/
42+
*.keystore
43+
44+
# fastlane
45+
#
46+
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
47+
# screenshots whenever they are needed.
48+
# For more information about the recommended setup visit:
49+
# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
50+
51+
fastlane/report.xml
52+
fastlane/Preview.html
53+
fastlane/screenshots
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}

react-native/SuspendResume/README.md

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
# React Native Suspend Resume Sample
2+
3+
A React-Native project that uses the [`Node.js for Mobile Apps React Native plugin`]( https://github.com/janeasystems/nodejs-mobile-react-native) shared library.
4+
5+
The sample app runs the Node.js engine in a background thread to start an HTTP server on port 3001 and return the `process.versions` value. It also uses the react-native bridge to send suspend and resume commands to close and reopen the HTTP server when the application goes to the background and back to the foreground. The react-native bridge also returns the process.versions into the UI.
6+
7+
It's possible to access the server from a browser running on a different device connected to the same local network, to verify that the Node.js process running in the background is closing the HTTP server when the app leaves the foreground state.
8+
9+
## How to run
10+
- Clone this project.
11+
- Run the required npm and react-native commands to install the required node modules in the project root (`react-native/SuspendResume/`):
12+
- `npm install`
13+
- `react-native link`
14+
15+
### iOS
16+
17+
As currently only `arm64` binaries are available, you need a physical device to run the project, so you'll also have to sign the project.
18+
19+
- Open the `ios/SuspendResume.xcodeproj` project file in Xcode.
20+
- Select one of the physical iOS devices as the run target.
21+
- In the project settings (click on the project main node), in the `Signing` portion of the `General` tab, select a valid Team and handle the provisioning profile creation/update. If you get an error that the bundle identifier cannot be used, you can simply change the bundle identifier to a unique string by appending a few characters to it.
22+
- Run the app. If the build process doesn't start the app right away, you might have to go to `Settings>General` in the device and enter `Device Management` or `Profiles & Device Management` to manually accept the profile.
23+
24+
25+
### Android
26+
27+
You may need to open your app's `/android` folder in `Android Studio`, so that it detects, downloads and cofigures requirements that might be missing, like the `NDK` and `CMake` to build the native code part of the project.
28+
29+
- Run `react-native run-android` in the project's root(`react-native/SuspendResume/`).
30+
31+
#### Troubleshooting
32+
On Android applications, the `react-native` build process is sometimes unable to rebuild assets.
33+
If you are getting errors while building the application using `react-native run-android`, the following commands can help you do a clean rebuild of the project, when run in the project's root(`react-native/SuspendResume/`).
34+
35+
On Windows:
36+
```sh
37+
cd android
38+
gradlew clean
39+
cd ..
40+
react-native run-android
41+
```
42+
43+
On Linux/macOS:
44+
```sh
45+
cd android
46+
./gradlew clean
47+
cd ..
48+
react-native run-android
49+
```
50+
51+
## Project structure
52+
53+
### Node.js Part
54+
55+
In `node-root/node-app/main.js` You can find the node.js back-end, that controls the HTTP server as it receives lifecycle events from the React Native part of the project:
56+
57+
```js
58+
var http = require('http');
59+
var rn_bridge = require('./rn-bridge/index.js');
60+
61+
let msg_number=0;
62+
63+
var listVersionsServer = http.createServer( (request, response) => {
64+
response.end('Versions: ' + JSON.stringify(process.versions));
65+
});
66+
67+
let listVersionsHTTPServer = listVersionsServer.listen(3001);
68+
69+
// Echo every message received from react-native.
70+
rn_bridge.channel.on('message', (msg) => {
71+
switch(msg) {
72+
case 'versions':
73+
msg_number++;
74+
rn_bridge.channel.send(
75+
"This is message number " +
76+
msg_number +
77+
". Versions: " +
78+
JSON.stringify(process.versions)
79+
);
80+
break;
81+
case 'suspend':
82+
listVersionsHTTPServer.close();
83+
break;
84+
case 'resume':
85+
if(!listVersionsHTTPServer.listening)
86+
listVersionsHTTPServer = listVersionsServer.listen(3001);
87+
break;
88+
default:
89+
break;
90+
}
91+
});
92+
93+
// Inform react-native node is initialized.
94+
rn_bridge.channel.send("Node was initialized.");
95+
```
96+
97+
### React Native part
98+
99+
The React Native interface takes care of querying `Node.js` for versions and showing it in the UI. It also signals when the App enters the background and comes back again, through `AppState`.
100+
101+
index.ios.js and index.android.js contents:
102+
```js
103+
...
104+
import nodejs from 'nodejs-mobile-react-native';
105+
106+
export default class SuspendResume extends Component {
107+
constructor(props){
108+
super(props);
109+
this.state = { lastNodeMessage: "No message yet." };
110+
}
111+
componentWillMount()
112+
{
113+
nodejs.start();
114+
nodejs.channel.addListener(
115+
"message",
116+
(msg) => {
117+
this.setState({lastNodeMessage: msg});
118+
},
119+
this
120+
);
121+
}
122+
componentDidMount(){
123+
AppState.addEventListener('change', (state) => {
124+
if (state === 'active') {
125+
nodejs.channel.send('resume');
126+
}
127+
if (state === 'background') {
128+
nodejs.channel.send('suspend');
129+
}
130+
});
131+
}
132+
render() {
133+
return (
134+
<View style={styles.container}>
135+
<Button title="Get Versions"
136+
onPress={() => nodejs.channel.send('versions')}
137+
/>
138+
<Text style={styles.instructions}>
139+
{this.state.lastNodeMessage}
140+
</Text>
141+
</View>
142+
);
143+
}
144+
}
145+
...
146+
```
147+
148+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import 'react-native';
2+
import React from 'react';
3+
import Index from '../index.android.js';
4+
5+
// Note: test renderer must be required after react-native.
6+
import renderer from 'react-test-renderer';
7+
8+
it('renders correctly', () => {
9+
const tree = renderer.create(
10+
<Index />
11+
);
12+
});

0 commit comments

Comments
 (0)