Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion ReactBrownfield.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,13 @@ Pod::Spec.new do |spec|
spec.module_name = "ReactBrownfield"
spec.source = { :git => "git@github.com:callstack/react-native-brownfield.git", :tag => "#{spec.version}" }
spec.source_files = "ios/**/*.{h,m,mm,swift}"
spec.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
spec.pod_target_xcconfig = {
'DEFINES_MODULE' => 'YES',
'OTHER_SWIFT_FLAGS' => "-enable-experimental-feature AccessLevelOnImport"
}

spec.dependency 'ReactAppDependencyProvider'
add_dependency(spec, "React-RCTAppDelegate")

install_modules_dependencies(spec)
end
19 changes: 18 additions & 1 deletion docs/OBJECTIVE_C.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ Examples:
| `entryFile` | `NSString` | `index` | Path to JavaScript root. |
| `fallbackResource` | `NSString` | `nil` | Path to bundle fallback resource. |
| `bundlePath` | `NSString` | `main.jsbundle`| Path to bundle fallback resource. |
| `reactNativeFactory` | `RCTReactNativeFactory` | `nil` | React Native factory instance. |

---

Expand Down Expand Up @@ -70,6 +69,24 @@ Examples:
}, launchOptions];
```

`view`

Creates a React Native view for the specified module name.

Params:

| Param | Required | Type | Description |
| ----------------------- | -------- | ----------------- | ----------------------------------------------------- |
| `moduleName` | Yes | `NSString` | Name of React Native component registered to `AppRegistry`. |
| `initialProps` | No | `NSDictionary` | Initial properties to be passed to React Native component. |
| `launchOptions` | No | `NSDictionary` | Launch options, typically passed from AppDelegate. |

Examples:

```objc
UIView *view = [[ReactNativeBrownfield shared] viewWithModuleName:@"ReactNative" initialProps:@{@"score": @12}];
```

---

#### `ReactNativeViewController`
Expand Down
25 changes: 22 additions & 3 deletions docs/SWIFT.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ ReactNativeBrownfield.shared
| `entryFile` | `String` | index | Path to JavaScript root. |
| `fallbackResource` | `String?` | nil | Path to bundle fallback resource. |
| `bundlePath` | `String` | main.jsbundle | Path to bundle fallback resource. |
| `reactNativeFactory` | `RCTReactNativeFactory?` | nil | React Native factory instance. |

---

**Methods:**


`startReactNative`

Starts React Native. You can use it to initialize React Native in your app.
Expand Down Expand Up @@ -70,6 +70,27 @@ ReactNativeBrownfield.shared.startReactNative(onBundleLoaded: {
}, launchOptions: launchOptions)
```

`view`

Creates a React Native view for the specified module name.

Params:

| Param | Required | Type | Description |
| ----------------------- | -------- | ------------------- | ----------------------------------------------------- |
| `moduleName` | Yes | `String` | Name of React Native component registered to `AppRegistry`. |
| `initialProps` | No | `[AnyHashable: Any]?` | Initial properties to be passed to React Native component. |
| `launchOptions` | No | `[AnyHashable: Any]?` | Launch options, typically passed from AppDelegate. |

Examples:

```swift
let view = ReactNativeBrownfield.shared.view(
moduleName: "ReactNative",
initialProps: ["score": 12]
)
```

---

