Skip to content

Commit 8d77eaf

Browse files
committed
fix(ios): add support for react-native-reanimated
1 parent c614aa0 commit 8d77eaf

File tree

10 files changed

+140
-47
lines changed

10 files changed

+140
-47
lines changed

ios/ReactTestApp.xcodeproj/project.pbxproj

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
archiveVersion = 1;
44
classes = {
55
};
6-
objectVersion = 52;
6+
objectVersion = 54;
77
objects = {
88

99
/* Begin PBXBuildFile section */
1010
192DD201240FCAF5004E9CEB /* Manifest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 192DD200240FCAF5004E9CEB /* Manifest.swift */; };
11-
193B614D27F5CD7D00080064 /* React+TurboModule.mm in Sources */ = {isa = PBXBuildFile; fileRef = 193B614B27F5CD7D00080064 /* React+TurboModule.mm */; };
11+
193B614D27F5CD7D00080064 /* BridgeDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 193B614B27F5CD7D00080064 /* BridgeDelegate.mm */; };
1212
1963A06227C82E730013D276 /* React+Fabric.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1963A06127C82E730013D276 /* React+Fabric.mm */; };
1313
196C22622490CB7600449D3C /* React+Compatibility.m in Sources */ = {isa = PBXBuildFile; fileRef = 196C22602490CB7600449D3C /* React+Compatibility.m */; };
1414
196C7215232F1788006556ED /* ReactInstance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 196C7214232F1788006556ED /* ReactInstance.swift */; };
@@ -47,8 +47,8 @@
4747
192F052624AD3CC500A48456 /* ReactTestApp.release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = ReactTestApp.release.xcconfig; sourceTree = "<group>"; };
4848
192F052724AD3CC500A48456 /* ReactTestApp.common.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = ReactTestApp.common.xcconfig; sourceTree = "<group>"; };
4949
192F052824AD3CC500A48456 /* ReactTestApp.debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = ReactTestApp.debug.xcconfig; sourceTree = "<group>"; };
50-
193B614B27F5CD7D00080064 /* React+TurboModule.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "React+TurboModule.mm"; sourceTree = "<group>"; };
51-
193B614C27F5CD7D00080064 /* React+TurboModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "React+TurboModule.h"; sourceTree = "<group>"; };
50+
193B614B27F5CD7D00080064 /* BridgeDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BridgeDelegate.mm; sourceTree = "<group>"; };
51+
193B614C27F5CD7D00080064 /* BridgeDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BridgeDelegate.h; sourceTree = "<group>"; };
5252
1963A06027C82E730013D276 /* React+Fabric.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "React+Fabric.h"; sourceTree = "<group>"; };
5353
1963A06127C82E730013D276 /* React+Fabric.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "React+Fabric.mm"; sourceTree = "<group>"; };
5454
196C22602490CB7600449D3C /* React+Compatibility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "React+Compatibility.m"; sourceTree = "<group>"; };
@@ -133,12 +133,12 @@
133133
196C7214232F1788006556ED /* ReactInstance.swift */,
134134
19A624A3258C95F000032776 /* Session.swift */,
135135
196C7207232EF5DC006556ED /* ReactTestApp-Bridging-Header.h */,
136+
193B614C27F5CD7D00080064 /* BridgeDelegate.h */,
137+
193B614B27F5CD7D00080064 /* BridgeDelegate.mm */,
136138
196C22612490CB7600449D3C /* React+Compatibility.h */,
137139
196C22602490CB7600449D3C /* React+Compatibility.m */,
138140
1963A06027C82E730013D276 /* React+Fabric.h */,
139141
1963A06127C82E730013D276 /* React+Fabric.mm */,
140-
193B614C27F5CD7D00080064 /* React+TurboModule.h */,
141-
193B614B27F5CD7D00080064 /* React+TurboModule.mm */,
142142
1988282224105BCC005057FF /* UIViewController+ReactTestApp.h */,
143143
1988284424105BEC005057FF /* UIViewController+ReactTestApp.m */,
144144
19ECD0DB232ED427003D8557 /* Assets.xcassets */,
@@ -325,13 +325,13 @@
325325
buildActionMask = 2147483647;
326326
files = (
327327
19ECD0D6232ED425003D8557 /* AppDelegate.swift in Sources */,
328+
193B614D27F5CD7D00080064 /* BridgeDelegate.mm in Sources */,
328329
19ECD0DA232ED425003D8557 /* ContentView.swift in Sources */,
329330
192DD201240FCAF5004E9CEB /* Manifest.swift in Sources */,
330331
197827FA27710D3400AEC655 /* Manifest+Decoder.swift in Sources */,
331332
196C724123319A85006556ED /* QRCodeScannerViewController.swift in Sources */,
332333
196C22622490CB7600449D3C /* React+Compatibility.m in Sources */,
333334
1963A06227C82E730013D276 /* React+Fabric.mm in Sources */,
334-
193B614D27F5CD7D00080064 /* React+TurboModule.mm in Sources */,
335335
196C7215232F1788006556ED /* ReactInstance.swift in Sources */,
336336
19ECD0D8232ED425003D8557 /* SceneDelegate.swift in Sources */,
337337
19A624A4258C95F000032776 /* Session.swift in Sources */,
Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
1-
#if USE_TURBOMODULE
2-
31
#import <React/RCTBridgeDelegate.h>
42

53
NS_ASSUME_NONNULL_BEGIN
64

7-
@interface RTATurboModuleManagerDelegate : NSObject <RCTBridgeDelegate>
5+
@interface RTABridgeDelegate : NSObject <RCTBridgeDelegate>
86
- (instancetype)initWithBridgeDelegate:(id<RCTBridgeDelegate>)bridgeDelegate;
97
@end
108

119
NS_ASSUME_NONNULL_END
12-
13-
#endif // USE_TURBOMODULE

ios/ReactTestApp/React+TurboModule.mm renamed to ios/ReactTestApp/BridgeDelegate.mm

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,24 @@
1-
#import "React+TurboModule.h"
1+
#import "BridgeDelegate.h"
22

3-
#if USE_TURBOMODULE
3+
#import <React/RCTCxxBridgeDelegate.h>
44

5+
#if USE_TURBOMODULE
56
#import <React/CoreModulesPlugins.h>
67
#import <React/RCTAppSetupUtils.h>
7-
#import <React/RCTCxxBridgeDelegate.h>
8-
#import <React/RCTDataRequestHandler.h>
9-
#import <React/RCTFileRequestHandler.h>
10-
#import <React/RCTGIFImageDecoder.h>
11-
#import <React/RCTHTTPRequestHandler.h>
12-
#import <React/RCTImageLoader.h>
13-
#import <React/RCTJSIExecutorRuntimeInstaller.h>
14-
#import <React/RCTLocalAssetImageLoader.h>
15-
#import <React/RCTNetworking.h>
168
#import <ReactCommon/RCTTurboModuleManager.h>
179

18-
@interface RTATurboModuleManagerDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate>
10+
@interface RTABridgeDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate>
11+
@end
12+
#else
13+
@interface RTABridgeDelegate () <RCTCxxBridgeDelegate>
1914
@end
15+
#endif // USE_TURBOMODULE
2016

21-
@implementation RTATurboModuleManagerDelegate {
17+
@implementation RTABridgeDelegate {
2218
__weak id<RCTBridgeDelegate> _bridgeDelegate;
19+
#if USE_TURBOMODULE
2320
RCTTurboModuleManager *_turboModuleManager;
21+
#endif // USE_TURBOMODULE
2422
}
2523

2624
- (instancetype)initWithBridgeDelegate:(id<RCTBridgeDelegate>)bridgeDelegate
@@ -48,15 +46,20 @@ - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
4846
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:
4947
(RCTBridge *)bridge
5048
{
51-
if (_turboModuleManager == nil) {
52-
_turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
53-
delegate:self
54-
jsInvoker:bridge.jsCallInvoker];
55-
}
49+
#if USE_TURBOMODULE
50+
// jsExecutorFactoryForBridge: (USE_TURBOMODULE=1)
51+
_turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
52+
delegate:self
53+
jsInvoker:bridge.jsCallInvoker];
5654
return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager);
55+
#else
56+
// jsExecutorFactoryForBridge: (USE_TURBOMODULE=0)
57+
return nullptr;
58+
#endif // USE_TURBOMODULE
5759
}
5860

