Installation and setup new project
If you go to main React-native site, you can see these steps below to setup:
Requirements
OS X - This repo only contains the iOS implementation right now, and Xcode only runs on Mac.
New to Xcode? Download it from the Mac App Store.
Homebrew is the recommended way to install node, watchman, and flow.
brew install node.
brew install --HEAD watchman. We recommend installing watchman, otherwise you might hit a node file watching bug.
brew install flow. If you want to use flow.
Quick start
npm install -g react-native-cli
react-native init AwesomeProject
In the newly created folder AwesomeProject/
Open AwesomeProject.xcodeproj and hit run in Xcode
Open index.ios.js in your text editor of choice and edit some lines
Hit cmd+R (twice) in your iOS simulator to reload the app and see your change!
Congratulations! You've just successfully run and modified your first React Native app.
A closer look at application creation
Let's look what's inside the AwesomeProject/ just created:
AwesomeProject.xcodeproj/
Podfile
iOS/
index.ios.js
node_modules/
package.json
To give you the full picture, here is what exactly happens when running react-native init AwesomeProject
:
- A folder named AwesomeProject is created
- In it, the package.json file is created
- npm install --save react-native is run, which installs react-native and its dependencies into AwesomeProject/node_modules and declares react-native as a dependency of your project in AwesomeProject/package.json
- The globally installed react-native CLI tool then hands over control to the local CLI tool that has just been installed into AwesomeProject/node_modules/react-native/local-cli/cli.js
- This in turn executes AwesomeProject/node_modules/react-native/init.sh, which is yet another helper script that takes care of putting the boiler plate application code in place, like the
minimal React Native code in file index.ios.js and the Objective-C code plus other goodies
in subfolder iOS, and the Xcode® project definition in subfolder AwesomeProject.xcodeproj
We already saw that the React Native based JavaScript code that makes up our actual application lives in index.ios.js
.
The package.json
file is no surprise for those who already worked with Node.js; it defines some metadata for our project and, most importantly, declares react-native (this time, the real thing, i.e.,
the actual framework that makes our application possible) as a dependency of our own project.
The node_modules
folder is simply a result of the npm install run that took place during project
initialization. It contains the react-native code, which in turn consists of other NPM dependencies,
helper scripts, and a lot of JavaScript and Objective-C code.
The initialization process also provided the minimum Xcode project definitions plus some Objective-C boilerplate code, which allows us to open our new project in Xcode and to instantly run the application without any further ado. All of this could have been done manually, but would include a lot of steps that are identical no matter what kind of application we are going to write, thus it makes sense to streamline this process via react-native init.
Podfile
is similar to package.json
; it declares Objective-C library dependencies for the CocoaPods
dependency manager. We will talk about this in more detail later in the book, and ignore it for
now.
The takeaway here is that our AwesomeProject project is multiple things at once. It is an Xcode® project,
but it’s also an NPM project. It’s a React Native based JavaScript application, but it also contains
some iOS glue code that is needed to make our JavaScript code run on iOS in the first place.
Troubleshooting
In case your Xcode built failed. Please follow steps below:
- Clone main react native repository from github:
git clone https://github.com/facebook/react-native
- Copy Examples/SampleApp to Examples/AwesomeProject
mkdir Examples/AwesomeProject
cp -R Examples/SampleApp/* Examples/AwesomeProject
- Run packager.sh to point to AwesomeProject just created:
packager/packager.sh --root=./Examples/AwesomeProject
- Now reopen again AwesomeProject in Xcode and start building.
Build and run on device:
-
In order to build and run on your device, follow these steps below:
curl http://localhost:8081/index.ios.js > main.jsbundle
In Xcode, click on Project name, goto Build Phases, and link the main.jsbundle to Assets
Open AppDelegate.m, remove the default code, and edit as below:**
NSURL *jsCodeLocation;
jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"SampleApp" launchOptions:self.launchOptions];
-
Now try to build and run project on your device.
So what is React-Native ?
Phuhh. Congratulation if you come to this step. I hope you're seeing your AwesomeProject running on your iPhone 5. Now it's time to understand what's going on.
In traditional iOS architecture, if you're an artist, you have:
- A
Canvas
, it's theUIWindow
class you often use to create your window application. - A
Brush
, it's theUIViewController
that you use to draw something onCanvas
- A
Paint
, it's the color and the view for your application. You use it with aBrush
, and paint on aCanvas
.
For more complex application design, you will have many Brush
, as well as Paint
. They're nested to others in a top-down manner to compose GUI.
Example:
// Creating the Canvas
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
// Creating the Brush
MyViewController *rootViewController = [[MyViewController alloc] init];
rootViewController.launchOptions = launchOptions;
// Make the Canvas use the Brush
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
You create Canvas
with Frame
, then create the Brush
, link it to the Canvas
to make it the rootViewController
.
Inside the Brush
, now you can create Paint
, it's the subView
of the Brush
:
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"AdmobTest" launchOptions:self.launchOptions];
rootView.frame = CGRectMake(0, 50, viewRect.size.width, viewRect.size.height - 50);
[self.view addSubview:rootView];
You can add as many subView
as you want.
Sweet!
So React-Native
is just a Paint
. If you see in the code below:
NSURL *jsCodeLocation;
jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"SampleApp" launchOptions:self.launchOptions];
you will see that to create new React-Native
view, you have to pass two parameters:
-
The
jsLocation
address: it's the local or remote url for theReact component
. -
The module name: It's the name that you register with
AppRegistry
inindex.ios.js
file:AppRegistry.registerComponent('SampleApp', () => SampleApp);
After creating the React-Native View
, now you can use its properties like any other iOS View
, it's the Paint
of your project.
Exercise:
It's enough for theory. There is a small exercise for you before you come to chapter 2.
Create new react native view, and put it inside a `ViewController`, style the view with backgroundColor blue.
Solution:
Please do the exercise by yourself before coming here!
If you're completely new to iOS, i recommend you to learn some basic Objective-C. There is a good resource here for you to learn.
Now create two file MyViewController.h
and MyViewController.m
in xcode. The code for each file is listed below:
// MyViewController.h
#import <UIKit/UIKit.h>
#import "RCTRootView.h"
@interface MyViewController : UIViewController
@property (weak, nonatomic) NSDictionary *launchOptions;
@end
// MyViewController.m
#import "MyViewController.h"
@implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL *jsCodeLocation;
jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"AdmobTest" launchOptions:self.launchOptions];
rootView.frame = CGRectMake(0, 50, viewRect.size.width, viewRect.size.height - 50);
[self.view addSubview:rootView];
}
@end
Now modify the default SampleApp's AppDelegate.m
:
#import "AppDelegate.h"
#import "MyViewController.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//NSURL *jsCodeLocation;
// Loading JavaScript code - uncomment the one you want.
// OPTION 1
// Load from development server. Start the server from the repository root:
//
// $ npm start
//
// To run on device, change `localhost` to the IP address of your computer, and make sure your computer and
// iOS device are on the same Wi-Fi network.
//jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle"];
// OPTION 2
// Load from pre-bundled file on disk. To re-generate the static bundle, run
//
// $ curl http://localhost:8081/index.ios.bundle -o main.jsbundle
//
// and uncomment the next following line
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
//UIViewController *rootViewController = [[UIViewController alloc] init];
MyViewController *rootViewController = [[MyViewController alloc] init];
rootViewController.launchOptions = launchOptions;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
@end
You'll see i comment out all default SampleApp
code, and put in our new MyViewController created above.
Try to build and run project again. You will understand what's React Native View is about.
We're ready to go to next step: Flux Application Architecture on React Native.
You can read all chapters at http://www.reactnativebook.com