#### Initialization Approaches
Expand Down Expand Up @@ -238,5 +259,3 @@ NavigationLink("Open React Native Screen") {
### Example

You can find an example app [here](../example/swift).


2 changes: 1 addition & 1 deletion example/swift/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ target 'SwiftExample' do
installer,
config[:reactNativePath],
:mac_catalyst_enabled => false,
:ccache_enabled => true
# :ccache_enabled => true
)
end
end
7 changes: 4 additions & 3 deletions example/swift/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1527,7 +1527,7 @@ PODS:
- React-jsi (= 0.78.0)
- ReactAppDependencyProvider (0.78.0):
- ReactCodegen
- ReactBrownfield (1.0.0-rc.0):
- ReactBrownfield (1.0.0-rc.1):
- DoubleConversion
- glog
- hermes-engine
Expand All @@ -1541,6 +1541,7 @@ PODS:
- React-graphics
- React-ImageManager
- React-NativeModulesApple
- React-RCTAppDelegate
- React-RCTFabric
- React-rendererdebug
- React-utils
Expand Down Expand Up @@ -1944,13 +1945,13 @@ SPEC CHECKSUMS:
React-timing: bb220a53a795ed57976a4855c521f3de2f298fe5
React-utils: 3b054aaebe658fc710a8d239d0e4b9fd3e0b78f9
ReactAppDependencyProvider: a1fb08dfdc7ebc387b2e54cfc9decd283ed821d8
ReactBrownfield: e05f198df083698ed9942ace80fd90da6e9298de
ReactBrownfield: f2e119f0241af9303f55556a63385efc58ce49b7
ReactCodegen: 008c319179d681a6a00966edfc67fda68f9fbb2e
ReactCommon: 0c097b53f03d6bf166edbcd0915da32f3015dd90
RNScreens: 0d4cb9afe052607ad0aa71f645a88bb7c7f2e64c
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
Yoga: afd04ff05ebe0121a00c468a8a3c8080221cb14c

PODFILE CHECKSUM: b5dc5f822e98018cbffd7384516e146bba9f6d99
PODFILE CHECKSUM: dd9bed4f3821ab08d739dbded562f749348cd4d7