5961
// MARK: - RCTTurboModuleManagerDelegate details
62+
#if USE_TURBOMODULE
6063

6164
- (Class)getModuleClassFromName:(const char *)name
6265
{
@@ -75,6 +78,6 @@ - (Class)getModuleClassFromName:(const char *)name
7578
return RCTAppSetupDefaultModuleFromClass(moduleClass);
7679
}
7780

78-
@end
79-
8081
#endif // USE_TURBOMODULE
82+
83+
@end

ios/ReactTestApp/ReactInstance.swift

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,9 @@ final class ReactInstance: NSObject, RCTBridgeDelegate {
1616

1717
private var surfacePresenterBridgeAdapter: NSObject?
1818
private(set) var bridge: RCTBridge?
19+
private lazy var bridgeDelegate = RTABridgeDelegate(bridgeDelegate: self)
1920
private var bundleRoot: String?
2021

21-
#if USE_TURBOMODULE
22-
private lazy var turboModuleManagerDelegate = RTATurboModuleManagerDelegate(bridgeDelegate: self)
23-
#endif
24-
2522
override init() {
2623
#if DEBUG
2724
remoteBundleURL = ReactInstance.jsBundleURL()
@@ -112,17 +109,10 @@ final class ReactInstance: NSObject, RCTBridgeDelegate {
112109
object: nil
113110
)
114111

115-
#if USE_TURBOMODULE
116-
guard let bridge = RCTBridge(delegate: turboModuleManagerDelegate, launchOptions: nil) else {
117-
assertionFailure("Failed to instantiate RCTBridge with TurboModule")
118-
return
119-
}
120-
#else
121-
guard let bridge = RCTBridge(delegate: self, launchOptions: nil) else {
112+
guard let bridge = RCTBridge(delegate: bridgeDelegate, launchOptions: nil) else {
122113
assertionFailure("Failed to instantiate RCTBridge")
123114
return
124115
}
125-
#endif // USE_TURBOMODULE
126116

127117
surfacePresenterBridgeAdapter = RTACreateSurfacePresenterBridgeAdapter(bridge)
128118
self.bridge = bridge

ios/ReactTestApp/ReactTestApp-Bridging-Header.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@
2525
#import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
2626
#endif // USE_FLIPPER
2727

28+
#import "BridgeDelegate.h"
2829
#import "React+Compatibility.h"
2930
#import "React+Fabric.h"
30-
#import "React+TurboModule.h"
3131
#import "UIViewController+ReactTestApp.h"
3232

3333
// Generated by `validate-manifest.js`

macos/ReactTestApp.xcodeproj/project.pbxproj

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
archiveVersion = 1;
44
classes = {
55
};
6-
objectVersion = 52;
6+
objectVersion = 54;
77
objects = {
88

99
/* Begin PBXBuildFile section */
@@ -14,6 +14,7 @@
1414
193EF08F247A799D00BE8C79 /* Manifest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 193EF08E247A799D00BE8C79 /* Manifest.swift */; };
1515
193EF093247A830200BE8C79 /* UIViewController+ReactTestApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 193EF091247A830200BE8C79 /* UIViewController+ReactTestApp.m */; };
1616
193EF098247B130700BE8C79 /* ReactInstance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 193EF097247B130700BE8C79 /* ReactInstance.swift */; };
17+
19510B70291D717200E4CED7 /* BridgeDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 19510B6F291D717200E4CED7 /* BridgeDelegate.mm */; };
1718
1960F339258C97C400AEC7A2 /* Session.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1960F338258C97C400AEC7A2 /* Session.swift */; };
1819
1963A06527C82F7E0013D276 /* React+Fabric.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1963A06427C82F7E0013D276 /* React+Fabric.mm */; };
1920
196C22652490CBAB00449D3C /* React+Compatibility.m in Sources */ = {isa = PBXBuildFile; fileRef = 196C22632490CBAB00449D3C /* React+Compatibility.m */; };
@@ -56,6 +57,8 @@
5657
193EF092247A830200BE8C79 /* UIViewController+ReactTestApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIViewController+ReactTestApp.h"; path = "../ReactTestAppShared/UIViewController+ReactTestApp.h"; sourceTree = "<group>"; };
5758
193EF094247A84DA00BE8C79 /* ReactTestApp-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "ReactTestApp-Bridging-Header.h"; path = "../ReactTestAppShared/ReactTestApp-Bridging-Header.h"; sourceTree = "<group>"; };
5859
193EF097247B130700BE8C79 /* ReactInstance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ReactInstance.swift; path = ../ReactTestAppShared/ReactInstance.swift; sourceTree = "<group>"; };
60+
19510B6E291D717200E4CED7 /* BridgeDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BridgeDelegate.h; path = ../ReactTestAppShared/BridgeDelegate.h; sourceTree = "<group>"; };
61+
19510B6F291D717200E4CED7 /* BridgeDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = BridgeDelegate.mm; path = ../ReactTestAppShared/BridgeDelegate.mm; sourceTree = "<group>"; };
5962
1960F338258C97C400AEC7A2 /* Session.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Session.swift; path = ../ReactTestAppShared/Session.swift; sourceTree = "<group>"; };
6063
1963A06327C82F7E0013D276 /* React+Fabric.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "React+Fabric.h"; path = "../ReactTestAppShared/React+Fabric.h"; sourceTree = "<group>"; };
6164
1963A06427C82F7E0013D276 /* React+Fabric.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "React+Fabric.mm"; path = "../ReactTestAppShared/React+Fabric.mm"; sourceTree = "<group>"; };
@@ -124,6 +127,8 @@
124127
193EF097247B130700BE8C79 /* ReactInstance.swift */,
125128
1960F338258C97C400AEC7A2 /* Session.swift */,
126129
193EF064247A736200BE8C79 /* ViewController.swift */,
130+
19510B6E291D717200E4CED7 /* BridgeDelegate.h */,
131+
19510B6F291D717200E4CED7 /* BridgeDelegate.mm */,
127132
193EF094247A84DA00BE8C79 /* ReactTestApp-Bridging-Header.h */,
128133
196C22642490CBAB00449D3C /* React+Compatibility.h */,
129134
196C22632490CBAB00449D3C /* React+Compatibility.m */,
@@ -317,14 +322,15 @@
317322
buildActionMask = 2147483647;
318323
files = (
319324
193EF063247A736200BE8C79 /* AppDelegate.swift in Sources */,
325+
19510B70291D717200E4CED7 /* BridgeDelegate.mm in Sources */,
320326
193EF08F247A799D00BE8C79 /* Manifest.swift in Sources */,
321327
19C4C89327710D8500157870 /* Manifest+Decoder.swift in Sources */,
322328
196C22652490CBAB00449D3C /* React+Compatibility.m in Sources */,
323329
1963A06527C82F7E0013D276 /* React+Fabric.mm in Sources */,
324330
193EF098247B130700BE8C79 /* ReactInstance.swift in Sources */,
325331
1960F339258C97C400AEC7A2 /* Session.swift in Sources */,
326-
193EF065247A736200BE8C79 /* ViewController.swift in Sources */,
327332
193EF093247A830200BE8C79 /* UIViewController+ReactTestApp.m in Sources */,
333+
193EF065247A736200BE8C79 /* ViewController.swift in Sources */,
328334
);
329335
runOnlyForDeploymentPostprocessing = 0;
330336
};

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"/example/{metro,react-native}.config.js",
3434
"/ios",
3535
"/macos",
36+
"/plugins",
3637
"/schema.json",
3738
"/scripts/*.js",
3839
"/scripts/apply-config-plugins.mjs",

