Skip to content

Commit 1288e5e

Browse files
authored
Merge pull request #153 from callstack/feat/react-host-options
feat: forward dictionary options to `getDefaultReactHost`, update documentation, fix example app release build
2 parents 2725345 + ff4a163 commit 1288e5e

File tree

8 files changed

+109
-78
lines changed

8 files changed

+109
-78
lines changed

README.md

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@
3131
- Compatible with all native languages **Objective-C**, **Swift**, **Java** and **Kotlin**
3232
- Supports UIKit and SwiftUI on iOS and Fragments and Jetpack Compose on Android
3333

34+
## React Native version compatibility matrix
35+
36+
| Tested React Native Version | React Native Brownfield Version |
37+
| --------------------------- | ------------------------------- |
38+
| 0.81.x, 0.82.x | ^2.0.0-rc.0 |
39+
| 0.78.x | ^1.2.0 |
40+
3441
## Installation
3542

3643
The React Native Brownfield library is intended to be installed in a React Native app that is later consumed as a framework artifact by your native iOS or Android app.
@@ -51,16 +58,16 @@ npm install @callstack/react-native-brownfield
5158

5259
First, we need to package our React Native app as an XCFramework or Fat-AAR.
5360

54-
#### With RNEF
61+
#### With Rock
5562

