Skip to content

Commit 7cb8122

Browse files
committed
chore: use more c++ and less objc++
1 parent 9388a1c commit 7cb8122

19 files changed

Lines changed: 736 additions & 664 deletions

apps/p2p-counter/ios/P2PCounter/LaunchScreen.storyboard

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23727" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
3-
<device id="retina4_7" orientation="portrait" appearance="light"/>
3+
<device id="retina6_9" orientation="portrait" appearance="light"/>
44
<dependencies>
55
<deployment identifier="iOS"/>
66
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23721"/>
@@ -14,28 +14,28 @@
1414
<objects>
1515
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
1616
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
17-
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
17+
<rect key="frame" x="0.0" y="0.0" width="440" height="956"/>
1818
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
1919
<subviews>
2020
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="cs-gradient" translatesAutoresizingMaskIntoConstraints="NO" id="bg-image">
21-
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
21+
<rect key="frame" x="0.0" y="0.0" width="440" height="956"/>
2222
</imageView>
2323
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="{callstack}" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="callstack-label">
24-
<rect key="frame" x="233.5" y="20" width="91.5" height="21"/>
24+
<rect key="frame" x="298.66666666666669" y="124" width="91.333333333333314" height="21"/>
2525
<fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
2626
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
2727
<nil key="highlightedColor"/>
2828
</label>
2929
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="middleTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="GJd-Yh-RWb">
30-
<rect key="frame" x="0.0" y="225" width="375" height="86"/>
30+
<rect key="frame" x="0.0" y="340.33333333333331" width="440" height="86"/>
3131
<string key="text">Sandbox:
3232
P2P Counter</string>
3333
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
3434
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
3535
<nil key="highlightedColor"/>
3636
</label>
3737
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Powered by React Native" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="MN2-I3-ftu">
38-
<rect key="frame" x="0.0" y="626" width="375" height="21"/>
38+
<rect key="frame" x="0.0" y="847" width="440" height="21"/>
3939
<fontDescription key="fontDescription" type="system" pointSize="17"/>
4040
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
4141
<nil key="highlightedColor"/>
@@ -65,7 +65,7 @@ P2P Counter</string>
6565
</scene>
6666
</scenes>
6767
<resources>
68-
<image name="cs-gradient" width="300" height="533.5"/>
68+
<image name="cs-gradient" width="200" height="355.66665649414062"/>
6969
<systemColor name="systemBackgroundColor">
7070
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
7171
</systemColor>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"lint": "eslint . && bun --filter=@callstack/react-native-sandbox lint",
1212
"format": "eslint . --fix && bun --filter=@callstack/react-native-sandbox format",
1313
"typecheck": "bun --filter=@callstack/react-native-sandbox typecheck",
14-
"test": "bun run jest && bun --filter=@callstack/react-native-sandbox xctest"
14+
"test": "bun run jest && bun --filter=@callstack/react-native-sandbox ctest"
1515
},
1616
"devDependencies": {
1717
"@babel/core": "^7.25.2",

packages/react-native-sandbox/React-Sandbox.podspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Pod::Spec.new do |s|
2020
s.source = { :git => "https://github.com/callstackincubator/react-native-sandbox.git", :tag => "#{s.version}" }
2121
s.source_files = "ios/**/*.{h,m,mm,cpp,swift}"
2222
install_modules_dependencies(s)
23+
s.dependency "fmt"
2324
s.pod_target_xcconfig = {
2425
"HEADER_SEARCH_PATHS" => header_search_paths,
2526
# "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1",
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#pragma once
2+
3+
#include <memory>
4+
#include <set>
5+
#include <string>
6+
7+
namespace facebook {
8+
namespace react {
9+
10+
/**
11+
* Interface for sandbox delegates that provides a clean abstraction
12+
* for sandbox functionality without React Native dependencies.
13+
*
14+
* This interface enables:
15+
* - Better testability (can be mocked without React Native)
16+
* - Cleaner separation of concerns
17+
* - Elimination of string conversions between std::string and NSString
18+
*/
19+
class ISandboxDelegate {
20+
public:
21+
virtual ~ISandboxDelegate() = default;
22+
23+
/**
24+
* Posts a message to the JavaScript runtime.
25+
* @param message JSON-serialized message string
26+
*/
27+
virtual void postMessage(const std::string& message) = 0;
28+
29+
/**
30+
* Routes a message to a specific sandbox delegate.
31+
* @param message The message to route
32+
* @param targetId The ID of the target sandbox
33+
* @return true if the message was successfully routed, false otherwise
34+
*/
35+
virtual bool routeMessage(
36+
const std::string& message,
37+
const std::string& targetId) = 0;
38+
39+
/**
40+
* Sets the origin identifier for this sandbox.
41+
* @param origin Unique identifier for the sandbox
42+
*/
43+
virtual void setOrigin(const std::string& origin) = 0;
44+
45+
/**
46+
* Sets the list of allowed origins for this sandbox instance.
47+
* Only sandboxes with origins in this list can send messages to this sandbox.
48+
* @param origins Set of allowed origin strings
49+
*/
50+
virtual void setAllowedOrigins(const std::set<std::string>& origins) = 0;
51+
52+
/**
53+
* Sets the list of allowed TurboModules for this sandbox instance.
54+
* Only modules in this list will be accessible to the JavaScript runtime.
55+
* @param modules Set of allowed TurboModule names
56+
*/
57+
virtual void setAllowedTurboModules(const std::set<std::string>& modules) = 0;
58+
};
59+
60+
} // namespace react
61+
} // namespace facebook
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#pragma once
2+
3+
#include <memory>
4+
#include <string>
5+
#include <vector>
6+
#include "ISandboxDelegate.h"
7+
8+
// Forward declaration to avoid including Objective-C headers in C++ interface
9+
#ifdef __OBJC__
10+
@class SandboxReactNativeDelegate;
11+
#else
12+
typedef struct objc_object SandboxReactNativeDelegate;
13+
#endif
14+
15+
namespace facebook {
16+
namespace react {
17+
18+
/**
19+
* C++ wrapper for SandboxReactNativeDelegate that implements ISandboxDelegate.
20+
* This allows the C++ registry to work with Objective-C++ objects through
21+
* a proper C++ interface.
22+
*/
23+
class SandboxDelegateWrapper : public ISandboxDelegate {
24+
public:
25+
/**
26+
* Creates a wrapper around the given Objective-C++ delegate.
27+
* @param delegate The Objective-C++ delegate to wrap (must not be null)
28+
*/
29+
explicit SandboxDelegateWrapper(SandboxReactNativeDelegate* delegate);
30+
31+
/**
32+
* Destructor - does not delete the wrapped delegate
33+
*/
34+
~SandboxDelegateWrapper() override = default;
35+
36+
// ISandboxDelegate implementation
37+
void postMessage(const std::string& message) override;
38+
bool routeMessage(const std::string& message, const std::string& targetId)
39+
override;
40+
void setOrigin(const std::string& origin) override;
41+
void setAllowedOrigins(const std::set<std::string>& origins) override;
42+
void setAllowedTurboModules(const std::set<std::string>& modules) override;
43+
44+
private:
45+
// Non-owning pointer to the Objective-C++ delegate
46+
SandboxReactNativeDelegate* delegate_;
47+
};
48+
49+
} // namespace react
50+
} // namespace facebook
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#include "SandboxDelegateWrapper.h"
2+
#import "SandboxReactNativeDelegate.h"
3+
4+
namespace facebook {
5+
namespace react {
6+
7+
SandboxDelegateWrapper::SandboxDelegateWrapper(SandboxReactNativeDelegate *delegate) : delegate_(delegate)
8+
{
9+
// Validate that delegate is not null
10+
if (!delegate_) {
11+
throw std::invalid_argument("SandboxReactNativeDelegate cannot be null");
12+
}
13+
}
14+
15+
void SandboxDelegateWrapper::postMessage(const std::string &message)
16+
{
17+
if (!delegate_)
18+
return;
19+
[delegate_ postMessage:message];
20+
}
21+
22+
bool SandboxDelegateWrapper::routeMessage(const std::string &message, const std::string &targetId)
23+
{
24+
if (!delegate_)
25+
return false;
26+
return [delegate_ routeMessage:message toSandbox:targetId];
27+
}
28+
29+
void SandboxDelegateWrapper::setOrigin(const std::string &origin)
30+
{
31+
if (!delegate_)
32+
return;
33+
[delegate_ setOrigin:origin];
34+
}
35+
36+
void SandboxDelegateWrapper::setAllowedOrigins(const std::set<std::string> &origins)
37+
{
38+
if (!delegate_)
39+
return;
40+
[delegate_ setAllowedOrigins:origins];
41+
}
42+
43+
void SandboxDelegateWrapper::setAllowedTurboModules(const std::set<std::string> &modules)
44+
{
45+
if (!delegate_)
46+
return;
47+
[delegate_ setAllowedTurboModules:modules];
48+
}
49+
50+
} // namespace react
51+
} // namespace facebook

packages/react-native-sandbox/ios/SandboxReactNativeDelegate.h

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,34 +11,38 @@
1111
#import <React/RCTComponent.h>
1212
#import <react/renderer/components/RNSandboxSpec/EventEmitters.h>
1313

14+
#include <string>
15+
#include <vector>
16+
1417
NS_ASSUME_NONNULL_BEGIN
1518

1619
/**
1720
* A React Native delegate that provides sandboxed environments with filtered module access.
1821
* This delegate uses RCTFilteredAppDependencyProvider to restrict which native modules
1922
* are available to the JavaScript runtime, enhancing security in multi-instance scenarios.
2023
*
21-
* Registry functionality has been moved to SandboxRegistry class to maintain single responsibility.
24+
* This class provides the core React Native integration functionality.
25+
* For C++ registry integration, use SandboxDelegateWrapper.
2226
*/
2327
@interface SandboxReactNativeDelegate : RCTDefaultReactNativeFactoryDelegate
2428

2529
@property (nonatomic) std::shared_ptr<const facebook::react::SandboxReactNativeViewEventEmitter> eventEmitter;
2630
@property (nonatomic, assign) BOOL hasOnMessageHandler;
2731
@property (nonatomic, assign) BOOL hasOnErrorHandler;
28-
@property (nonatomic, copy, nullable) NSString *origin;
29-
@property (nonatomic, copy, nullable) NSString *jsBundleSource;
32+
@property (nonatomic, readwrite) std::string origin;
33+
@property (nonatomic, readwrite) std::string jsBundleSource;
3034

3135
/**
3236
* Sets the list of allowed TurboModules for this sandbox instance.
3337
* Only modules in this list will be accessible to the JavaScript runtime.
3438
*/
35-
@property (nonatomic, copy) NSArray<NSString *> *allowedTurboModules;
39+
@property (nonatomic, readwrite) std::set<std::string> allowedTurboModules;
3640

3741
/**
3842
* Sets the list of allowed origins for this sandbox instance.
3943
* Only sandboxes with origins in this list can send messages to this sandbox.
4044
*/
41-
@property (nonatomic, copy) NSArray<NSString *> *allowedOrigins;
45+
@property (nonatomic, readwrite) std::set<std::string> allowedOrigins;
4246

4347
/**
4448
* Initializes the delegate.
@@ -48,17 +52,17 @@ NS_ASSUME_NONNULL_BEGIN
4852

4953
/**
5054
* Posts a message to the JavaScript runtime.
51-
* @param message String containing the JSON.stringified message
55+
* @param message C++ string containing the JSON.stringified message
5256
*/
53-
- (void)postMessage:(NSString *)message;
57+
- (void)postMessage:(const std::string &)message;
5458

5559
/**
5660
* Routes a message to a specific sandbox delegate.
5761
* @param message The message to route
5862
* @param targetId The ID of the target sandbox
59-
* @return YES if the message was successfully routed, NO otherwise
63+
* @return true if the message was successfully routed, false otherwise
6064
*/
61-
- (BOOL)routeMessage:(NSString *)message toSandbox:(NSString *)targetId;
65+
- (bool)routeMessage:(const std::string &)message toSandbox:(const std::string &)targetId;
6266

6367
@end
6468

0 commit comments

Comments
 (0)