react-native 0.74.1-rc.0 → 0.74.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Libraries/Components/TextInput/TextInput.js +6 -3
- package/Libraries/Components/Touchable/TouchableBounce.js +1 -0
- package/Libraries/Components/Touchable/TouchableOpacity.js +1 -0
- package/Libraries/Core/ReactNativeVersion.js +2 -2
- package/React/Base/RCTUtils.m +28 -8
- package/React/Base/RCTVersion.m +2 -2
- package/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.mm +0 -3
- package/React/Fabric/Mounting/ComponentViews/Root/RCTRootComponentView.mm +22 -1
- package/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +5 -1
- package/React/Modules/RCTUIManager.m +8 -9
- package/React/Views/RCTComponentData.m +14 -1
- package/ReactAndroid/api/ReactAndroid.api +1 -2
- package/ReactAndroid/gradle.properties +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/ReactActivity.java +2 -2
- package/ReactAndroid/src/main/java/com/facebook/react/ReactDelegate.java +24 -9
- package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java +2 -2
- package/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessCatalystInstance.kt +11 -18
- package/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java +27 -14
- package/ReactCommon/ReactCommon.podspec +1 -0
- package/ReactCommon/cxxreact/ReactNativeVersion.h +2 -2
- package/ReactCommon/jsc/JSCRuntime.cpp +2 -0
- package/ReactCommon/jsinspector-modern/React-jsinspector.podspec +2 -1
- package/ReactCommon/react/renderer/components/textinput/platform/ios/react/renderer/components/iostextinput/TextInputEventEmitter.cpp +53 -1
- package/cli.js +11 -3
- package/package.json +11 -11
- package/scripts/cocoapods/privacy_manifest_utils.rb +173 -0
- package/scripts/cocoapods/utils.rb +1 -38
- package/scripts/ios-configure-glog.sh +9 -2
- package/scripts/react_native_pods.rb +14 -3
- package/sdks/.hermesversion +1 -1
- package/sdks/hermesc/osx-bin/hermes +0 -0
- package/sdks/hermesc/osx-bin/hermesc +0 -0
- package/sdks/hermesc/win64-bin/hermesc.exe +0 -0
- package/template/package.json +5 -5
- package/third-party-podspecs/RCT-Folly.podspec +1 -0
|
@@ -1135,12 +1135,14 @@ function InternalTextInput(props: Props): React.Node {
|
|
|
1135
1135
|
};
|
|
1136
1136
|
|
|
1137
1137
|
const [mostRecentEventCount, setMostRecentEventCount] = useState<number>(0);
|
|
1138
|
-
|
|
1139
1138
|
const [lastNativeText, setLastNativeText] = useState<?Stringish>(props.value);
|
|
1140
1139
|
const [lastNativeSelectionState, setLastNativeSelection] = useState<{|
|
|
1141
|
-
selection:
|
|
1140
|
+
selection: Selection,
|
|
1142
1141
|
mostRecentEventCount: number,
|
|
1143
|
-
|}>({
|
|
1142
|
+
|}>({
|
|
1143
|
+
selection: {start: -1, end: -1},
|
|
1144
|
+
mostRecentEventCount: mostRecentEventCount,
|
|
1145
|
+
});
|
|
1144
1146
|
|
|
1145
1147
|
const lastNativeSelection = lastNativeSelectionState.selection;
|
|
1146
1148
|
|
|
@@ -1498,6 +1500,7 @@ function InternalTextInput(props: Props): React.Node {
|
|
|
1498
1500
|
onSelectionChange={_onSelectionChange}
|
|
1499
1501
|
onSelectionChangeShouldSetResponder={emptyFunctionThatReturnsTrue}
|
|
1500
1502
|
selection={selection}
|
|
1503
|
+
selectionColor={selectionColor}
|
|
1501
1504
|
style={StyleSheet.compose(
|
|
1502
1505
|
useMultilineDefaultStyle ? styles.multilineDefault : null,
|
|
1503
1506
|
style,
|
package/React/Base/RCTUtils.m
CHANGED
|
@@ -562,17 +562,37 @@ UIWindow *__nullable RCTKeyWindow(void)
|
|
|
562
562
|
return nil;
|
|
563
563
|
}
|
|
564
564
|
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
565
|
+
NSSet<UIScene *> *connectedScenes = RCTSharedApplication().connectedScenes;
|
|
566
|
+
|
|
567
|
+
UIScene *foregroundActiveScene;
|
|
568
|
+
UIScene *foregroundInactiveScene;
|
|
569
|
+
|
|
570
|
+
for (UIScene *scene in connectedScenes) {
|
|
571
|
+
if (![scene isKindOfClass:[UIWindowScene class]]) {
|
|
568
572
|
continue;
|
|
569
573
|
}
|
|
570
|
-
UIWindowScene *windowScene = (UIWindowScene *)scene;
|
|
571
574
|
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
575
|
+
if (scene.activationState == UISceneActivationStateForegroundActive) {
|
|
576
|
+
foregroundActiveScene = scene;
|
|
577
|
+
break;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
if (!foregroundInactiveScene && scene.activationState == UISceneActivationStateForegroundInactive) {
|
|
581
|
+
foregroundInactiveScene = scene;
|
|
582
|
+
// no break, we can have the active scene later in the set.
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
UIScene *sceneToUse = foregroundActiveScene ? foregroundActiveScene : foregroundInactiveScene;
|
|
587
|
+
UIWindowScene *windowScene = (UIWindowScene *)sceneToUse;
|
|
588
|
+
|
|
589
|
+
if (@available(iOS 15.0, *)) {
|
|
590
|
+
return windowScene.keyWindow;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
for (UIWindow *window in windowScene.windows) {
|
|
594
|
+
if (window.isKeyWindow) {
|
|
595
|
+
return window;
|
|
576
596
|
}
|
|
577
597
|
}
|
|
578
598
|
|
package/React/Base/RCTVersion.m
CHANGED
|
@@ -23,8 +23,8 @@ NSDictionary* RCTGetReactNativeVersion(void)
|
|
|
23
23
|
__rnVersion = @{
|
|
24
24
|
RCTVersionMajor: @(0),
|
|
25
25
|
RCTVersionMinor: @(74),
|
|
26
|
-
RCTVersionPatch: @(
|
|
27
|
-
RCTVersionPrerelease:
|
|
26
|
+
RCTVersionPatch: @(2),
|
|
27
|
+
RCTVersionPrerelease: [NSNull null],
|
|
28
28
|
};
|
|
29
29
|
});
|
|
30
30
|
return __rnVersion;
|
|
@@ -125,9 +125,6 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder)
|
|
|
125
125
|
[super surface:surface didChangeStage:stage];
|
|
126
126
|
if (RCTSurfaceStageIsRunning(stage)) {
|
|
127
127
|
[_bridge.performanceLogger markStopForTag:RCTPLTTI];
|
|
128
|
-
dispatch_async(dispatch_get_main_queue(), ^{
|
|
129
|
-
[[NSNotificationCenter defaultCenter] postNotificationName:RCTContentDidAppearNotification object:self];
|
|
130
|
-
});
|
|
131
128
|
}
|
|
132
129
|
}
|
|
133
130
|
|
|
@@ -7,18 +7,22 @@
|
|
|
7
7
|
|
|
8
8
|
#import "RCTRootComponentView.h"
|
|
9
9
|
|
|
10
|
+
#import <React/RCTRootView.h>
|
|
10
11
|
#import <react/renderer/components/root/RootComponentDescriptor.h>
|
|
11
12
|
#import <react/renderer/components/root/RootProps.h>
|
|
12
13
|
#import "RCTConversions.h"
|
|
13
14
|
|
|
14
15
|
using namespace facebook::react;
|
|
15
16
|
|
|
16
|
-
@implementation RCTRootComponentView
|
|
17
|
+
@implementation RCTRootComponentView {
|
|
18
|
+
BOOL _contentHasAppeared;
|
|
19
|
+
}
|
|
17
20
|
|
|
18
21
|
- (instancetype)initWithFrame:(CGRect)frame
|
|
19
22
|
{
|
|
20
23
|
if (self = [super initWithFrame:frame]) {
|
|
21
24
|
_props = RootShadowNode::defaultSharedProps();
|
|
25
|
+
_contentHasAppeared = NO;
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
return self;
|
|
@@ -26,6 +30,23 @@ using namespace facebook::react;
|
|
|
26
30
|
|
|
27
31
|
#pragma mark - RCTComponentViewProtocol
|
|
28
32
|
|
|
33
|
+
- (void)prepareForRecycle
|
|
34
|
+
{
|
|
35
|
+
[super prepareForRecycle];
|
|
36
|
+
_contentHasAppeared = NO;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
|
|
40
|
+
{
|
|
41
|
+
[super mountChildComponentView:childComponentView index:index];
|
|
42
|
+
if (!self->_contentHasAppeared) {
|
|
43
|
+
self->_contentHasAppeared = YES;
|
|
44
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
45
|
+
[[NSNotificationCenter defaultCenter] postNotificationName:RCTContentDidAppearNotification object:self];
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
29
50
|
+ (ComponentDescriptorProvider)componentDescriptorProvider
|
|
30
51
|
{
|
|
31
52
|
return concreteComponentDescriptorProvider<RootComponentDescriptor>();
|
|
@@ -420,6 +420,11 @@ static void RCTSendScrollEventForNativeAnimations_DEPRECATED(UIScrollView *scrol
|
|
|
420
420
|
|
|
421
421
|
- (void)prepareForRecycle
|
|
422
422
|
{
|
|
423
|
+
[super prepareForRecycle];
|
|
424
|
+
// Must invalidate state before setting contentOffset on ScrollView.
|
|
425
|
+
// Otherwise the state will be propagated to shadow tree.
|
|
426
|
+
_state.reset();
|
|
427
|
+
|
|
423
428
|
const auto &props = static_cast<const ScrollViewProps &>(*_props);
|
|
424
429
|
_scrollView.contentOffset = RCTCGPointFromPoint(props.contentOffset);
|
|
425
430
|
// We set the default behavior to "never" so that iOS
|
|
@@ -427,7 +432,6 @@ static void RCTSendScrollEventForNativeAnimations_DEPRECATED(UIScrollView *scrol
|
|
|
427
432
|
// and keeps it as an opt-in behavior.
|
|
428
433
|
_scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
|
|
429
434
|
_shouldUpdateContentInsetAdjustmentBehavior = YES;
|
|
430
|
-
_state.reset();
|
|
431
435
|
_isUserTriggeredScrolling = NO;
|
|
432
436
|
CGRect oldFrame = self.frame;
|
|
433
437
|
self.frame = CGRectZero;
|
|
@@ -1674,8 +1674,8 @@ static UIView *_jsResponder;
|
|
|
1674
1674
|
{
|
|
1675
1675
|
self = [super init];
|
|
1676
1676
|
if (self) {
|
|
1677
|
-
|
|
1678
|
-
|
|
1677
|
+
_uiManager = uiManager;
|
|
1678
|
+
_registry = registry;
|
|
1679
1679
|
}
|
|
1680
1680
|
return self;
|
|
1681
1681
|
}
|
|
@@ -1693,26 +1693,27 @@ static UIView *_jsResponder;
|
|
|
1693
1693
|
- (id)objectForKey:(id)key
|
|
1694
1694
|
{
|
|
1695
1695
|
if (![key isKindOfClass:[NSNumber class]]) {
|
|
1696
|
-
return
|
|
1696
|
+
return NULL;
|
|
1697
1697
|
}
|
|
1698
1698
|
|
|
1699
1699
|
NSNumber *index = (NSNumber *)key;
|
|
1700
|
-
UIView *view = [
|
|
1700
|
+
UIView *view = _registry[index];
|
|
1701
1701
|
if (view) {
|
|
1702
1702
|
return [RCTUIManager paperViewOrCurrentView:view];
|
|
1703
1703
|
}
|
|
1704
|
-
view =
|
|
1704
|
+
view = [_uiManager viewForReactTag:index];
|
|
1705
1705
|
if (view) {
|
|
1706
1706
|
return [RCTUIManager paperViewOrCurrentView:view];
|
|
1707
1707
|
}
|
|
1708
|
-
return
|
|
1708
|
+
return NULL;
|
|
1709
1709
|
}
|
|
1710
1710
|
|
|
1711
1711
|
- (void)removeObjectForKey:(id)key
|
|
1712
1712
|
{
|
|
1713
1713
|
if (![key isKindOfClass:[NSNumber class]]) {
|
|
1714
|
-
return
|
|
1714
|
+
return;
|
|
1715
1715
|
}
|
|
1716
|
+
|
|
1716
1717
|
NSNumber *tag = (NSNumber *)key;
|
|
1717
1718
|
|
|
1718
1719
|
if (_registry[key]) {
|
|
@@ -1720,8 +1721,6 @@ static UIView *_jsResponder;
|
|
|
1720
1721
|
[mutableRegistry removeObjectForKey:tag];
|
|
1721
1722
|
} else if ([_uiManager viewForReactTag:tag]) {
|
|
1722
1723
|
[_uiManager removeViewFromRegistry:tag];
|
|
1723
|
-
} else {
|
|
1724
|
-
[super removeObjectForKey:key];
|
|
1725
1724
|
}
|
|
1726
1725
|
}
|
|
1727
1726
|
|
|
@@ -416,7 +416,20 @@ static RCTPropBlock createNSInvocationSetter(NSMethodSignature *typeSignature, S
|
|
|
416
416
|
+ (NSDictionary<NSString *, id> *)constantsForViewMangerClass:(Class)managerClass
|
|
417
417
|
{
|
|
418
418
|
if ([managerClass instancesRespondToSelector:@selector(constantsToExport)]) {
|
|
419
|
-
|
|
419
|
+
BOOL shouldRunOnMainThread = NO;
|
|
420
|
+
|
|
421
|
+
if ([managerClass respondsToSelector:@selector(requiresMainQueueSetup)]) {
|
|
422
|
+
shouldRunOnMainThread = [managerClass requiresMainQueueSetup];
|
|
423
|
+
}
|
|
424
|
+
if (shouldRunOnMainThread) {
|
|
425
|
+
__block NSDictionary<NSString *, id> *constants;
|
|
426
|
+
RCTUnsafeExecuteOnMainQueueSync(^{
|
|
427
|
+
constants = [[managerClass new] constantsToExport];
|
|
428
|
+
});
|
|
429
|
+
return constants;
|
|
430
|
+
} else {
|
|
431
|
+
return [[managerClass new] constantsToExport];
|
|
432
|
+
}
|
|
420
433
|
}
|
|
421
434
|
return @{};
|
|
422
435
|
}
|
|
@@ -92,7 +92,7 @@ public abstract class com/facebook/react/ReactActivity : androidx/appcompat/app/
|
|
|
92
92
|
protected fun <init> ()V
|
|
93
93
|
protected fun createReactActivityDelegate ()Lcom/facebook/react/ReactActivityDelegate;
|
|
94
94
|
protected fun getMainComponentName ()Ljava/lang/String;
|
|
95
|
-
public fun getReactDelegate ()
|
|
95
|
+
public fun getReactDelegate ()Lcom/facebook/react/ReactDelegate;
|
|
96
96
|
protected final fun getReactInstanceManager ()Lcom/facebook/react/ReactInstanceManager;
|
|
97
97
|
protected final fun getReactNativeHost ()Lcom/facebook/react/ReactNativeHost;
|
|
98
98
|
public fun invokeDefaultOnBackPressed ()V
|
|
@@ -7697,4 +7697,3 @@ public class com/facebook/react/views/view/ViewGroupClickEvent : com/facebook/re
|
|
|
7697
7697
|
protected fun getEventData ()Lcom/facebook/react/bridge/WritableMap;
|
|
7698
7698
|
public fun getEventName ()Ljava/lang/String;
|
|
7699
7699
|
}
|
|
7700
|
-
|
|
@@ -65,8 +65,8 @@ public abstract class ReactActivity extends AppCompatActivity
|
|
|
65
65
|
mDelegate.onDestroy();
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
public
|
|
69
|
-
mDelegate.getReactDelegate();
|
|
68
|
+
public @Nullable ReactDelegate getReactDelegate() {
|
|
69
|
+
return mDelegate.getReactDelegate();
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
@Override
|
|
@@ -15,6 +15,7 @@ import android.view.KeyEvent;
|
|
|
15
15
|
import androidx.annotation.NonNull;
|
|
16
16
|
import androidx.annotation.Nullable;
|
|
17
17
|
import com.facebook.infer.annotation.Assertions;
|
|
18
|
+
import com.facebook.react.bridge.UiThreadUtil;
|
|
18
19
|
import com.facebook.react.config.ReactFeatureFlags;
|
|
19
20
|
import com.facebook.react.devsupport.DisabledDevSupportManager;
|
|
20
21
|
import com.facebook.react.devsupport.DoubleTapReloadRecognizer;
|
|
@@ -99,7 +100,7 @@ public class ReactDelegate {
|
|
|
99
100
|
&& mReactHost.getDevSupportManager() != null) {
|
|
100
101
|
return mReactHost.getDevSupportManager();
|
|
101
102
|
} else if (getReactNativeHost().hasInstance()
|
|
102
|
-
&& getReactNativeHost().
|
|
103
|
+
&& getReactNativeHost().getReactInstanceManager() != null) {
|
|
103
104
|
return getReactNativeHost().getReactInstanceManager().getDevSupportManager();
|
|
104
105
|
} else {
|
|
105
106
|
return null;
|
|
@@ -241,17 +242,31 @@ public class ReactDelegate {
|
|
|
241
242
|
|
|
242
243
|
public void reload() {
|
|
243
244
|
DevSupportManager devSupportManager = getDevSupportManager();
|
|
244
|
-
if (devSupportManager
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
245
|
+
if (devSupportManager == null) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Reload in RELEASE mode
|
|
250
|
+
if (devSupportManager instanceof DisabledDevSupportManager) {
|
|
251
|
+
// Do not reload the bundle from JS as there is no bundler running in release mode.
|
|
252
|
+
if (ReactFeatureFlags.enableBridgelessArchitecture) {
|
|
253
|
+
if (mReactHost != null) {
|
|
254
|
+
mReactHost.reload("ReactDelegate.reload()");
|
|
255
|
+
}
|
|
251
256
|
} else {
|
|
252
|
-
|
|
257
|
+
UiThreadUtil.runOnUiThread(
|
|
258
|
+
() -> {
|
|
259
|
+
if (mReactNativeHost.hasInstance()
|
|
260
|
+
&& mReactNativeHost.getReactInstanceManager() != null) {
|
|
261
|
+
mReactNativeHost.getReactInstanceManager().recreateReactContextInBackground();
|
|
262
|
+
}
|
|
263
|
+
});
|
|
253
264
|
}
|
|
265
|
+
return;
|
|
254
266
|
}
|
|
267
|
+
|
|
268
|
+
// Reload in DEBUG mode
|
|
269
|
+
devSupportManager.handleReloadJS();
|
|
255
270
|
}
|
|
256
271
|
|
|
257
272
|
public void loadApp() {
|
|
@@ -92,25 +92,20 @@ public class BridgelessCatalystInstance(private val reactHost: ReactHostImpl) :
|
|
|
92
92
|
throw UnsupportedOperationException("Unimplemented method 'initialize'")
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
override fun getReactQueueConfiguration(): ReactQueueConfiguration
|
|
96
|
-
|
|
97
|
-
}
|
|
95
|
+
override fun getReactQueueConfiguration(): ReactQueueConfiguration =
|
|
96
|
+
reactHost.reactQueueConfiguration!!
|
|
98
97
|
|
|
99
|
-
override fun <T : JavaScriptModule> getJSModule(jsInterface: Class<T>): T
|
|
100
|
-
|
|
101
|
-
}
|
|
98
|
+
override fun <T : JavaScriptModule> getJSModule(jsInterface: Class<T>): T =
|
|
99
|
+
reactHost.currentReactContext?.getJSModule(jsInterface)!!
|
|
102
100
|
|
|
103
|
-
override fun <T : NativeModule> hasNativeModule(nativeModuleInterface: Class<T>): Boolean
|
|
104
|
-
|
|
105
|
-
}
|
|
101
|
+
override fun <T : NativeModule> hasNativeModule(nativeModuleInterface: Class<T>): Boolean =
|
|
102
|
+
reactHost.hasNativeModule(nativeModuleInterface)
|
|
106
103
|
|
|
107
|
-
override fun <T : NativeModule> getNativeModule(nativeModuleInterface: Class<T>): T?
|
|
108
|
-
|
|
109
|
-
}
|
|
104
|
+
override fun <T : NativeModule> getNativeModule(nativeModuleInterface: Class<T>): T? =
|
|
105
|
+
reactHost.getNativeModule(nativeModuleInterface)
|
|
110
106
|
|
|
111
|
-
override fun getNativeModule(moduleName: String): NativeModule?
|
|
112
|
-
|
|
113
|
-
}
|
|
107
|
+
override fun getNativeModule(moduleName: String): NativeModule? =
|
|
108
|
+
reactHost.getNativeModule(moduleName)
|
|
114
109
|
|
|
115
110
|
@Deprecated(
|
|
116
111
|
message =
|
|
@@ -119,9 +114,7 @@ public class BridgelessCatalystInstance(private val reactHost: ReactHostImpl) :
|
|
|
119
114
|
throw UnsupportedOperationException("Unimplemented method 'getJSIModule'")
|
|
120
115
|
}
|
|
121
116
|
|
|
122
|
-
override fun getNativeModules(): Collection<NativeModule>
|
|
123
|
-
throw UnsupportedOperationException("Unimplemented method 'getNativeModules'")
|
|
124
|
-
}
|
|
117
|
+
override fun getNativeModules(): Collection<NativeModule> = reactHost.getNativeModules()
|
|
125
118
|
|
|
126
119
|
override fun extendNativeModules(modules: NativeModuleRegistry) {
|
|
127
120
|
throw UnsupportedOperationException("Unimplemented method 'extendNativeModules'")
|
|
@@ -592,6 +592,16 @@ public class ReactHostImpl implements ReactHost {
|
|
|
592
592
|
return null;
|
|
593
593
|
}
|
|
594
594
|
|
|
595
|
+
/* package */
|
|
596
|
+
@Nullable
|
|
597
|
+
NativeModule getNativeModule(String nativeModuleName) {
|
|
598
|
+
final ReactInstance reactInstance = mReactInstanceTaskRef.get().getResult();
|
|
599
|
+
if (reactInstance != null) {
|
|
600
|
+
return reactInstance.getNativeModule(nativeModuleName);
|
|
601
|
+
}
|
|
602
|
+
return null;
|
|
603
|
+
}
|
|
604
|
+
|
|
595
605
|
/* package */
|
|
596
606
|
@Nullable
|
|
597
607
|
RuntimeExecutor getRuntimeExecutor() {
|
|
@@ -643,11 +653,12 @@ public class ReactHostImpl implements ReactHost {
|
|
|
643
653
|
ReactContext currentContext = getCurrentReactContext();
|
|
644
654
|
if (currentContext != null) {
|
|
645
655
|
currentContext.onActivityResult(activity, requestCode, resultCode, data);
|
|
656
|
+
} else {
|
|
657
|
+
ReactSoftExceptionLogger.logSoftException(
|
|
658
|
+
TAG,
|
|
659
|
+
new ReactNoCrashSoftException(
|
|
660
|
+
"Tried to access onActivityResult while context is not ready"));
|
|
646
661
|
}
|
|
647
|
-
ReactSoftExceptionLogger.logSoftException(
|
|
648
|
-
TAG,
|
|
649
|
-
new ReactNoCrashSoftException(
|
|
650
|
-
"Tried to access onActivityResult while context is not ready"));
|
|
651
662
|
}
|
|
652
663
|
|
|
653
664
|
/* To be called when focus has changed for the hosting window. */
|
|
@@ -660,11 +671,12 @@ public class ReactHostImpl implements ReactHost {
|
|
|
660
671
|
ReactContext currentContext = getCurrentReactContext();
|
|
661
672
|
if (currentContext != null) {
|
|
662
673
|
currentContext.onWindowFocusChange(hasFocus);
|
|
674
|
+
} else {
|
|
675
|
+
ReactSoftExceptionLogger.logSoftException(
|
|
676
|
+
TAG,
|
|
677
|
+
new ReactNoCrashSoftException(
|
|
678
|
+
"Tried to access onWindowFocusChange while context is not ready"));
|
|
663
679
|
}
|
|
664
|
-
ReactSoftExceptionLogger.logSoftException(
|
|
665
|
-
TAG,
|
|
666
|
-
new ReactNoCrashSoftException(
|
|
667
|
-
"Tried to access onWindowFocusChange while context is not ready"));
|
|
668
680
|
}
|
|
669
681
|
|
|
670
682
|
/* This method will give JS the opportunity to receive intents via Linking.
|
|
@@ -691,10 +703,11 @@ public class ReactHostImpl implements ReactHost {
|
|
|
691
703
|
}
|
|
692
704
|
}
|
|
693
705
|
currentContext.onNewIntent(getCurrentActivity(), intent);
|
|
706
|
+
} else {
|
|
707
|
+
ReactSoftExceptionLogger.logSoftException(
|
|
708
|
+
TAG,
|
|
709
|
+
new ReactNoCrashSoftException("Tried to access onNewIntent while context is not ready"));
|
|
694
710
|
}
|
|
695
|
-
ReactSoftExceptionLogger.logSoftException(
|
|
696
|
-
TAG,
|
|
697
|
-
new ReactNoCrashSoftException("Tried to access onNewIntent while context is not ready"));
|
|
698
711
|
}
|
|
699
712
|
|
|
700
713
|
@ThreadConfined(UI)
|
|
@@ -1513,9 +1526,9 @@ public class ReactHostImpl implements ReactHost {
|
|
|
1513
1526
|
|
|
1514
1527
|
// Step 3: Stop all React Native surfaces
|
|
1515
1528
|
stopAttachedSurfaces(method, reactInstance);
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1529
|
+
synchronized (mAttachedSurfaces) {
|
|
1530
|
+
mAttachedSurfaces.clear();
|
|
1531
|
+
}
|
|
1519
1532
|
|
|
1520
1533
|
return task;
|
|
1521
1534
|
},
|
|
@@ -36,6 +36,7 @@ Pod::Spec.new do |s|
|
|
|
36
36
|
s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags
|
|
37
37
|
s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fmt/include\" \"$(PODS_ROOT)/Headers/Private/React-Core\"",
|
|
38
38
|
"USE_HEADERMAP" => "YES",
|
|
39
|
+
"DEFINES_MODULE" => "YES",
|
|
39
40
|
"CLANG_CXX_LANGUAGE_STANDARD" => "c++20",
|
|
40
41
|
"GCC_WARN_PEDANTIC" => "YES" }
|
|
41
42
|
if ENV['USE_FRAMEWORKS']
|
|
@@ -17,8 +17,8 @@ namespace facebook::react {
|
|
|
17
17
|
constexpr struct {
|
|
18
18
|
int32_t Major = 0;
|
|
19
19
|
int32_t Minor = 74;
|
|
20
|
-
int32_t Patch =
|
|
21
|
-
std::string_view Prerelease = "
|
|
20
|
+
int32_t Patch = 2;
|
|
21
|
+
std::string_view Prerelease = "";
|
|
22
22
|
} ReactNativeVersion;
|
|
23
23
|
|
|
24
24
|
} // namespace facebook::react
|
|
@@ -370,11 +370,13 @@ JSCRuntime::JSCRuntime(JSGlobalContextRef ctx)
|
|
|
370
370
|
{
|
|
371
371
|
#ifndef NDEBUG
|
|
372
372
|
#ifdef _JSC_HAS_INSPECTABLE
|
|
373
|
+
#if (__OSX_AVAILABLE_STARTING(MAC_NA, IPHONE_16_4))
|
|
373
374
|
if (__builtin_available(macOS 13.3, iOS 16.4, tvOS 16.4, *)) {
|
|
374
375
|
JSGlobalContextSetInspectable(ctx_, true);
|
|
375
376
|
}
|
|
376
377
|
#endif
|
|
377
378
|
#endif
|
|
379
|
+
#endif
|
|
378
380
|
}
|
|
379
381
|
|
|
380
382
|
JSCRuntime::~JSCRuntime() {
|
|
@@ -38,7 +38,8 @@ Pod::Spec.new do |s|
|
|
|
38
38
|
s.compiler_flags = folly_compiler_flags
|
|
39
39
|
s.pod_target_xcconfig = {
|
|
40
40
|
"HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/..\" \"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/RCT-Folly\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fmt/include\"",
|
|
41
|
-
"CLANG_CXX_LANGUAGE_STANDARD" => "c++20"
|
|
41
|
+
"CLANG_CXX_LANGUAGE_STANDARD" => "c++20",
|
|
42
|
+
"DEFINES_MODULE" => "YES"
|
|
42
43
|
}.merge!(use_frameworks ? {
|
|
43
44
|
"PUBLIC_HEADERS_FOLDER_PATH" => "#{module_name}.framework/Headers/#{header_dir}"
|
|
44
45
|
} : {})
|
|
@@ -36,6 +36,56 @@ static jsi::Value textInputMetricsPayload(
|
|
|
36
36
|
return payload;
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
+
static jsi::Value textInputMetricsScrollPayload(
|
|
40
|
+
jsi::Runtime& runtime,
|
|
41
|
+
const TextInputMetrics& textInputMetrics) {
|
|
42
|
+
auto payload = jsi::Object(runtime);
|
|
43
|
+
|
|
44
|
+
{
|
|
45
|
+
auto contentOffset = jsi::Object(runtime);
|
|
46
|
+
contentOffset.setProperty(runtime, "x", textInputMetrics.contentOffset.x);
|
|
47
|
+
contentOffset.setProperty(runtime, "y", textInputMetrics.contentOffset.y);
|
|
48
|
+
payload.setProperty(runtime, "contentOffset", contentOffset);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
{
|
|
52
|
+
auto contentInset = jsi::Object(runtime);
|
|
53
|
+
contentInset.setProperty(runtime, "top", textInputMetrics.contentInset.top);
|
|
54
|
+
contentInset.setProperty(
|
|
55
|
+
runtime, "left", textInputMetrics.contentInset.left);
|
|
56
|
+
contentInset.setProperty(
|
|
57
|
+
runtime, "bottom", textInputMetrics.contentInset.bottom);
|
|
58
|
+
contentInset.setProperty(
|
|
59
|
+
runtime, "right", textInputMetrics.contentInset.right);
|
|
60
|
+
payload.setProperty(runtime, "contentInset", contentInset);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
{
|
|
64
|
+
auto contentSize = jsi::Object(runtime);
|
|
65
|
+
contentSize.setProperty(
|
|
66
|
+
runtime, "width", textInputMetrics.contentSize.width);
|
|
67
|
+
contentSize.setProperty(
|
|
68
|
+
runtime, "height", textInputMetrics.contentSize.height);
|
|
69
|
+
payload.setProperty(runtime, "contentSize", contentSize);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
{
|
|
73
|
+
auto layoutMeasurement = jsi::Object(runtime);
|
|
74
|
+
layoutMeasurement.setProperty(
|
|
75
|
+
runtime, "width", textInputMetrics.layoutMeasurement.width);
|
|
76
|
+
layoutMeasurement.setProperty(
|
|
77
|
+
runtime, "height", textInputMetrics.layoutMeasurement.height);
|
|
78
|
+
payload.setProperty(runtime, "layoutMeasurement", layoutMeasurement);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
payload.setProperty(
|
|
82
|
+
runtime,
|
|
83
|
+
"zoomScale",
|
|
84
|
+
textInputMetrics.zoomScale ? textInputMetrics.zoomScale : 1);
|
|
85
|
+
|
|
86
|
+
return payload;
|
|
87
|
+
};
|
|
88
|
+
|
|
39
89
|
static jsi::Value textInputMetricsContentSizePayload(
|
|
40
90
|
jsi::Runtime& runtime,
|
|
41
91
|
const TextInputMetrics& textInputMetrics) {
|
|
@@ -140,7 +190,9 @@ void TextInputEventEmitter::onKeyPressSync(
|
|
|
140
190
|
|
|
141
191
|
void TextInputEventEmitter::onScroll(
|
|
142
192
|
const TextInputMetrics& textInputMetrics) const {
|
|
143
|
-
|
|
193
|
+
dispatchEvent("scroll", [textInputMetrics](jsi::Runtime& runtime) {
|
|
194
|
+
return textInputMetricsScrollPayload(runtime, textInputMetrics);
|
|
195
|
+
});
|
|
144
196
|
}
|
|
145
197
|
|
|
146
198
|
void TextInputEventEmitter::dispatchTextInputEvent(
|
package/cli.js
CHANGED
|
@@ -17,6 +17,7 @@ const {get} = require('https');
|
|
|
17
17
|
const {URL} = require('url');
|
|
18
18
|
|
|
19
19
|
const isNpxRuntime = process.env.npm_lifecycle_event === 'npx';
|
|
20
|
+
const isInitCommand = process.argv[2] === 'init';
|
|
20
21
|
const DEFAULT_REGISTRY_HOST =
|
|
21
22
|
process.env.npm_config_registry ?? 'https://registry.npmjs.org/';
|
|
22
23
|
const HEAD = '1000.0.0';
|
|
@@ -44,8 +45,10 @@ async function getLatestVersion(registryHost = DEFAULT_REGISTRY_HOST) {
|
|
|
44
45
|
* @see https://github.com/react-native-community/discussions-and-proposals/tree/main/proposals/0759-react-native-frameworks.md
|
|
45
46
|
*/
|
|
46
47
|
function warnWhenRunningInit() {
|
|
47
|
-
if (
|
|
48
|
-
console.warn(
|
|
48
|
+
if (isInitCommand) {
|
|
49
|
+
console.warn(
|
|
50
|
+
`\nRunning: ${chalk.grey.bold('npx @react-native-community/cli init')}\n`,
|
|
51
|
+
);
|
|
49
52
|
}
|
|
50
53
|
}
|
|
51
54
|
|
|
@@ -59,7 +62,12 @@ function warnWhenRunningInit() {
|
|
|
59
62
|
*
|
|
60
63
|
*/
|
|
61
64
|
async function main() {
|
|
62
|
-
if (
|
|
65
|
+
if (
|
|
66
|
+
isNpxRuntime &&
|
|
67
|
+
!process.env.SKIP &&
|
|
68
|
+
currentVersion !== HEAD &&
|
|
69
|
+
isInitCommand
|
|
70
|
+
) {
|
|
63
71
|
try {
|
|
64
72
|
const latest = await getLatestVersion();
|
|
65
73
|
if (latest !== currentVersion) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native",
|
|
3
|
-
"version": "0.74.
|
|
3
|
+
"version": "0.74.2",
|
|
4
4
|
"description": "A framework for building native apps using React",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -107,16 +107,16 @@
|
|
|
107
107
|
},
|
|
108
108
|
"dependencies": {
|
|
109
109
|
"@jest/create-cache-key-function": "^29.6.3",
|
|
110
|
-
"@react-native-community/cli": "13.6.
|
|
111
|
-
"@react-native-community/cli-platform-android": "13.6.
|
|
112
|
-
"@react-native-community/cli-platform-ios": "13.6.
|
|
113
|
-
"@react-native/assets-registry": "0.74.
|
|
114
|
-
"@react-native/codegen": "0.74.
|
|
115
|
-
"@react-native/community-cli-plugin": "0.74.
|
|
116
|
-
"@react-native/gradle-plugin": "0.74.
|
|
117
|
-
"@react-native/js-polyfills": "0.74.
|
|
118
|
-
"@react-native/normalize-colors": "0.74.
|
|
119
|
-
"@react-native/virtualized-lists": "0.74.
|
|
110
|
+
"@react-native-community/cli": "13.6.8",
|
|
111
|
+
"@react-native-community/cli-platform-android": "13.6.8",
|
|
112
|
+
"@react-native-community/cli-platform-ios": "13.6.8",
|
|
113
|
+
"@react-native/assets-registry": "0.74.84",
|
|
114
|
+
"@react-native/codegen": "0.74.84",
|
|
115
|
+
"@react-native/community-cli-plugin": "0.74.84",
|
|
116
|
+
"@react-native/gradle-plugin": "0.74.84",
|
|
117
|
+
"@react-native/js-polyfills": "0.74.84",
|
|
118
|
+
"@react-native/normalize-colors": "0.74.84",
|
|
119
|
+
"@react-native/virtualized-lists": "0.74.84",
|
|
120
120
|
"abort-controller": "^3.0.0",
|
|
121
121
|
"anser": "^1.4.9",
|
|
122
122
|
"ansi-regex": "^5.0.0",
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
#
|
|
3
|
+
# This source code is licensed under the MIT license found in the
|
|
4
|
+
# LICENSE file in the root directory of this source tree.
|
|
5
|
+
|
|
6
|
+
module PrivacyManifestUtils
|
|
7
|
+
def self.add_aggregated_privacy_manifest(installer)
|
|
8
|
+
user_project = get_user_project_from(installer)
|
|
9
|
+
targets = get_application_targets(user_project)
|
|
10
|
+
file_path = get_privacyinfo_file_path(user_project, targets)
|
|
11
|
+
|
|
12
|
+
privacy_info = read_privacyinfo_file(file_path) || {
|
|
13
|
+
"NSPrivacyCollectedDataTypes" => [],
|
|
14
|
+
"NSPrivacyTracking" => false
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
# Get all required reason APIs defined in current pods
|
|
18
|
+
required_reason_apis = get_used_required_reason_apis(installer)
|
|
19
|
+
|
|
20
|
+
# Add the Required Reason APIs from React Native core
|
|
21
|
+
get_core_accessed_apis.each do |accessed_api|
|
|
22
|
+
api_type = accessed_api["NSPrivacyAccessedAPIType"]
|
|
23
|
+
reasons = accessed_api["NSPrivacyAccessedAPITypeReasons"]
|
|
24
|
+
required_reason_apis[api_type] ||= []
|
|
25
|
+
required_reason_apis[api_type] += reasons
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Merge the Required Reason APIs from pods with the ones from the existing PrivacyInfo file
|
|
29
|
+
(privacy_info["NSPrivacyAccessedAPITypes"] || []).each do |accessed_api|
|
|
30
|
+
api_type = accessed_api["NSPrivacyAccessedAPIType"]
|
|
31
|
+
reasons = accessed_api["NSPrivacyAccessedAPITypeReasons"]
|
|
32
|
+
# Add reasons from existing PrivacyInfo file to the ones from pods
|
|
33
|
+
required_reason_apis[api_type] ||= []
|
|
34
|
+
required_reason_apis[api_type] += reasons
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Update the existing PrivacyInfo file with the new aggregated data
|
|
38
|
+
privacy_info["NSPrivacyAccessedAPITypes"] = required_reason_apis.map { |api_type, reasons|
|
|
39
|
+
{
|
|
40
|
+
"NSPrivacyAccessedAPIType" => api_type,
|
|
41
|
+
"NSPrivacyAccessedAPITypeReasons" => reasons.uniq
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
Xcodeproj::Plist.write_to_path(privacy_info, file_path)
|
|
46
|
+
|
|
47
|
+
targets.each do |target|
|
|
48
|
+
ensure_reference(file_path, user_project, target)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def self.get_application_targets(user_project)
|
|
53
|
+
return user_project.targets.filter { |t| t.symbol_type == :application }
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def self.read_privacyinfo_file(file_path)
|
|
57
|
+
# Maybe add missing default NSPrivacyTracking, NSPrivacyTrackingDomains, NSPrivacyCollectedDataTypes, but this works without those keys
|
|
58
|
+
source_data = nil
|
|
59
|
+
# Try to read an existing PrivacyInfo.xcprivacy file
|
|
60
|
+
begin
|
|
61
|
+
source_data = Xcodeproj::Plist.read_from_path(file_path)
|
|
62
|
+
Pod::UI.puts "[Privacy Manifest Aggregation] Appending aggregated reasons to existing PrivacyInfo.xcprivacy file."
|
|
63
|
+
rescue => e
|
|
64
|
+
Pod::UI.puts "[Privacy Manifest Aggregation] No existing PrivacyInfo.xcprivacy file found, creating a new one."
|
|
65
|
+
end
|
|
66
|
+
return source_data
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def self.ensure_reference(file_path, user_project, target)
|
|
70
|
+
reference_exists = target.resources_build_phase.files_references.any? { |file_ref| file_ref.path&.end_with? "PrivacyInfo.xcprivacy" }
|
|
71
|
+
unless reference_exists
|
|
72
|
+
# We try to find the main group, but if it doesn't exist, we default to adding the file to the project root – both work
|
|
73
|
+
file_root = user_project.root_object.main_group.children.find { |group|
|
|
74
|
+
group.class == Xcodeproj::Project::Object::PBXGroup && (group.name == target.name || group.path == target.name)
|
|
75
|
+
} || user_project
|
|
76
|
+
file_ref = file_root.new_file(file_path)
|
|
77
|
+
build_file = target.resources_build_phase.add_file_reference(file_ref, true)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def self.get_privacyinfo_file_path(user_project, targets)
|
|
82
|
+
file_refs = targets.flat_map { |target| target.resources_build_phase.files_references }
|
|
83
|
+
existing_file = file_refs.find { |file_ref| file_ref.path&.end_with? "PrivacyInfo.xcprivacy" }
|
|
84
|
+
if existing_file
|
|
85
|
+
return existing_file.real_path
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# We try to find a file we know exists in the project to get the path to the main group directory
|
|
89
|
+
info_plist_path = user_project.files.find { |file_ref| file_ref.name == "Info.plist" }
|
|
90
|
+
if info_plist_path.nil?
|
|
91
|
+
# return path that is sibling to .xcodeproj
|
|
92
|
+
path = user_project.path
|
|
93
|
+
return File.join(File.dirname(path), "PrivacyInfo.xcprivacy")
|
|
94
|
+
end
|
|
95
|
+
return File.join(File.dirname(info_plist_path.real_path),"PrivacyInfo.xcprivacy")
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def self.get_used_required_reason_apis(installer)
|
|
99
|
+
# A dictionary with keys of type string (NSPrivacyAccessedAPIType) and values of type string[] (NSPrivacyAccessedAPITypeReasons[])
|
|
100
|
+
used_apis = {}
|
|
101
|
+
Pod::UI.puts "[Privacy Manifest Aggregation] Reading .xcprivacy files to aggregate all used Required Reason APIs."
|
|
102
|
+
installer.pod_targets.each do |pod_target|
|
|
103
|
+
# puts pod_target
|
|
104
|
+
pod_target.file_accessors.each do |file_accessor|
|
|
105
|
+
file_accessor.resource_bundles.each do |bundle_name, bundle_files|
|
|
106
|
+
bundle_files.each do |file_path|
|
|
107
|
+
# This needs to be named like that due to apple requirements
|
|
108
|
+
if File.basename(file_path) == 'PrivacyInfo.xcprivacy'
|
|
109
|
+
content = Xcodeproj::Plist.read_from_path(file_path)
|
|
110
|
+
accessed_api_types = content["NSPrivacyAccessedAPITypes"]
|
|
111
|
+
accessed_api_types&.each do |accessed_api|
|
|
112
|
+
api_type = accessed_api["NSPrivacyAccessedAPIType"]
|
|
113
|
+
reasons = accessed_api["NSPrivacyAccessedAPITypeReasons"]
|
|
114
|
+
next unless api_type
|
|
115
|
+
used_apis[api_type] ||= []
|
|
116
|
+
used_apis[api_type] += reasons
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
return used_apis
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def self.get_privacy_manifest_paths_from(user_project)
|
|
127
|
+
privacy_manifests = user_project
|
|
128
|
+
.files
|
|
129
|
+
.select { |p|
|
|
130
|
+
p.path&.end_with?('PrivacyInfo.xcprivacy')
|
|
131
|
+
}
|
|
132
|
+
return privacy_manifests
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def self.get_core_accessed_apis()
|
|
136
|
+
file_timestamp_accessed_api = {
|
|
137
|
+
"NSPrivacyAccessedAPIType" => "NSPrivacyAccessedAPICategoryFileTimestamp",
|
|
138
|
+
"NSPrivacyAccessedAPITypeReasons" => ["C617.1"],
|
|
139
|
+
}
|
|
140
|
+
user_defaults_accessed_api = {
|
|
141
|
+
"NSPrivacyAccessedAPIType" => "NSPrivacyAccessedAPICategoryUserDefaults",
|
|
142
|
+
"NSPrivacyAccessedAPITypeReasons" => ["CA92.1"],
|
|
143
|
+
}
|
|
144
|
+
boot_time_accessed_api = {
|
|
145
|
+
"NSPrivacyAccessedAPIType" => "NSPrivacyAccessedAPICategorySystemBootTime",
|
|
146
|
+
"NSPrivacyAccessedAPITypeReasons" => ["35F9.1"],
|
|
147
|
+
}
|
|
148
|
+
return [file_timestamp_accessed_api, user_defaults_accessed_api, boot_time_accessed_api]
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def self.get_user_project_from(installer)
|
|
153
|
+
user_project = installer.aggregate_targets
|
|
154
|
+
.map{ |t| t.user_project }
|
|
155
|
+
.first
|
|
156
|
+
return user_project
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def self.add_privacy_manifest_if_needed(installer)
|
|
160
|
+
user_project = get_user_project_from(installer)
|
|
161
|
+
privacy_manifest = self.get_privacy_manifest_paths_from(user_project).first
|
|
162
|
+
if privacy_manifest.nil?
|
|
163
|
+
privacy_manifest = {
|
|
164
|
+
"NSPrivacyCollectedDataTypes" => [],
|
|
165
|
+
"NSPrivacyTracking" => false,
|
|
166
|
+
"NSPrivacyAccessedAPITypes" => get_core_accessed_apis
|
|
167
|
+
}
|
|
168
|
+
path = File.join(user_project.path.parent, "PrivacyInfo.xcprivacy")
|
|
169
|
+
Xcodeproj::Plist.write_to_path(privacy_manifest, path)
|
|
170
|
+
Pod::UI.puts "Your app does not have a privacy manifest! A template has been generated containing Required Reasons API usage in the core React Native library. Please add the PrivacyInfo.xcprivacy file to your project and complete data use, tracking and any additional required reasons your app is using according to Apple's guidance: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files. Then, you will need to manually add this file to your project in Xcode.".red
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
@@ -44,6 +44,7 @@ class ReactNativePodsUtils
|
|
|
44
44
|
def self.set_gcc_preprocessor_definition_for_React_hermes(installer)
|
|
45
45
|
self.add_build_settings_to_pod(installer, "GCC_PREPROCESSOR_DEFINITIONS", "HERMES_ENABLE_DEBUGGER=1", "React-hermes", "Debug")
|
|
46
46
|
self.add_build_settings_to_pod(installer, "GCC_PREPROCESSOR_DEFINITIONS", "HERMES_ENABLE_DEBUGGER=1", "hermes-engine", "Debug")
|
|
47
|
+
self.add_build_settings_to_pod(installer, "GCC_PREPROCESSOR_DEFINITIONS", "HERMES_ENABLE_DEBUGGER=1", "React-RuntimeHermes", "Debug")
|
|
47
48
|
end
|
|
48
49
|
|
|
49
50
|
def self.turn_off_resource_bundle_react_core(installer)
|
|
@@ -591,44 +592,6 @@ class ReactNativePodsUtils
|
|
|
591
592
|
ReactNativePodsUtils.update_header_paths_if_depends_on(target_installation_result, "React-ImageManager", header_search_paths)
|
|
592
593
|
end
|
|
593
594
|
|
|
594
|
-
def self.get_privacy_manifest_paths_from(user_project)
|
|
595
|
-
privacy_manifests = user_project
|
|
596
|
-
.files
|
|
597
|
-
.select { |p|
|
|
598
|
-
p.path&.end_with?('PrivacyInfo.xcprivacy')
|
|
599
|
-
}
|
|
600
|
-
return privacy_manifests
|
|
601
|
-
end
|
|
602
|
-
|
|
603
|
-
def self.add_privacy_manifest_if_needed(installer)
|
|
604
|
-
user_project = installer.aggregate_targets
|
|
605
|
-
.map{ |t| t.user_project }
|
|
606
|
-
.first
|
|
607
|
-
privacy_manifest = self.get_privacy_manifest_paths_from(user_project).first
|
|
608
|
-
if privacy_manifest.nil?
|
|
609
|
-
file_timestamp_reason = {
|
|
610
|
-
"NSPrivacyAccessedAPIType" => "NSPrivacyAccessedAPICategoryFileTimestamp",
|
|
611
|
-
"NSPrivacyAccessedAPITypeReasons" => ["C617.1"],
|
|
612
|
-
}
|
|
613
|
-
user_defaults_reason = {
|
|
614
|
-
"NSPrivacyAccessedAPIType" => "NSPrivacyAccessedAPICategoryUserDefaults",
|
|
615
|
-
"NSPrivacyAccessedAPITypeReasons" => ["CA92.1"],
|
|
616
|
-
}
|
|
617
|
-
boot_time_reason = {
|
|
618
|
-
"NSPrivacyAccessedAPIType" => "NSPrivacyAccessedAPICategorySystemBootTime",
|
|
619
|
-
"NSPrivacyAccessedAPITypeReasons" => ["35F9.1"],
|
|
620
|
-
}
|
|
621
|
-
privacy_manifest = {
|
|
622
|
-
"NSPrivacyCollectedDataTypes" => [],
|
|
623
|
-
"NSPrivacyTracking" => false,
|
|
624
|
-
"NSPrivacyAccessedAPITypes" => [file_timestamp_reason, user_defaults_reason, boot_time_reason]
|
|
625
|
-
}
|
|
626
|
-
path = File.join(user_project.path.parent, "PrivacyInfo.xcprivacy")
|
|
627
|
-
Xcodeproj::Plist.write_to_path(privacy_manifest, path)
|
|
628
|
-
Pod::UI.puts "Your app does not have a privacy manifest! A template has been generated containing Required Reasons API usage in the core React Native library. Please add the PrivacyInfo.xcprivacy file to your project and complete data use, tracking and any additional required reasons your app is using according to Apple's guidance: https://developer.apple.com/.../privacy_manifest_files. Then, you will need to manually add this file to your project in Xcode.".red
|
|
629
|
-
end
|
|
630
|
-
end
|
|
631
|
-
|
|
632
595
|
def self.react_native_pods
|
|
633
596
|
return [
|
|
634
597
|
"DoubleConversion",
|
|
@@ -42,8 +42,15 @@ EOF
|
|
|
42
42
|
patch -p1 config.sub fix_glog_0.3.5_apple_silicon.patch
|
|
43
43
|
fi
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
XCRUN="$(which xcrun)"
|
|
46
|
+
if [ -n "$XCRUN" ]; then
|
|
47
|
+
export CC="$(xcrun -find -sdk $PLATFORM_NAME cc) -arch $CURRENT_ARCH -isysroot $(xcrun -sdk $PLATFORM_NAME --show-sdk-path)"
|
|
48
|
+
export CXX="$CC"
|
|
49
|
+
else
|
|
50
|
+
export CC="$CC:-$(which gcc)"
|
|
51
|
+
export CXX="$CXX:-$(which g++ || true)"
|
|
52
|
+
fi
|
|
53
|
+
export CXX="$CXX:-$CC"
|
|
47
54
|
|
|
48
55
|
# Remove automake symlink if it exists
|
|
49
56
|
if [ -h "test-driver" ]; then
|
|
@@ -16,6 +16,7 @@ require_relative './cocoapods/new_architecture.rb'
|
|
|
16
16
|
require_relative './cocoapods/local_podspec_patch.rb'
|
|
17
17
|
require_relative './cocoapods/runtime.rb'
|
|
18
18
|
require_relative './cocoapods/helpers.rb'
|
|
19
|
+
require_relative './cocoapods/privacy_manifest_utils.rb'
|
|
19
20
|
|
|
20
21
|
$CODEGEN_OUTPUT_DIR = 'build/generated/ios'
|
|
21
22
|
$CODEGEN_COMPONENT_DIR = 'react/renderer/components'
|
|
@@ -73,7 +74,8 @@ def use_react_native! (
|
|
|
73
74
|
production: false, # deprecated
|
|
74
75
|
hermes_enabled: ENV['USE_HERMES'] && ENV['USE_HERMES'] == '0' ? false : true,
|
|
75
76
|
app_path: '..',
|
|
76
|
-
config_file_dir: ''
|
|
77
|
+
config_file_dir: '',
|
|
78
|
+
privacy_file_aggregation_enabled: true
|
|
77
79
|
)
|
|
78
80
|
|
|
79
81
|
# Set the app_path as env variable so the podspecs can access it.
|
|
@@ -97,6 +99,7 @@ def use_react_native! (
|
|
|
97
99
|
|
|
98
100
|
ENV['RCT_FABRIC_ENABLED'] = fabric_enabled ? "1" : "0"
|
|
99
101
|
ENV['USE_HERMES'] = hermes_enabled ? "1" : "0"
|
|
102
|
+
ENV['RCT_AGGREGATE_PRIVACY_FILES'] = privacy_file_aggregation_enabled ? "1" : "0"
|
|
100
103
|
|
|
101
104
|
prefix = path
|
|
102
105
|
|
|
@@ -278,6 +281,7 @@ def react_native_post_install(
|
|
|
278
281
|
|
|
279
282
|
fabric_enabled = ENV['RCT_FABRIC_ENABLED'] == '1'
|
|
280
283
|
hermes_enabled = ENV['USE_HERMES'] == '1'
|
|
284
|
+
privacy_file_aggregation_enabled = ENV['RCT_AGGREGATE_PRIVACY_FILES'] == '1'
|
|
281
285
|
|
|
282
286
|
if hermes_enabled
|
|
283
287
|
ReactNativePodsUtils.set_gcc_preprocessor_definition_for_React_hermes(installer)
|
|
@@ -288,11 +292,18 @@ def react_native_post_install(
|
|
|
288
292
|
ReactNativePodsUtils.set_use_hermes_build_setting(installer, hermes_enabled)
|
|
289
293
|
ReactNativePodsUtils.set_node_modules_user_settings(installer, react_native_path)
|
|
290
294
|
ReactNativePodsUtils.set_ccache_compiler_and_linker_build_settings(installer, react_native_path, ccache_enabled)
|
|
291
|
-
|
|
295
|
+
if Environment.new().ruby_platform().include?('darwin')
|
|
296
|
+
ReactNativePodsUtils.apply_xcode_15_patch(installer)
|
|
297
|
+
end
|
|
292
298
|
ReactNativePodsUtils.updateOSDeploymentTarget(installer)
|
|
293
299
|
ReactNativePodsUtils.set_dynamic_frameworks_flags(installer)
|
|
294
300
|
ReactNativePodsUtils.add_ndebug_flag_to_pods_in_release(installer)
|
|
295
|
-
|
|
301
|
+
|
|
302
|
+
if privacy_file_aggregation_enabled
|
|
303
|
+
PrivacyManifestUtils.add_aggregated_privacy_manifest(installer)
|
|
304
|
+
else
|
|
305
|
+
PrivacyManifestUtils.add_privacy_manifest_if_needed(installer)
|
|
306
|
+
end
|
|
296
307
|
|
|
297
308
|
NewArchitectureHelper.set_clang_cxx_language_standard_if_needed(installer)
|
|
298
309
|
NewArchitectureHelper.modify_flags_for_new_architecture(installer, NewArchitectureHelper.new_arch_enabled)
|
package/sdks/.hermesversion
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
hermes-2024-
|
|
1
|
+
hermes-2024-06-03-RNv0.74.2-bb1e74fe1e95c2b5a2f4f9311152da052badc2bc
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/template/package.json
CHANGED
|
@@ -11,16 +11,16 @@
|
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"react": "18.2.0",
|
|
14
|
-
"react-native": "0.74.
|
|
14
|
+
"react-native": "0.74.2"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
17
|
"@babel/core": "^7.20.0",
|
|
18
18
|
"@babel/preset-env": "^7.20.0",
|
|
19
19
|
"@babel/runtime": "^7.20.0",
|
|
20
|
-
"@react-native/babel-preset": "0.74.
|
|
21
|
-
"@react-native/eslint-config": "0.74.
|
|
22
|
-
"@react-native/metro-config": "0.74.
|
|
23
|
-
"@react-native/typescript-config": "0.74.
|
|
20
|
+
"@react-native/babel-preset": "0.74.84",
|
|
21
|
+
"@react-native/eslint-config": "0.74.84",
|
|
22
|
+
"@react-native/metro-config": "0.74.84",
|
|
23
|
+
"@react-native/typescript-config": "0.74.84",
|
|
24
24
|
"@types/react": "^18.2.6",
|
|
25
25
|
"@types/react-test-renderer": "^18.0.0",
|
|
26
26
|
"babel-jest": "^29.6.3",
|
|
@@ -81,6 +81,7 @@ Pod::Spec.new do |spec|
|
|
|
81
81
|
'folly/system/*.h',
|
|
82
82
|
spec.libraries = "c++abi" # NOTE Apple-only: Keep c++abi here due to https://github.com/react-native-community/releases/issues/251
|
|
83
83
|
spec.pod_target_xcconfig = { "USE_HEADERMAP" => "NO",
|
|
84
|
+
"DEFINES_MODULE" => "YES",
|
|
84
85
|
"CLANG_CXX_LANGUAGE_STANDARD" => "c++20",
|
|
85
86
|
"HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)\" \"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/fmt/include\"",
|
|
86
87
|
# In dynamic framework (use_frameworks!) mode, ignore the unused and undefined boost symbols when generating the library.
|