56-
Follow [Integrating with Native Apps](https://www.rnef.dev/docs/brownfield/intro) steps in RNEF docs and run:
63+
Follow [Integrating with Native Apps](https://www.rockjs.dev/docs/brownfield/intro) steps in Rock docs and run:
5764

58-
- `rnef package:ios` for iOS
59-
- `rnef package:aar` for Android
65+
- `rock package:ios` for iOS
66+
- `rock package:aar` for Android
6067

6168
#### With custom scripts
6269

63-
Instead of using RNEF, you can create your own custom packaging scripts. Here are base versions for iOS and Android that you'll need to adjust for your project-specific setup:
70+
Instead of using Rock, you can create your own custom packaging scripts. Here are base versions for iOS and Android that you'll need to adjust for your project-specific setup:
6471

6572
- [Example iOS script](https://github.com/callstackincubator/modern-brownfield-ref/blob/main/scripts/build-xcframework.sh)
6673
- [Example Android script](https://github.com/callstackincubator/modern-brownfield-ref/blob/main/scripts/build-aar.sh)
@@ -121,17 +128,13 @@ import android.view.LayoutInflater
121128
import android.view.View
122129
import android.view.ViewGroup
123130
import androidx.fragment.app.Fragment
124-
import com.callstack.rnbrownfield.RNViewFactory // exposed by RN app framework
125131

126132
class RNAppFragment : Fragment() {
127133
override fun onCreateView(
128134
inflater: LayoutInflater,
129135
container: ViewGroup?,
130136
savedInstanceState: Bundle?,
131-
): View? =
132-
this.context?.let {
133-
RNViewFactory.createFrameLayout(it)
134-
}
137+
): View? = ReactNativeBrownfield.shared.createView(activity, "BrownFieldTest")
135138
}
136139
```
137140

@@ -166,7 +169,9 @@ class MainActivity : AppCompatActivity() {
166169

167170
override fun onCreate(savedInstanceState: Bundle?) {
168171
super.onCreate(savedInstanceState)
169-
ReactNativeHostManager.shared.initialize(this.application)
172+
ReactNativeHostManager.shared.initialize(this.application) {
173+
println("JS bundle loaded")
174+
}
170175

171176
showRNAppBtn = findViewById(R.id.show_rn_app_btn)
172177
showRNAppBtn.setOnClickListener {
@@ -228,7 +233,7 @@ Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds
228233
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
229234
<!-- prettier-ignore -->
230235
| [<img src="https://avatars0.githubusercontent.com/u/7837457?s=460&v=4" width="100px;" alt="Michał Chudziak"/><br /><sub><b>Michał Chudziak</b></sub>](https://twitter.com/michalchudziak)<br />[💻](https://github.com/callstack/react-native-brownfield/commits?author=michalchudziak "Code") [📖](https://github.com/callstack/react-native-brownfield/commits?author=michalchudziak "Documentation") [🤔](#ideas-michalchudziak "Ideas, Planning, & Feedback") | [<img src="https://avatars1.githubusercontent.com/u/16336501?s=400&v=4" width="100px;" alt="Piotr Drapich"/><br /><sub><b>Piotr Drapich</b></sub>](https://twitter.com/dratwas)<br />[💻](https://github.com/callstack/react-native-brownfield/commits?author=dratwas "Code") [🤔](#ideas-dratwas "Ideas, Planning, & Feedback") |
231-
| :---: | :---: |
236+
| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
232237

233238
<!-- ALL-CONTRIBUTORS-LIST:END -->
234239

android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeBrownfield.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import com.facebook.react.ReactHost
1212
import com.facebook.react.ReactInstanceEventListener
1313
import com.facebook.react.ReactPackage
1414
import com.facebook.react.bridge.ReactContext
15+
import com.facebook.react.common.build.ReactBuildConfig
1516
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
1617
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
1718
import com.facebook.react.soloader.OpenSourceMergedSoMapping
@@ -75,6 +76,9 @@ class ReactNativeBrownfield private constructor(val reactHost: ReactHost) {
7576
context = application,
7677
packageList = (options["packages"] as? List<*> ?: emptyList<ReactPackage>())
7778
.filterIsInstance<ReactPackage>(),
79+
jsMainModulePath = options["mainModuleName"] as? String ?: "index",
80+
useDevSupport = options["useDeveloperSupport"] as? Boolean
81+
?: ReactBuildConfig.DEBUG,
7882
jsRuntimeFactory = null
7983
)
8084
}

android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeFragment.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import android.util.Log
55
import android.view.LayoutInflater
66
import android.view.View
77
import android.view.ViewGroup
8-
import com.callstack.reactnativebrownfield.constants.ReactNativeInitialPropsNames
8+
import com.callstack.reactnativebrownfield.constants.ReactNativeFragmentArgNames
99
import com.facebook.react.ReactFragment
1010
import com.facebook.react.ReactHost
1111
import com.facebook.react.bridge.Callback
@@ -36,13 +36,13 @@ class ReactNativeFragment : ReactFragment(), PermissionAwareActivity {
3636
)
3737
}
3838

39-
moduleName = arguments?.getString(ReactNativeInitialPropsNames.ARG_MODULE_NAME)!!
39+
moduleName = arguments?.getString(ReactNativeFragmentArgNames.ARG_MODULE_NAME)!!
4040
this.reactDelegate =
4141
ReactDelegateWrapper(
4242
activity,
4343
this.reactHost,
4444
moduleName,
45-
arguments?.getBundle(ReactNativeInitialPropsNames.ARG_LAUNCH_OPTIONS)
45+
arguments?.getBundle(ReactNativeFragmentArgNames.ARG_LAUNCH_OPTIONS)
4646
)
4747
}
4848

@@ -113,9 +113,9 @@ class ReactNativeFragment : ReactFragment(), PermissionAwareActivity {
113113
): ReactNativeFragment {
114114
val fragment = ReactNativeFragment()
115115
val args = Bundle()
116-
args.putString(ReactNativeInitialPropsNames.ARG_MODULE_NAME, moduleName)
116+
args.putString(ReactNativeFragmentArgNames.ARG_MODULE_NAME, moduleName)
117117
if (initialProps != null) {
118-
args.putBundle(ReactNativeInitialPropsNames.ARG_LAUNCH_OPTIONS, initialProps)
118+
args.putBundle(ReactNativeFragmentArgNames.ARG_LAUNCH_OPTIONS, initialProps)
119119
}
120120
fragment.arguments = args
121121
return fragment
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import com.facebook.react.ReactFragment
55
/**
66
* Convenience export of arguments that can be used
77
*/
8-
class ReactNativeInitialPropsNames private constructor() :
8+
class ReactNativeFragmentArgNames private constructor() :
99
ReactFragment() // subclass to gain access to protected constants
1010
{
1111
companion object {

docs/JAVA.md

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ With react-native >= 0.80.0, an auto-generated file was added which is responsib
2525
you will have this file `ReactNativeApplicationEntryPoint` available. If you're consuming this library in a RN android library which is backed by
2626
`com.callstack.react:brownfield-gradle-plugin`, then this file will also be available.
2727

28-
Below is the code you need to add before you call `RNBrownfield.initialize`:
28+
Below is the code you need to add before you call `ReactNativeBrownfield.initialize`:
2929

3030
```java
3131
import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
3232

3333
loadReactNative(application);
34-
RNBrownfield.initialize(application, packages);
34+
ReactNativeBrownfield.initialize(application, packages);
3535
```
3636

3737
<hr/>
@@ -62,15 +62,15 @@ A function used to initialize a React Native Brownfield singleton. Keep in mind
6262

6363
Params:
6464

65-
| Param | Required | Type | Description |
66-
| ----------------------- | -------- | -------------------- | --------------------------------------------------------- |
67-
| application | Yes | `Application` | Main application. |
68-
| rnHost | No* | `ReactNativeHost` | An instance of [ReactNativeHost](https://bit.ly/2ZnwgnA). |
69-
| packages | No* | `List<ReactPackage>` | List of your React Native Native modules. |
70-
| options | No* | `HashMap<String, Any>` | Map of initial options. __Options listed below.__ |
71-
| onJSBundleLoaded | No* | `OnJSBundleLoaded` | Callback invoked after JS bundle is fully loaded. |
65+
| Param | Required | Type | Description |
66+
| ---------------- | ------------ | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
67+
| application | Yes | `Application` | Main application. |
68+
| reactHost | Exclusively* | `ReactHost` | An instance of [ReactHost](https://github.com/facebook/react-native/blob/main/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt). |
69+
| packages | Exclusively* | `List<ReactPackage>` | List of your React Native Native modules. |
70+
| options | Exclusively* | `HashMap<String, Any>` | Map of initial options. __Options listed below.__ |
71+
| onJSBundleLoaded | Exclusively* | `OnJSBundleLoaded` | Callback invoked after JS bundle is fully loaded. |
7272

73-
> * - Those fields aren't itself required, but at least one of them is. See examples below.
73+
> * - From the marked fields, exactly one must be specified, excluding the others. See examples below.
7474
7575
Available options:
7676
- `useDeveloperSupport`: `Boolean` - Flag to use dev support.
@@ -103,7 +103,7 @@ private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
103103

104104
ReactNativeBrownfield.initialize(this, mReactNativeHost);
105105

106-
OR
106+
// OR
107107

108108
ReactNativeBrownfield.initialize(this, mReactNativeHost, initialized -> {
109109
// JS bundle loaded
@@ -115,7 +115,7 @@ List<ReactPackage> packages = new PackageList(this).getPackages();
115115

116116
ReactNativeBrownfield.initialize(this, packages);
117117

118-
OR
118+
// OR
119119

120120
ReactNativeBrownfield.initialize(this, packages, initialized -> {
121121
// JS bundle loaded
@@ -130,7 +130,7 @@ options.put("mainModuleName", "example/index");
130130

131131
ReactNativeBrownfield.initialize(this, options);
132132

133-
OR
133+
// OR
134134

135135
ReactNativeBrownfield.initialize(this, options, initialized -> {
136136
// JS bundle loaded
@@ -153,26 +153,26 @@ ReactNativeBrownfield.getShared()
153153

154154
**Properties:**
155155

156-
| Property | Type | Default | Description |
157-
| --------------- | --------------- | -------------- | --------------------------------------------------------- |
158-
| reactNativeHost | `ReactNativeHost` | null | An instance of [ReactNativeHost](https://bit.ly/2ZnwgnA). |
156+
| Property | Type | Default | Description |
157+
| --------- | ----------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
158+
| reactHost | `ReactHost` | null | An instance of [ReactHost](https://github.com/facebook/react-native/blob/main/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt). |
159159

160160
---
161161

162162
**Methods:**
163163

164164
`createView`
165165

166-
Creates a React Native view with a given module name. It automatically uses an instance of React Native created in `startReactNative` method. This is useful when embedding React Native views directly in your native layouts.
166+
Creates a React Native view with a given module name. It automatically uses an instance of React Native created in `initialize` method. This is useful when embedding React Native views directly in your native layouts.
167167

168168
Params:
169169

170-
| Param | Required | Type | Description |
171-
| -------------- | -------- | ------------------- | ----------------------------------------------------------- |
172-
| context | Yes | `Context` | Android context to create the view |
173-
| activity | No | `FragmentActivity` | Activity hosting the view, used for lifecycle management |
174-
| moduleName | Yes | `String` | Name of React Native component registered to `AppRegistry` |
175-
| launchOptions | No | `Bundle` | Initial properties to be passed to React Native component |
170+
| Param | Required | Type | Description |
171+
| ------------- | -------- | ------------------ | ---------------------------------------------------------- |
172+
| context | Yes | `Context` | Android context to create the view |
173+
| activity | No | `FragmentActivity` | Activity hosting the view, used for lifecycle management |
174+
| moduleName | Yes | `String` | Name of React Native component registered to `AppRegistry` |
175+
| launchOptions | No | `Bundle` | Initial properties to be passed to React Native component |
176176

177177
Returns:
178178
`FrameLayout` - A view containing the React Native component.
@@ -193,7 +193,7 @@ container.addView(reactView);
193193

194194
#### `ReactNativeFragment`
195195

196-
An fragment rendering `ReactRootView` with a given module name. It automatically uses an instance of a React Native created in `startReactNative` method. It works well with exposed JavaScript module. All the lifecycles are proxied to `ReactInstanceManager`. It's the simplest way to embed React Native into your navigation stack.
196+
An fragment rendering `ReactRootView` with a given module name. It automatically uses an instance of a React Native created in `initialize` method. It works well with exposed JavaScript module. All the lifecycles are proxied to `ReactInstanceManager`. It's the simplest way to embed React Native into your navigation stack.
197197

198198
```java
199199
import com.callstack.reactnativebrownfield.ReactNativeFragment;
@@ -209,10 +209,10 @@ Creates a Fragment with `ReactNativeActivity`, you can use it as a parameter in
209209

210210
Params:
211211

212-
| Param | Required | Type | Description |
213-
| ----------------------- | -------- | ------------------------------------------- | ----------------------------------------------------------- |
214-
| moduleName | Yes | `String` | Name of React Native component registered to `AppRegistry`. |
215-
| initialProps | No | `Bundle` \|\| `HashMap<String, *>` \|\| `ReadableMap` | Initial properties to be passed to React Native component. |
212+
| Param | Required | Type | Description |
213+
| ------------ | -------- | ----------------------------------------------------- | ----------------------------------------------------------- |
214+
| moduleName | Yes | `String` | Name of React Native component registered to `AppRegistry`. |
215+
| initialProps | No | `Bundle` \|\| `HashMap<String, *>` \|\| `ReadableMap` | Initial properties to be passed to React Native component. |
216216

217217
Examples:
218218

0 commit comments

Comments
 (0)