plugins/index.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
const { withMod } = require("@expo/config-plugins");
2+
3+
function withBridgeDelegate(config, action) {
4+
return withMod(config, {
5+
platform: "ios",
6+
mod: "bridgeDelegate",
7+
action,
8+
});
9+
}
10+
11+
function withSceneDelegate(config, action) {
12+
return withMod(config, {
13+
platform: "ios",
14+
mod: "sceneDelegate",
15+
action,
16+
});
17+
}
18+
19+
exports.withBridgeDelegate = withBridgeDelegate;
20+
exports.withSceneDelegate = withSceneDelegate;

plugins/reanimated.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
const { createRunOncePlugin } = require("@expo/config-plugins");
2+
const {
3+
mergeContents,
4+
} = require("@expo/config-plugins/build/utils/generateCode");
5+
const { withBridgeDelegate } = require("./index");
6+
7+
const NAME = "react-native-reanimated";
8+
9+
function addContents(tag, src, newSrc, anchor) {
10+
return mergeContents({
11+
tag: `${NAME}-${tag}`,
12+
src,
13+
newSrc,
14+
anchor,
15+
offset: 1,
16+
comment: "//",
17+
}).contents;
18+
}
19+
20+
function withReanimatedExecutor(config) {
21+
return withBridgeDelegate(config, (config) => {
22+
if (config.modResults.language !== "objcpp") {
23+
throw new Error(
24+
"`BridgeDelegate` is not in Objective-C++ (did that change recently?)"
25+
);
26+
}
27+
28+
// Add Reanimated headers
29+
config.modResults.contents = addContents(
30+
"header",
31+
config.modResults.contents,
32+
[
33+
"#pragma clang diagnostic push",
34+
'#pragma clang diagnostic ignored "-Wnullability-completeness"',
35+
"",
36+
"#import <RNReanimated/REAInitializer.h>",
37+
"",
38+
"#if __has_include(<reacthermes/HermesExecutorFactory.h>)",
39+
"#import <reacthermes/HermesExecutorFactory.h>",
40+
"using ExecutorFactory = HermesExecutorFactory;",
41+
"#elif __has_include(<React/HermesExecutorFactory.h>)",
42+
"#import <React/HermesExecutorFactory.h>",
43+
"using ExecutorFactory = HermesExecutorFactory;",
44+
"#else",
45+
"#import <React/JSCExecutorFactory.h>",
46+
"using ExecutorFactory = JSCExecutorFactory;",
47+
"#endif",
48+
"",
49+
"#pragma clang diagnostic pop",
50+
].join("\n"),
51+
/#import "BridgeDelegate\.h"/
52+
);
53+
54+
// Install Reanimated's JSI executor runtime
55+
const indent = " ";
56+
config.modResults.contents = addContents(
57+
"executor",
58+
config.modResults.contents,
59+
[
60+
`${indent}const auto installer = reanimated::REAJSIExecutorRuntimeInstaller(bridge, nullptr);`,
61+
`${indent}return std::make_unique<ExecutorFactory>(RCTJSIExecutorRuntimeInstaller(installer));`,
62+
].join("\n"),
63+
/\/\/ jsExecutorFactoryForBridge: \(USE_TURBOMODULE=0\)/
64+
);
65+
return config;
66+
});
67+
}
68+
69+
module.exports = createRunOncePlugin(
70+
withReanimatedExecutor,
71+
NAME,
72+
"UNVERSIONED"
73+
);

scripts/config-plugins/plugins/withIosBaseMods.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ const defaultProviders = {
3030
};
3131

3232
// `react-native-test-app` files
33+
defaultProviders["bridgeDelegate"] = modifyFilePath(
34+
expoProviders.appDelegate,
35+
"ReactTestApp/BridgeDelegate.mm"
36+
);
3337
defaultProviders["sceneDelegate"] = modifyFilePath(
3438
expoProviders.appDelegate,
3539
"ReactTestApp/SceneDelegate.swift"

0 commit comments

Comments
 (0)