https://github.com/younatics/react-native-integration-with-existing-app
React Native Integration with existing app
https://github.com/younatics/react-native-integration-with-existing-app
integration react reactnative
Last synced: 5 months ago
JSON representation
React Native Integration with existing app
- Host: GitHub
- URL: https://github.com/younatics/react-native-integration-with-existing-app
- Owner: younatics
- Created: 2017-06-28T07:41:07.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2017-07-31T01:51:34.000Z (about 8 years ago)
- Last Synced: 2023-10-04T21:49:21.822Z (about 2 years ago)
- Topics: integration, react, reactnative
- Size: 7.81 KB
- Stars: 53
- Watchers: 6
- Forks: 10
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# React Native [0.45.1] Integration with the existing apps
## Purpose
This repository was made for React Natvie users who want to integrate RN[0.45.1] to the existing application using Swift3, Obbjective-C, JAVA, Kotlin. [Integration with existing apps](http://facebook.github.io/react-native/releases/next/docs/integration-with-existing-apps.html#integration-with-existing-apps) is well documented, but I wanted to make it more easy. This document was recorded after the recent test. Feel free to make Pull Request.
Thanks.## Develop Enviroment
This document is based on below version. React Native currently changes a lot, so be careful.```javascript
"dependencies": {
"react": "16.0.0-alpha.12",
"react-native": "0.45.1"
}
```
If you have `iOS` and `Android` application independently, this will be the perfect guide for you. Please follow these steps.## Getting started
### Step 1. Install tools and init project
#### Install tools
you can also see this in [Getting Started](http://facebook.github.io/react-native/releases/next/docs/getting-started.html)
```
brew install node
brew install watchman
npm install -g react-native-cli
```If you are all done with the above, init your project.
```
react-native init ReactProject
```
In your `ReactProject` directory, you can find `package.json`. this should look like this.
```javascript
{
"name": "ReactProject",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest"
},
"dependencies": {
"react": "16.0.0-alpha.6",
"react-native": "0.44.0"
},
"devDependencies": {
"babel-jest": "20.0.3",
"babel-preset-react-native": "1.9.2",
"jest": "20.0.4",
"react-test-renderer": "16.0.0-alpha.6"
},
"jest": {
"preset": "react-native"
}
}
```> you can't use `expo` when you integrate with existing apps.
---
### Step 2. Add postinstall in package.json
```javascript
{
"name": "ReactProject",
"version": "0.0.1",
"private": true,
"scripts": {
"postinstall": "sed -i '' 's/#import /#import \"RCTValueAnimatedNode.h\"/' ./node_modules/react-native/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.h",
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest"
},
"dependencies": {
"react": "16.0.0-alpha.12",
"react-native": "0.45.1"
},
"devDependencies": {
"babel-jest": "20.0.3",
"babel-preset-react-native": "2.0.0",
"jest": "20.0.4",
"react-test-renderer": "16.0.0-alpha.12"
},
"jest": {
"preset": "react-native"
}
}
```
Currently, RN 0.45.1 have a problem in `iOS - #import `. You need to change it to `#import "RCTValueAnimatedNode.h`. So use `postinstall`---
### Step 3. Git clone your iOS and Android Project
Main purpose of this step is to make a structure for configuration management. You can just copy and paste to `/android` directory and `/iOS` directory. or `git clone` to make a structure as below.
```
[React native repository]
|
|- /android [Android repository]
|- /ios [iOS repository]
```---
### Step4. Modify iOS project
You can do this step easily with the iOS depedency tool `cocoapods`. Add libraries in `Podfile` and `pod install`
```ruby
#React Native
pod 'React', :path => '../node_modules/react-native', :subspecs => [
'Core',
'RCTText',
'RCTNetwork',
'RCTImage',
'RCTWebSocket',
'DevSupport',
'BatchedBridge',
'RCTAnimation'
]
pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
```
Make `UIViewController` to present `React Native view`
```Swift
import UIKit
import React
import SnapKitclass ReactViewController: UIViewController, ZBAnSimPopupDelegate {
var reactView: RCTRootView!
var item_id: Int?override func loadView() {
super.loadView()
guard let id = item_id else { return }
let mockData = ["item_id": "\(id)"]
self.reactView = ReactBridge.shared.viewForModule("ReactProject", initialProperties: mockData)
self.view.addSubview(self.reactView)
self.reactView.snp.makeConstraints { (m) in
m.edges.equalTo(self.view)
}
}
}
```
Add `React Bridge` to communicate with `index.ios.js` <-> `UIViewController`. `forHotReloading` flag is for compile bundle or localhost.
```Swift
let localUrl = "http://localhost:8081/index.ios.bundle?platform=ios&dev=true"
let forHotReloading = falseclass ReactBridge: NSObject {
static let shared = ReactBridge()
}
extension ReactBridge: RCTBridgeDelegate {
func sourceURL(for bridge: RCTBridge!) -> URL! {
return URL(string: localUrl)
}
func createBridgeIfNeeded() -> RCTBridge {
let bridge = RCTBridge.init(delegate: self, launchOptions: nil)
return bridge ?? RCTBridge()
}
func viewForModule(_ moduleName: String, initialProperties: [String : Any]?) -> RCTRootView {
if forHotReloading {
let viewBridge = createBridgeIfNeeded()
let rootView: RCTRootView = RCTRootView(
bridge: viewBridge,
moduleName: moduleName,
initialProperties: initialProperties)
return rootView
} else {
if let iosBundle = Bundle.main.url(forResource: "main", withExtension: "jsbundle") {
guard let bundleRootView = RCTRootView(bundleURL: iosBundle, moduleName: moduleName, initialProperties: initialProperties, launchOptions: nil) else { return RCTRootView() }
return bundleRootView
}
}
return RCTRootView()
}
}
```
Add `ReactManager.swift` to call method with `Native` <-> `React-Native`
```Swift
@objc(ReactManager) class ReactManager: NSObject {
var bridge: RCTBridge!
@objc func back(_ reactTag: NSNumber) {
DispatchQueue.main.async {
if let view = self.bridge.uiManager.view(forReactTag: reactTag) {
let presentedViewController = view.reactViewController()
presentedViewController?.navigationController?.pop(animated: true)
}
}
}
}
```
We need an addtional `Objective-C file` beacuse `React` uses macro. Add `ReactManagerBridge.m` file like this
```Swift
#import "ReactManagerBridge.h"
#import "zigbang-Swift.h"@implementation ReactManagerBridge
RCT_EXPORT_MODULE(ReactManager);
RCT_EXPORT_METHOD(back:(nonnull NSNumber *)reactTag) {
ReactManager* reactManager = [[ReactManager alloc] init];
reactManager.bridge = _bridge;
[reactManager back:reactTag];}
@end
```---
### Step4. Modify Android projectadd dependency in `build.gradle`
```
allprojects {
repositories {
mavenLocal()
jcenter()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
}
}
```
in your `app.gradle`. I added `exclude` becuase it conflicts with existing dependecies```
compile ("com.facebook.react:react-native:+") {
exclude group:'com.facebook.stetho', module:'stetho'
}```
Add `ReactInstanceManager` to use it in `React Native`. I recommend to make an instance in `Mainapplication` because it takes some time to generate an instance
```Java
public static ReactInstanceManager react;this.react = ReactInstanceManager.builder()
.setApplication(this)
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
.addPackage(new MainReactPackage())
.addPackage(new ReactManagerBridge())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
```Modify your `ReactRootView` where you want to use. Also, add props to pass parameter
```Java
@BindView(R.id.container)
ReactRootView container;
react = MainApplication.react;Bundle props = new Bundle();
props.putString("items", new Gson().toJson(response));
container.startReactApplication(react, "ReactProject", props);```
Add bridge to communicate with Native
```Java
class ReactManagerBridge() : ReactPackage {override fun createJSModules(): List> {
return emptyList()
}override fun createViewManagers(reactContext: ReactApplicationContext): List> {
val modules = ArrayList>()
return modules
}override fun createNativeModules(reactContext: ReactApplicationContext): List {
val modules = ArrayList()modules.add(ReactManager(reactContext))
return modules
}}
```Add reactmanager to call method
```Java
class ReactManager(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {fun ReactManager(reactContext: ReactApplicationContext) {
super.getReactApplicationContext()
}override fun getName(): String {
return "ReactManager"
}@ReactMethod
fun alert(message: String) {
Toast.makeText(getReactApplicationContext(), message, Toast.LENGTH_LONG).show()
}
}
```This is all about setting your react native to existing application!