{"id":19760204,"url":"https://github.com/younatics/react-native-integration-with-existing-app","last_synced_at":"2025-04-30T13:32:41.554Z","repository":{"id":198221654,"uuid":"95642633","full_name":"younatics/React-Native-Integration-with-existing-app","owner":"younatics","description":"React Native Integration with existing app","archived":false,"fork":false,"pushed_at":"2017-07-31T01:51:34.000Z","size":8,"stargazers_count":53,"open_issues_count":2,"forks_count":10,"subscribers_count":6,"default_branch":"master","last_synced_at":"2023-10-04T21:49:21.822Z","etag":null,"topics":["integration","react","reactnative"],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/younatics.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2017-06-28T07:41:07.000Z","updated_at":"2023-10-04T21:54:10.383Z","dependencies_parsed_at":"2023-10-04T21:54:09.913Z","dependency_job_id":null,"html_url":"https://github.com/younatics/React-Native-Integration-with-existing-app","commit_stats":null,"previous_names":["younatics/react-native-integration-with-existing-app"],"tags_count":null,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/younatics%2FReact-Native-Integration-with-existing-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/younatics%2FReact-Native-Integration-with-existing-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/younatics%2FReact-Native-Integration-with-existing-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/younatics%2FReact-Native-Integration-with-existing-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/younatics","download_url":"https://codeload.github.com/younatics/React-Native-Integration-with-existing-app/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224214289,"owners_count":17274524,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["integration","react","reactnative"],"created_at":"2024-11-12T03:36:00.158Z","updated_at":"2024-11-12T03:36:00.763Z","avatar_url":"https://github.com/younatics.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# React Native [0.45.1] Integration with the existing apps\n\n## Purpose\nThis 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.\nThanks.\n\n## Develop Enviroment\nThis document is based on below version. React Native currently changes a lot, so be careful.\n\n```javascript\n\"dependencies\": {\n\t\t\"react\": \"16.0.0-alpha.12\",\n\t\t\"react-native\": \"0.45.1\"\n\t}\n```\nIf you have `iOS` and `Android` application independently, this will be the perfect guide for you. Please follow these steps.\n\n## Getting started\n### Step 1. Install tools and init project \n#### Install tools\nyou can also see this in [Getting Started](http://facebook.github.io/react-native/releases/next/docs/getting-started.html)\n```\nbrew install node\nbrew install watchman\nnpm install -g react-native-cli\n```\n\nIf you are all done with the above, init your project.\n```\nreact-native init ReactProject\n```\nIn your `ReactProject` directory, you can find `package.json`. this should look like this.\n```javascript\n{\n\t\"name\": \"ReactProject\",\n\t\"version\": \"0.0.1\",\n\t\"private\": true,\n\t\"scripts\": {\n\t\t\"start\": \"node node_modules/react-native/local-cli/cli.js start\",\n\t\t\"test\": \"jest\"\n\t},\n\t\"dependencies\": {\n\t\t\"react\": \"16.0.0-alpha.6\",\n\t\t\"react-native\": \"0.44.0\"\n\t},\n\t\"devDependencies\": {\n\t\t\"babel-jest\": \"20.0.3\",\n\t\t\"babel-preset-react-native\": \"1.9.2\",\n\t\t\"jest\": \"20.0.4\",\n\t\t\"react-test-renderer\": \"16.0.0-alpha.6\"\n\t},\n\t\"jest\": {\n\t\t\"preset\": \"react-native\"\n\t}\n}\n```\n\n\u003e you can't use `expo` when you integrate with existing apps.\n\n---\n### Step 2. Add postinstall in package.json\n```javascript\n{\n\t\"name\": \"ReactProject\",\n\t\"version\": \"0.0.1\",\n\t\"private\": true,\n\t\"scripts\": {\n\t\t\"postinstall\": \"sed -i '' 's/#import \u003cRCTAnimation\\\\/RCTValueAnimatedNode.h\u003e/#import \\\"RCTValueAnimatedNode.h\\\"/' ./node_modules/react-native/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.h\",\n\t\t\"start\": \"node node_modules/react-native/local-cli/cli.js start\",\n\t\t\"test\": \"jest\"\n\t},\n\t\"dependencies\": {\n\t\t\"react\": \"16.0.0-alpha.12\",\n\t\t\"react-native\": \"0.45.1\"\n\t},\n\t\"devDependencies\": {\n\t\t\"babel-jest\": \"20.0.3\",\n\t\t\"babel-preset-react-native\": \"2.0.0\",\n\t\t\"jest\": \"20.0.4\",\n\t\t\"react-test-renderer\": \"16.0.0-alpha.12\"\n\t},\n\t\"jest\": {\n\t\t\"preset\": \"react-native\"\n\t}\n}\n```\nCurrently, RN 0.45.1 have a problem in `iOS - #import \u003cRCTAnimation\\\\/RCTValueAnimatedNode.h\u003e`. You need to change it to `#import \"RCTValueAnimatedNode.h`. So use `postinstall`\n\n---\n### Step 3. Git clone your iOS and Android Project\nMain 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.\n```\n[React native repository] \n|\n|- /android [Android repository]\n|- /ios [iOS repository]\n```\n\n---\n### Step4. Modify iOS project\nYou can do this step easily with the iOS depedency tool `cocoapods`. Add libraries in `Podfile` and `pod install`\n```ruby\n#React Native\npod 'React', :path =\u003e '../node_modules/react-native', :subspecs =\u003e [\n\t'Core',\n\t'RCTText',\n\t'RCTNetwork',\n\t'RCTImage',\n\t'RCTWebSocket',\n\t'DevSupport',\n\t'BatchedBridge',\n\t'RCTAnimation'\n]\npod 'Yoga', :path =\u003e '../node_modules/react-native/ReactCommon/yoga'\n```\nMake `UIViewController` to present `React Native view`\n```Swift\nimport UIKit\nimport React\nimport SnapKit\n\nclass ReactViewController: UIViewController, ZBAnSimPopupDelegate {\n    var reactView: RCTRootView!\n\tvar item_id: Int?\n\n    override func loadView() {\n        super.loadView()\n        \n        guard let id = item_id else { return }\n        let mockData = [\"item_id\": \"\\(id)\"]\n        \n        self.reactView = ReactBridge.shared.viewForModule(\"ReactProject\", initialProperties: mockData)\n        self.view.addSubview(self.reactView)\n        \n        self.reactView.snp.makeConstraints { (m) in\n            m.edges.equalTo(self.view)\n        }\n    }\n}\n```\nAdd `React Bridge` to communicate with `index.ios.js` \u003c-\u003e `UIViewController`. `forHotReloading` flag is for compile bundle or localhost. \n```Swift\nlet localUrl = \"http://localhost:8081/index.ios.bundle?platform=ios\u0026dev=true\"\nlet forHotReloading = false\n\nclass ReactBridge: NSObject {\n    static let shared = ReactBridge()\n}\nextension ReactBridge: RCTBridgeDelegate {\n    func sourceURL(for bridge: RCTBridge!) -\u003e URL! {\n        return URL(string: localUrl)\n    }\n    \n    func createBridgeIfNeeded() -\u003e RCTBridge {\n        let bridge = RCTBridge.init(delegate: self, launchOptions: nil)\n        return bridge ?? RCTBridge()\n    }\n    \n    func viewForModule(_ moduleName: String, initialProperties: [String : Any]?) -\u003e RCTRootView {\n        if forHotReloading {\n            let viewBridge = createBridgeIfNeeded()\n            let rootView: RCTRootView = RCTRootView(\n                bridge: viewBridge,\n                moduleName: moduleName,\n                initialProperties: initialProperties)\n            return rootView\n        } else {\n            if let iosBundle = Bundle.main.url(forResource: \"main\", withExtension: \"jsbundle\") {\n                guard let bundleRootView = RCTRootView(bundleURL: iosBundle, moduleName: moduleName, initialProperties: initialProperties, launchOptions: nil) else { return RCTRootView() }\n                return bundleRootView\n            }\n        }\n        return RCTRootView()\n    }\n}\n```\nAdd `ReactManager.swift` to call method with `Native` \u003c-\u003e `React-Native`\n```Swift\n@objc(ReactManager) class ReactManager: NSObject {\n    var bridge: RCTBridge!\n    \n    @objc func back(_ reactTag: NSNumber) {\n        DispatchQueue.main.async {\n            if let view = self.bridge.uiManager.view(forReactTag: reactTag) {\n                let presentedViewController = view.reactViewController()\n                presentedViewController?.navigationController?.pop(animated: true)\n            }\n        }\n    }\n}    \n```\nWe need an addtional `Objective-C file` beacuse `React` uses macro. Add `ReactManagerBridge.m` file like this\n```Swift\n#import \"ReactManagerBridge.h\"\n#import \"zigbang-Swift.h\"\n\n@implementation ReactManagerBridge\n\nRCT_EXPORT_MODULE(ReactManager);\n\nRCT_EXPORT_METHOD(back:(nonnull NSNumber *)reactTag) {\n    ReactManager* reactManager = [[ReactManager alloc] init];\n    reactManager.bridge = _bridge;\n    [reactManager back:reactTag];\n\n}\n@end\n```\n\n---\n### Step4. Modify Android project\n\nadd dependency in `build.gradle`\n\n```\nallprojects {\n    repositories {\n        mavenLocal()\n        jcenter()\n        maven {\n            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm\n            url \"$rootDir/../node_modules/react-native/android\"\n        }\n    }\n}\n```\nin your `app.gradle`. I added `exclude` becuase it conflicts with  existing dependecies\n\n\n```\n    compile (\"com.facebook.react:react-native:+\") {\n        exclude group:'com.facebook.stetho', module:'stetho'\n    }\n\n```\n\nAdd `ReactInstanceManager` to use it in `React Native`. I recommend to make an instance in `Mainapplication` because it takes some time to generate an instance\n\n```Java\n    public static ReactInstanceManager react;\n\n\n\tthis.react = ReactInstanceManager.builder()\n                .setApplication(this)\n                .setBundleAssetName(\"index.android.bundle\")\n                .setJSMainModuleName(\"index.android\")\n                .addPackage(new MainReactPackage())\n                .addPackage(new ReactManagerBridge())\n                .setUseDeveloperSupport(BuildConfig.DEBUG)\n                .setInitialLifecycleState(LifecycleState.RESUMED)\n                .build();\n```\n\nModify your `ReactRootView` where you want to use. Also, add props to pass parameter\n```Java\n    @BindView(R.id.container)\n    ReactRootView container;\n    \n\treact = MainApplication.react;\n\n\tBundle props = new Bundle();\n\tprops.putString(\"items\", new Gson().toJson(response));\n\tcontainer.startReactApplication(react, \"ReactProject\", props);\n\n```\n\nAdd bridge to communicate with Native\n\n```Java\nclass ReactManagerBridge() : ReactPackage {\n\n    override fun createJSModules(): List\u003cClass\u003cout JavaScriptModule\u003e\u003e {\n        return emptyList()\n    }\n\n    override fun createViewManagers(reactContext: ReactApplicationContext): List\u003cViewManager\u003c*, *\u003e\u003e {\n        val modules = ArrayList\u003cViewManager\u003c*, *\u003e\u003e()\n        return modules\n    }\n\n    override fun createNativeModules(reactContext: ReactApplicationContext): List\u003cNativeModule\u003e {\n        val modules = ArrayList\u003cNativeModule\u003e()\n\n        modules.add(ReactManager(reactContext))\n        return modules\n    }\n\n}\n```\n\nAdd reactmanager to call method\n\n```Java\nclass ReactManager(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {\n\n    fun ReactManager(reactContext: ReactApplicationContext) {\n        super.getReactApplicationContext()\n    }\n\n    override fun getName(): String {\n        return \"ReactManager\"\n    }\n\n    @ReactMethod\n    fun alert(message: String) {\n        Toast.makeText(getReactApplicationContext(), message, Toast.LENGTH_LONG).show()\n    }\n}\n```\n\nThis is all about setting your react native to existing application!\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyounatics%2Freact-native-integration-with-existing-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyounatics%2Freact-native-integration-with-existing-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyounatics%2Freact-native-integration-with-existing-app/lists"}