COCOAPODS: 1.15.2
10 changes: 8 additions & 2 deletions example/swift/SwiftExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,10 @@
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = "$(inherited)";
OTHER_CPLUSPLUSFLAGS = "$(inherited)";
OTHER_LDFLAGS = "$(inherited) ";
OTHER_LDFLAGS = (
"$(inherited)",
" ",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
Expand Down Expand Up @@ -392,7 +395,10 @@
MTL_FAST_MATH = YES;
OTHER_CFLAGS = "$(inherited)";
OTHER_CPLUSPLUSFLAGS = "$(inherited)";
OTHER_LDFLAGS = "$(inherited) ";
OTHER_LDFLAGS = (
"$(inherited)",
" ",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
Expand Down
87 changes: 54 additions & 33 deletions ios/ReactNativeBrownfield.swift
Original file line number Diff line number Diff line change
@@ -1,16 +1,44 @@
import React
import React_RCTAppDelegate
import ReactAppDependencyProvider
import UIKit
internal import React
internal import React_RCTAppDelegate
internal import ReactAppDependencyProvider

@objc public class ReactNativeBrownfield: RCTDefaultReactNativeFactoryDelegate {
@objc public static let shared = ReactNativeBrownfield()
private var onBundleLoaded: (() -> Void)?
class ReactNativeBrownfieldDelegate: RCTDefaultReactNativeFactoryDelegate {
var entryFile = "index"
// MARK: - RCTReactNativeFactoryDelegate Methods

override func sourceURL(for bridge: RCTBridge) -> URL? {
return bundleURL()
}

public override func bundleURL() -> URL? {
#if DEBUG
return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: entryFile)
#else
let resourceURLComponents = bundlePath.components(separatedBy: ".")
let withoutLast = resourceURLComponents[..<(resourceURLComponents.count - 1)]
let resourceName = withoutLast.joined()
let fileExtension = resourceURLComponents.last ?? ""

return Bundle.main.url(forResource: resourceName, withExtension: fileExtension)
#endif
}
}

@objc public class ReactNativeBrownfield: NSObject {
public static let shared = ReactNativeBrownfield()
private var onBundleLoaded: (() -> Void)?
private var delegate = ReactNativeBrownfieldDelegate()

/**
* Path to JavaScript root.
* Default value: "index"
*/
@objc public var entryFile: String = "index"
@objc public var entryFile: String = "index" {
didSet {
delegate.entryFile = entryFile
}
}
/**
* Path to bundle fallback resource.
* Default value: nil
Expand All @@ -25,24 +53,36 @@ import ReactAppDependencyProvider
* React Native factory instance created when starting React Native.
* Default value: nil
*/
@objc public var reactNativeFactory: RCTReactNativeFactory? = nil
private var reactNativeFactory: RCTReactNativeFactory? = nil
/**
* Root view factory used to create React Native views.
*/
@objc lazy public var rootViewFactory: RCTRootViewFactory? = {
lazy private var rootViewFactory: RCTRootViewFactory? = {
return reactNativeFactory?.rootViewFactory
}()

/**
* Starts React Native with default parameters.
*/
@objc public func startReactNative() {
startReactNative(onBundleLoaded: nil)
}

@objc public func view(
moduleName: String,
initialProps: [AnyHashable: Any]?,
launchOptions: [AnyHashable: Any]? = nil
) -> UIView? {
reactNativeFactory?.rootViewFactory.view(
withModuleName: moduleName,
initialProperties: initialProps,
launchOptions: launchOptions
)
}

/**
* Starts React Native with optional callback when bundle is loaded.
*
*
* @param onBundleLoaded Optional callback invoked after JS bundle is fully loaded.
*/
@objc public func startReactNative(onBundleLoaded: (() -> Void)?) {
Expand All @@ -51,15 +91,15 @@ import ReactAppDependencyProvider

/**
* Starts React Native with optional callback and launch options.
*
*
* @param onBundleLoaded Optional callback invoked after JS bundle is fully loaded.
* @param launchOptions Launch options, typically passed from AppDelegate.
*/
@objc public func startReactNative(onBundleLoaded: (() -> Void)?, launchOptions: [AnyHashable: Any]?) {
guard reactNativeFactory == nil else { return }

self.dependencyProvider = RCTAppDependencyProvider()
self.reactNativeFactory = RCTReactNativeFactory(delegate: self)
delegate.dependencyProvider = RCTAppDependencyProvider()
self.reactNativeFactory = RCTReactNativeFactory(delegate: delegate)

if let onBundleLoaded {
self.onBundleLoaded = onBundleLoaded
Expand All @@ -86,25 +126,6 @@ import ReactAppDependencyProvider
onBundleLoaded = nil
NotificationCenter.default.removeObserver(self)
}

// MARK: - RCTReactNativeFactoryDelegate Methods

@objc public override func sourceURL(for bridge: RCTBridge) -> URL? {
return bundleURL()
}

public override func bundleURL() -> URL? {
#if DEBUG
return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: entryFile)
#else
let resourceURLComponents = bundlePath.components(separatedBy: ".")
let withoutLast = resourceURLComponents[..<(resourceURLComponents.count - 1)]
let resourceName = withoutLast.joined()
let fileExtension = resourceURLComponents.last ?? ""

return Bundle.main.url(forResource: resourceName, withExtension: fileExtension)
#endif
}
}

extension Notification.Name {
Expand Down
1 change: 0 additions & 1 deletion ios/ReactNativeBrownfieldModule.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#ifdef __cplusplus

#import <React-RCTAppDelegate/RCTDefaultReactNativeFactoryDelegate.h>
#import <ReactNativeBrownfield/ReactNativeBrownfield.h>

@interface ReactNativeBrownfieldModule : NSObject <NativeReactNativeBrownfieldModuleSpec>
Expand Down
4 changes: 2 additions & 2 deletions ios/ReactNativeBrownfieldModule.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React
internal import React

@objcMembers
public class ReactNativeBrownfieldModuleImpl: NSObject {
Expand All @@ -8,7 +8,7 @@ public class ReactNativeBrownfieldModuleImpl: NSObject {
NotificationCenter.default.post(name: Notification.Name.togglePopGestureRecognizer, object: nil, userInfo: userInfo)
}
}

static public func popToNative(animated: Bool) {
let userInfo = ["animated": animated]
DispatchQueue.main.async {
Expand Down
Loading
Loading