Skip to content
Merged
29 changes: 17 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@
- Compatible with all native languages **Objective-C**, **Swift**, **Java** and **Kotlin**
- Supports UIKit and SwiftUI on iOS and Fragments and Jetpack Compose on Android

## React Native version compatibility matrix

| Tested React Native Version | React Native Brownfield Version |
| --------------------------- | ------------------------------- |
| 0.81.x, 0.82.x | ^2.0.0-rc.0 |
| 0.78.x | ^1.2.0 |

## Installation

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.
Expand All @@ -51,16 +58,16 @@ npm install @callstack/react-native-brownfield

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

#### With RNEF
#### With Rock

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

- `rnef package:ios` for iOS
- `rnef package:aar` for Android
- `rock package:ios` for iOS
- `rock package:aar` for Android

#### With custom scripts

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:
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:

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

class RNAppFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View? =
this.context?.let {
RNViewFactory.createFrameLayout(it)
}
): View? = ReactNativeBrownfield.shared.createView(activity, "BrownFieldTest")
}
```

Expand Down Expand Up @@ -166,7 +169,9 @@ class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ReactNativeHostManager.shared.initialize(this.application)
ReactNativeHostManager.shared.initialize(this.application) {
println("JS bundle loaded")
}

showRNAppBtn = findViewById(R.id.show_rn_app_btn)
showRNAppBtn.setOnClickListener {
Expand Down Expand Up @@ -228,7 +233,7 @@ Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore -->
| [<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") |
| :---: | :---: |
| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import com.facebook.react.ReactHost
import com.facebook.react.ReactInstanceEventListener
import com.facebook.react.ReactPackage
import com.facebook.react.bridge.ReactContext
import com.facebook.react.common.build.ReactBuildConfig
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
import com.facebook.react.soloader.OpenSourceMergedSoMapping
Expand Down Expand Up @@ -75,6 +76,9 @@ class ReactNativeBrownfield private constructor(val reactHost: ReactHost) {
context = application,
packageList = (options["packages"] as? List<*> ?: emptyList<ReactPackage>())
.filterIsInstance<ReactPackage>(),
jsMainModulePath = options["mainModuleName"] as? String ?: "index",
useDevSupport = options["useDeveloperSupport"] as? Boolean
?: ReactBuildConfig.DEBUG,
jsRuntimeFactory = null
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.callstack.reactnativebrownfield.constants.ReactNativeInitialPropsNames
import com.callstack.reactnativebrownfield.constants.ReactNativeFragmentArgNames
import com.facebook.react.ReactFragment
import com.facebook.react.ReactHost
import com.facebook.react.bridge.Callback
Expand Down Expand Up @@ -36,13 +36,13 @@ class ReactNativeFragment : ReactFragment(), PermissionAwareActivity {
)
}

moduleName = arguments?.getString(ReactNativeInitialPropsNames.ARG_MODULE_NAME)!!
moduleName = arguments?.getString(ReactNativeFragmentArgNames.ARG_MODULE_NAME)!!
this.reactDelegate =
ReactDelegateWrapper(
activity,
this.reactHost,
moduleName,
arguments?.getBundle(ReactNativeInitialPropsNames.ARG_LAUNCH_OPTIONS)
arguments?.getBundle(ReactNativeFragmentArgNames.ARG_LAUNCH_OPTIONS)
)
}

Expand Down Expand Up @@ -113,9 +113,9 @@ class ReactNativeFragment : ReactFragment(), PermissionAwareActivity {
): ReactNativeFragment {
val fragment = ReactNativeFragment()
val args = Bundle()
args.putString(ReactNativeInitialPropsNames.ARG_MODULE_NAME, moduleName)
args.putString(ReactNativeFragmentArgNames.ARG_MODULE_NAME, moduleName)
if (initialProps != null) {
args.putBundle(ReactNativeInitialPropsNames.ARG_LAUNCH_OPTIONS, initialProps)
args.putBundle(ReactNativeFragmentArgNames.ARG_LAUNCH_OPTIONS, initialProps)
}
fragment.arguments = args
return fragment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import com.facebook.react.ReactFragment
/**
* Convenience export of arguments that can be used
*/
class ReactNativeInitialPropsNames private constructor() :
class ReactNativeFragmentArgNames private constructor() :
ReactFragment() // subclass to gain access to protected constants
{
companion object {
Expand Down
56 changes: 28 additions & 28 deletions docs/JAVA.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ With react-native >= 0.80.0, an auto-generated file was added which is responsib
you will have this file `ReactNativeApplicationEntryPoint` available. If you're consuming this library in a RN android library which is backed by
`com.callstack.react:brownfield-gradle-plugin`, then this file will also be available.

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

```java
import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative

loadReactNative(application);
RNBrownfield.initialize(application, packages);
ReactNativeBrownfield.initialize(application, packages);
```

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

Params:

| Param | Required | Type | Description |
| ----------------------- | -------- | -------------------- | --------------------------------------------------------- |
| application | Yes | `Application` | Main application. |
| rnHost | No* | `ReactNativeHost` | An instance of [ReactNativeHost](https://bit.ly/2ZnwgnA). |
| packages | No* | `List<ReactPackage>` | List of your React Native Native modules. |
| options | No* | `HashMap<String, Any>` | Map of initial options. __Options listed below.__ |
| onJSBundleLoaded | No* | `OnJSBundleLoaded` | Callback invoked after JS bundle is fully loaded. |
| Param | Required | Type | Description |
| ---------------- | ------------ | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| application | Yes | `Application` | Main application. |
| 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). |
| packages | Exclusively* | `List<ReactPackage>` | List of your React Native Native modules. |
| options | Exclusively* | `HashMap<String, Any>` | Map of initial options. __Options listed below.__ |
| onJSBundleLoaded | Exclusively* | `OnJSBundleLoaded` | Callback invoked after JS bundle is fully loaded. |

> * - Those fields aren't itself required, but at least one of them is. See examples below.
> * - From the marked fields, exactly one must be specified, excluding the others. See examples below.

Available options:
- `useDeveloperSupport`: `Boolean` - Flag to use dev support.
Expand Down Expand Up @@ -103,7 +103,7 @@ private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {

ReactNativeBrownfield.initialize(this, mReactNativeHost);

OR
// OR

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

ReactNativeBrownfield.initialize(this, packages);

OR
// OR

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

ReactNativeBrownfield.initialize(this, options);

OR
// OR

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

**Properties:**

| Property | Type | Default | Description |
| --------------- | --------------- | -------------- | --------------------------------------------------------- |
| reactNativeHost | `ReactNativeHost` | null | An instance of [ReactNativeHost](https://bit.ly/2ZnwgnA). |
| Property | Type | Default | Description |
| --------- | ----------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 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). |

---

**Methods:**

`createView`

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.
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.

Params:

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

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

#### `ReactNativeFragment`

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.
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.

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

Params:

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

Examples:

Expand Down
Loading
Loading