├── .gitignore ├── README.md ├── bin └── rnnb.js ├── boot.sh ├── findProject.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | npm-debug.log 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Network Boot 2 | 3 | If you are tired of manually setting your bundle host IP when moving between networks, or having conflicts when sharing the network bootstrapping code in a team (that's in `AppDelegate.m`), this library will autoconfigure the host IP for you automatically. 4 | 5 | 6 | To start, run: 7 | 8 | ``` 9 | $ npm i react-native-network-boot -D 10 | ``` 11 | 12 | 13 | ### Integration 14 | 15 | In `AppDelegate.m`, replace the old host loading code with this: 16 | 17 | ```objective-c 18 | NSString *host = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"RNHost"]; 19 | jsCodeLocation = [NSURL URLWithString: [NSString stringWithFormat:@"http://%@:8081/index.ios.bundle?platform=ios&dev=true", host]]; 20 | ``` 21 | 22 | Run the initializer that automatically adds a Run Script phase, in your React Native project folder: 23 | 24 | ``` 25 | $ ./node_modules/.bin/rnnb ios 26 | ``` 27 | 28 | Or add a Run Script phase manually, with this script as its content: 29 | 30 | ``` 31 | ../node_modules/react-native-network-boot/boot.sh 32 | ``` 33 | 34 | ### How Does it Work? 35 | 36 | Rather than hardcode the IP of your local workstation, it takes a different and more flexible approach: 37 | 38 | * Store current host in `Info.plist` at app packaging time (out of your source tree) 39 | * Provide a Run Script that keeps this value up to date on each build 40 | * Provide an example network bootstrapping code (see below) to use the value from your `Info.plist` instead of the hard coded one. 41 | 42 | 43 | 44 | # Contributing 45 | 46 | Fork, implement, add tests, pull request, get my everlasting thanks and a respectable place here :). 47 | 48 | # Copyright 49 | 50 | Copyright (c) 2016 [Dotan Nahum](http://gplus.to/dotan) [@jondot](http://twitter.com/jondot). See [LICENSE](LICENSE.txt) for further details. 51 | -------------------------------------------------------------------------------- /bin/rnnb.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | //use this instead? https://github.com/flatiron/prompt 3 | 4 | if(process.argv.length == 3 && process.argv[2] == 'ios'){ 5 | var xcode = require('xcode'), 6 | fs = require('fs'), 7 | inquirer = require('inquirer'), 8 | findProject = require('../findProject') 9 | 10 | var question = 11 | { 12 | type: 'input', 13 | name: 'pbxproj', 14 | message: 'Your project.pbxproj location so I can add a Run Script phase?', 15 | default: '', 16 | validate: function (value) { 17 | if (value) { 18 | return true; 19 | } 20 | 21 | return 'Please your main project.pbxproj location'; 22 | } 23 | } 24 | question.default = findProject(process.cwd()) 25 | 26 | var comment = 'react native boot run script phase' 27 | var script = "../node_modules/react-native-network-boot/boot.sh" 28 | 29 | inquirer.prompt([ question ]).then(function (answers) { 30 | var projectPath = answers['pbxproj'] 31 | myProj = xcode.project(projectPath) 32 | myProj.parse(function (err) { 33 | var item = myProj.pbxItemByComment(comment, 'PBXShellScriptBuildPhase') 34 | if(item){ 35 | console.log("Already initialized.") 36 | }else{ 37 | myProj.addBuildPhase([], 'PBXShellScriptBuildPhase', comment, null, null, null, script) 38 | fs.writeFileSync(projectPath, myProj.writeSync()); 39 | console.log('Initialized in ' + projectPath); 40 | } 41 | }); 42 | }) 43 | }else{ 44 | console.log("Currently only 'rnnb ios' is supported.") 45 | } 46 | -------------------------------------------------------------------------------- /boot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # todo: improve this, some boxes has en5, en1, etc 3 | 4 | # use ifconfig, remove loopack and virtualbox IPs 5 | rnhost=`ifconfig | sed -En 's/127.0.0.1//;s/127.94.0.(1|2)//;s/192.168.99.*//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p' | head -n1` 6 | plist=${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/../${INFOPLIST_PATH} 7 | 8 | case "$CONFIGURATION" in 9 | Debug) 10 | ;; 11 | "") 12 | echo "$0 must be invoked by Xcode" 13 | exit 1 14 | ;; 15 | *) 16 | echo "$0 will not work in release configurations - configure by hand" 17 | exit 0 18 | ;; 19 | esac 20 | 21 | echo Setting ATS exception for arbitrary loads 22 | /usr/libexec/PlistBuddy -c "Delete :NSAppTransportSecurity" $plist &>/dev/null 23 | /usr/libexec/PlistBuddy -c "Add :NSAppTransportSecurity:NSAllowsArbitraryLoads bool true" $plist 24 | 25 | echo Setting React Native RNHost variable to $rnhost 26 | /usr/libexec/PlistBuddy -c "Add :RNHost string" $plist 27 | /usr/libexec/PlistBuddy -c "Set :RNHost ${rnhost}" $plist 28 | echo Done. 29 | -------------------------------------------------------------------------------- /findProject.js: -------------------------------------------------------------------------------- 1 | // based on findProject from rnpm 2 | var glob = require('glob'), 3 | path = require('path') 4 | 5 | var GLOB_PATTERN = '**/*.xcodeproj/project.pbxproj' 6 | var TEST_PROJECTS = /test|example|sample/i 7 | var IOS_BASE = 'ios' 8 | var GLOB_EXCLUDE_PATTERN = ['**/@(Pods|node_modules)/**'] 9 | 10 | module.exports = function findProject(folder) { 11 | var projects = glob 12 | .sync(GLOB_PATTERN, { 13 | cwd: folder, 14 | ignore: GLOB_EXCLUDE_PATTERN, 15 | }) 16 | .filter(function(project){ 17 | return path.dirname(project) === IOS_BASE || !TEST_PROJECTS.test(project) 18 | }); 19 | 20 | if (projects.length === 0) { 21 | return null; 22 | } 23 | 24 | return projects[0] 25 | }; 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-network-boot", 3 | "version": "1.0.6", 4 | "description": "", 5 | "bin":{ "rnnb" : "./bin/rnnb.js" }, 6 | "main": "index.js", 7 | "scripts": { 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "glob": "^7.0.3", 14 | "inquirer": "^1.0.2", 15 | "xcode": "git://github.com/jondot/node-xcode.git" 16 | } 17 | } 18 | --------------------------------------------------------------------------------