|
| 1 | +# Native Xcode Sample using a Node Project folder |
| 2 | + |
| 3 | +An iOS Xcode project that uses the [`Node.js on Mobile`]( https://github.com/janeasystems/nodejs-mobile) shared library, as an example of using a Node Project folder inside the Application. |
| 4 | + |
| 5 | +The sample app runs the node.js engine in a background thread to start an HTTP server on port 3000 and return the `process.versions` value. The app's Main ViewController UI has a button to query the server and show the server's response. Alternatively, it's also possible to access the server from a browser running on a different device connected to the same local network. |
| 6 | + |
| 7 | +## Prerequisites |
| 8 | +To run the sample on iOS you need: |
| 9 | + - A macOS device with the latest Xcode (Xcode version 9 or greater) with the iOS SDK version 11.0 or higher. |
| 10 | + - One iOS device with arm64 architecture, running iOS version 11.0 or higher. |
| 11 | + - A valid Apple Developer Account. |
| 12 | + |
| 13 | +## How to run |
| 14 | + - 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.4/nodejs-mobile-v0.1.4-ios.zip). |
| 16 | + - Copy the `NodeMobile.framework` file inside the zip's `Release-universal` path to this project's `NodeMobile/` folder (there's a `copy-NodeMobile.framework-here` empty file inside the project's folder for convenience). |
| 17 | + - In Xcode import the `ios/native-xcode-node-folder/native-xcode-node-folder.xcodeproj` project. |
| 18 | + - Select one physical iOS device as the run target. |
| 19 | + - 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. |
| 20 | + - 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. |
| 21 | + |
| 22 | +## How the sample was developed |
| 23 | + |
| 24 | +This sample was built on top of the [`native-xcode` sample from this repo](https://github.com/janeasystems/nodejs-mobile-samples/tree/master/ios/native-xcode), with the same functionality, but uses a `nodejs-project` folder that contains the node part of the project. |
| 25 | + |
| 26 | +### Create the `nodejs-project` folder |
| 27 | + |
| 28 | +Create a `nodejs-project` folder inside the project and add it as a Resource to the Xcode project. |
| 29 | +It contains two files inside: |
| 30 | + |
| 31 | +- `main.js` |
| 32 | +```js |
| 33 | +var http = require('http'); |
| 34 | +var versions_server = http.createServer( (request, response) => { |
| 35 | + response.end('Versions: ' + JSON.stringify(process.versions)); |
| 36 | +}); |
| 37 | +versions_server.listen(3000); |
| 38 | +``` |
| 39 | + |
| 40 | +- `package.json` |
| 41 | +``` |
| 42 | +{ |
| 43 | + "name": "native-xcode-node-project", |
| 44 | + "version": "0.0.1", |
| 45 | + "description": "node part of the project", |
| 46 | + "main": "main.js", |
| 47 | + "author": "janeasystems", |
| 48 | + "license": "" |
| 49 | +} |
| 50 | +``` |
| 51 | + |
| 52 | +> Having a `nodejs-project` path with a `package.json` inside is helpful for using npm modules, by running `npm install {module_name}` inside `nodejs-project` so that the modules are also packaged with the application and made available at runtime. |
| 53 | +
|
| 54 | +### Start the node runtime from the Node Project |
| 55 | + |
| 56 | +Change the code that starts the node runtime in `AppDelegate.m` to find the `main.js` inside the Application's bundle and start from there: |
| 57 | + |
| 58 | +```objectivec |
| 59 | +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { |
| 60 | + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ |
| 61 | + NSString* srcPath = [[NSBundle mainBundle] pathForResource:@"nodejs-project/main.js" ofType:@""]; |
| 62 | + NSArray* nodeArguments = [NSArray arrayWithObjects: |
| 63 | + @"node", |
| 64 | + srcPath, |
| 65 | + nil |
| 66 | + ]; |
| 67 | + [NodeRunner startEngineWithArguments:nodeArguments]; |
| 68 | + }); |
| 69 | + return YES; |
| 70 | +} |
| 71 | +``` |
0 commit comments