react-native-tvos 0.74.0-0rc3 → 0.74.2-0
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/AppDelegate/RCTAppDelegate+Protected.h +16 -0
- package/Libraries/AppDelegate/RCTAppDelegate.mm +32 -1
- package/Libraries/AppDelegate/React-RCTAppDelegate.podspec +1 -0
- package/Libraries/Components/Pressable/Pressable.js +9 -5
- 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/Libraries/ReactNative/RendererImplementation.js +2 -0
- package/README.md +29 -9
- package/React/Base/RCTUtils.m +28 -8
- package/React/Base/RCTVersion.m +2 -2
- package/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.mm +2 -4
- package/React/Fabric/Mounting/ComponentViews/Root/RCTRootComponentView.mm +22 -2
- package/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +5 -1
- package/React/Fabric/RCTScheduler.h +2 -0
- package/React/Fabric/RCTScheduler.mm +6 -0
- package/React/Fabric/RCTSurfacePresenter.mm +5 -0
- package/React/Modules/RCTUIManager.m +8 -9
- package/React/Views/RCTComponentData.m +14 -1
- package/React/Views/ScrollView/RCTScrollView.m +30 -14
- 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/defaults/DefaultNewArchitectureEntryPoint.kt +15 -0
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +19 -7
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +31 -11
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +7 -3
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +7 -3
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +34 -12
- package/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +7 -3
- 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/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java +1 -3
- package/ReactAndroid/src/main/jni/react/fabric/Binding.cpp +38 -3
- package/ReactAndroid/src/main/jni/react/fabric/Binding.h +8 -0
- package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +43 -15
- package/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +10 -4
- 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/featureflags/ReactNativeFeatureFlags.cpp +13 -5
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +16 -6
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +62 -26
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +8 -4
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +13 -5
- package/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +4 -2
- package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +16 -6
- package/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +7 -3
- package/ReactCommon/react/renderer/components/textinput/platform/ios/react/renderer/components/iostextinput/TextInputEventEmitter.cpp +53 -1
- package/ReactCommon/react/renderer/mounting/MountingTransaction.cpp +13 -0
- package/ReactCommon/react/renderer/mounting/MountingTransaction.h +9 -0
- package/ReactCommon/react/renderer/scheduler/Scheduler.cpp +7 -2
- package/ReactCommon/react/renderer/scheduler/SchedulerDelegate.h +11 -0
- package/cli.js +11 -3
- package/package.json +12 -12
- 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/src/private/featureflags/NativeReactNativeFeatureFlags.js +4 -2
- package/src/private/featureflags/ReactNativeFeatureFlags.js +16 -6
- package/template/package.json +5 -5
- package/third-party-podspecs/RCT-Folly.podspec +1 -0
- package/types/public/ReactNativeTVTypes.d.ts +6 -10
- package/Libraries/React-Native +0 -214
- package/ReactAndroid/src/main/java/com/facebook/react/ReactAndroidHWInputDeviceHelper.java +0 -98
|
@@ -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(
|
|
@@ -41,4 +41,17 @@ Number MountingTransaction::getNumber() const {
|
|
|
41
41
|
return number_;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
void MountingTransaction::mergeWith(MountingTransaction&& transaction) {
|
|
45
|
+
react_native_assert(transaction.getSurfaceId() == surfaceId_);
|
|
46
|
+
number_ = transaction.getNumber();
|
|
47
|
+
mutations_.insert(
|
|
48
|
+
mutations_.end(),
|
|
49
|
+
std::make_move_iterator(transaction.mutations_.begin()),
|
|
50
|
+
std::make_move_iterator(transaction.mutations_.end()));
|
|
51
|
+
|
|
52
|
+
// TODO T186641819: Telemetry for merged transactions is not supported, use
|
|
53
|
+
// the latest instance
|
|
54
|
+
telemetry_ = std::move(transaction.telemetry_);
|
|
55
|
+
}
|
|
56
|
+
|
|
44
57
|
} // namespace facebook::react
|
|
@@ -76,6 +76,15 @@ class MountingTransaction final {
|
|
|
76
76
|
*/
|
|
77
77
|
Number getNumber() const;
|
|
78
78
|
|
|
79
|
+
/*
|
|
80
|
+
* Merges the given transaction in the current transaction, so they
|
|
81
|
+
* can be executed atomatically as a single transaction.
|
|
82
|
+
*
|
|
83
|
+
* This is required for Android UI, which needs to separately apply
|
|
84
|
+
* each ShadowTree mutation due to differences in props representation.
|
|
85
|
+
*/
|
|
86
|
+
void mergeWith(MountingTransaction&& transaction);
|
|
87
|
+
|
|
79
88
|
private:
|
|
80
89
|
SurfaceId surfaceId_;
|
|
81
90
|
Number number_;
|
|
@@ -273,6 +273,10 @@ void Scheduler::uiManagerDidFinishTransaction(
|
|
|
273
273
|
SystraceSection s("Scheduler::uiManagerDidFinishTransaction");
|
|
274
274
|
|
|
275
275
|
if (delegate_ != nullptr) {
|
|
276
|
+
// This is no-op on all platforms except for Android where we need to
|
|
277
|
+
// observe each transaction to be able to mount correctly.
|
|
278
|
+
delegate_->schedulerDidFinishTransaction(mountingCoordinator);
|
|
279
|
+
|
|
276
280
|
auto weakRuntimeScheduler =
|
|
277
281
|
contextContainer_->find<std::weak_ptr<RuntimeScheduler>>(
|
|
278
282
|
"RuntimeScheduler");
|
|
@@ -283,13 +287,14 @@ void Scheduler::uiManagerDidFinishTransaction(
|
|
|
283
287
|
runtimeScheduler->scheduleRenderingUpdate(
|
|
284
288
|
[delegate = delegate_,
|
|
285
289
|
mountingCoordinator = std::move(mountingCoordinator)]() {
|
|
286
|
-
delegate->
|
|
290
|
+
delegate->schedulerShouldRenderTransactions(mountingCoordinator);
|
|
287
291
|
});
|
|
288
292
|
} else {
|
|
289
|
-
delegate_->
|
|
293
|
+
delegate_->schedulerShouldRenderTransactions(mountingCoordinator);
|
|
290
294
|
}
|
|
291
295
|
}
|
|
292
296
|
}
|
|
297
|
+
|
|
293
298
|
void Scheduler::uiManagerDidCreateShadowNode(const ShadowNode& shadowNode) {
|
|
294
299
|
SystraceSection s("Scheduler::uiManagerDidCreateShadowNode");
|
|
295
300
|
|
|
@@ -28,6 +28,17 @@ class SchedulerDelegate {
|
|
|
28
28
|
virtual void schedulerDidFinishTransaction(
|
|
29
29
|
const MountingCoordinator::Shared& mountingCoordinator) = 0;
|
|
30
30
|
|
|
31
|
+
/*
|
|
32
|
+
* Called when the runtime scheduler decides that one-or-more previously
|
|
33
|
+
* finished transactions should now be flushed to the screen (atomically).
|
|
34
|
+
*
|
|
35
|
+
* This is a separate callback from didFinishTransaction as the Android UI
|
|
36
|
+
* mounting layer needs to be able toobserve each created ShadowTree to
|
|
37
|
+
* correctly apply changes, due to changes in Props representation.
|
|
38
|
+
*/
|
|
39
|
+
virtual void schedulerShouldRenderTransactions(
|
|
40
|
+
const MountingCoordinator::Shared& mountingCoordinator) = 0;
|
|
41
|
+
|
|
31
42
|
/*
|
|
32
43
|
* Called right after a new ShadowNode was created.
|
|
33
44
|
*/
|
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-tvos",
|
|
3
|
-
"version": "0.74.0
|
|
3
|
+
"version": "0.74.2-0",
|
|
4
4
|
"description": "A framework for building native apps using React",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -108,16 +108,16 @@
|
|
|
108
108
|
},
|
|
109
109
|
"dependencies": {
|
|
110
110
|
"@jest/create-cache-key-function": "^29.6.3",
|
|
111
|
-
"@react-native-community/cli": "13.6.
|
|
112
|
-
"@react-native-community/cli-platform-android": "13.6.
|
|
113
|
-
"@react-native-community/cli-platform-ios": "13.6.
|
|
114
|
-
"@react-native/assets-registry": "0.74.
|
|
115
|
-
"@react-native/codegen": "0.74.
|
|
116
|
-
"@react-native/community-cli-plugin": "0.74.
|
|
117
|
-
"@react-native/gradle-plugin": "0.74.
|
|
118
|
-
"@react-native/js-polyfills": "0.74.
|
|
119
|
-
"@react-native/normalize-colors": "0.74.
|
|
120
|
-
"@react-native-tvos/virtualized-lists": "0.74.0
|
|
111
|
+
"@react-native-community/cli": "13.6.8",
|
|
112
|
+
"@react-native-community/cli-platform-android": "13.6.8",
|
|
113
|
+
"@react-native-community/cli-platform-ios": "13.6.8",
|
|
114
|
+
"@react-native/assets-registry": "0.74.84",
|
|
115
|
+
"@react-native/codegen": "0.74.84",
|
|
116
|
+
"@react-native/community-cli-plugin": "0.74.84",
|
|
117
|
+
"@react-native/gradle-plugin": "0.74.84",
|
|
118
|
+
"@react-native/js-polyfills": "0.74.84",
|
|
119
|
+
"@react-native/normalize-colors": "0.74.84",
|
|
120
|
+
"@react-native-tvos/virtualized-lists": "0.74.2-0",
|
|
121
121
|
"abort-controller": "^3.0.0",
|
|
122
122
|
"anser": "^1.4.9",
|
|
123
123
|
"ansi-regex": "^5.0.0",
|
|
@@ -164,6 +164,6 @@
|
|
|
164
164
|
]
|
|
165
165
|
},
|
|
166
166
|
"devDependencies": {
|
|
167
|
-
"react-native-core": "npm:react-native@0.74.
|
|
167
|
+
"react-native-core": "npm:react-native@0.74.2"
|
|
168
168
|
}
|
|
169
169
|
}
|
|
@@ -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)
|
|
@@ -595,44 +596,6 @@ class ReactNativePodsUtils
|
|
|
595
596
|
ReactNativePodsUtils.update_header_paths_if_depends_on(target_installation_result, "React-ImageManager", header_search_paths)
|
|
596
597
|
end
|
|
597
598
|
|
|
598
|
-
def self.get_privacy_manifest_paths_from(user_project)
|
|
599
|
-
privacy_manifests = user_project
|
|
600
|
-
.files
|
|
601
|
-
.select { |p|
|
|
602
|
-
p.path&.end_with?('PrivacyInfo.xcprivacy')
|
|
603
|
-
}
|
|
604
|
-
return privacy_manifests
|
|
605
|
-
end
|
|
606
|
-
|
|
607
|
-
def self.add_privacy_manifest_if_needed(installer)
|
|
608
|
-
user_project = installer.aggregate_targets
|
|
609
|
-
.map{ |t| t.user_project }
|
|
610
|
-
.first
|
|
611
|
-
privacy_manifest = self.get_privacy_manifest_paths_from(user_project).first
|
|
612
|
-
if privacy_manifest.nil?
|
|
613
|
-
file_timestamp_reason = {
|
|
614
|
-
"NSPrivacyAccessedAPIType" => "NSPrivacyAccessedAPICategoryFileTimestamp",
|
|
615
|
-
"NSPrivacyAccessedAPITypeReasons" => ["C617.1"],
|
|
616
|
-
}
|
|
617
|
-
user_defaults_reason = {
|
|
618
|
-
"NSPrivacyAccessedAPIType" => "NSPrivacyAccessedAPICategoryUserDefaults",
|
|
619
|
-
"NSPrivacyAccessedAPITypeReasons" => ["CA92.1"],
|
|
620
|
-
}
|
|
621
|
-
boot_time_reason = {
|
|
622
|
-
"NSPrivacyAccessedAPIType" => "NSPrivacyAccessedAPICategorySystemBootTime",
|
|
623
|
-
"NSPrivacyAccessedAPITypeReasons" => ["35F9.1"],
|
|
624
|
-
}
|
|
625
|
-
privacy_manifest = {
|
|
626
|
-
"NSPrivacyCollectedDataTypes" => [],
|
|
627
|
-
"NSPrivacyTracking" => false,
|
|
628
|
-
"NSPrivacyAccessedAPITypes" => [file_timestamp_reason, user_defaults_reason, boot_time_reason]
|
|
629
|
-
}
|
|
630
|
-
path = File.join(user_project.path.parent, "PrivacyInfo.xcprivacy")
|
|
631
|
-
Xcodeproj::Plist.write_to_path(privacy_manifest, path)
|
|
632
|
-
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
|
|
633
|
-
end
|
|
634
|
-
end
|
|
635
|
-
|
|
636
599
|
def self.react_native_pods
|
|
637
600
|
return [
|
|
638
601
|
"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
|
|
@@ -17,6 +17,7 @@ require_relative './cocoapods/new_architecture.rb'
|
|
|
17
17
|
require_relative './cocoapods/local_podspec_patch.rb'
|
|
18
18
|
require_relative './cocoapods/runtime.rb'
|
|
19
19
|
require_relative './cocoapods/helpers.rb'
|
|
20
|
+
require_relative './cocoapods/privacy_manifest_utils.rb'
|
|
20
21
|
|
|
21
22
|
$CODEGEN_OUTPUT_DIR = 'build/generated/ios'
|
|
22
23
|
$CODEGEN_COMPONENT_DIR = 'react/renderer/components'
|
|
@@ -74,7 +75,8 @@ def use_react_native! (
|
|
|
74
75
|
production: false, # deprecated
|
|
75
76
|
hermes_enabled: ENV['USE_HERMES'] && ENV['USE_HERMES'] == '0' ? false : true,
|
|
76
77
|
app_path: '..',
|
|
77
|
-
config_file_dir: ''
|
|
78
|
+
config_file_dir: '',
|
|
79
|
+
privacy_file_aggregation_enabled: true
|
|
78
80
|
)
|
|
79
81
|
|
|
80
82
|
# Set the app_path as env variable so the podspecs can access it.
|
|
@@ -98,6 +100,7 @@ def use_react_native! (
|
|
|
98
100
|
|
|
99
101
|
ENV['RCT_FABRIC_ENABLED'] = fabric_enabled ? "1" : "0"
|
|
100
102
|
ENV['USE_HERMES'] = hermes_enabled ? "1" : "0"
|
|
103
|
+
ENV['RCT_AGGREGATE_PRIVACY_FILES'] = privacy_file_aggregation_enabled ? "1" : "0"
|
|
101
104
|
|
|
102
105
|
prefix = path
|
|
103
106
|
|
|
@@ -283,6 +286,7 @@ def react_native_post_install(
|
|
|
283
286
|
|
|
284
287
|
fabric_enabled = ENV['RCT_FABRIC_ENABLED'] == '1'
|
|
285
288
|
hermes_enabled = ENV['USE_HERMES'] == '1'
|
|
289
|
+
privacy_file_aggregation_enabled = ENV['RCT_AGGREGATE_PRIVACY_FILES'] == '1'
|
|
286
290
|
|
|
287
291
|
if hermes_enabled
|
|
288
292
|
ReactNativePodsUtils.set_gcc_preprocessor_definition_for_React_hermes(installer)
|
|
@@ -293,11 +297,18 @@ def react_native_post_install(
|
|
|
293
297
|
ReactNativePodsUtils.set_use_hermes_build_setting(installer, hermes_enabled)
|
|
294
298
|
ReactNativePodsUtils.set_node_modules_user_settings(installer, react_native_path)
|
|
295
299
|
ReactNativePodsUtils.set_ccache_compiler_and_linker_build_settings(installer, react_native_path, ccache_enabled)
|
|
296
|
-
|
|
300
|
+
if Environment.new().ruby_platform().include?('darwin')
|
|
301
|
+
ReactNativePodsUtils.apply_xcode_15_patch(installer)
|
|
302
|
+
end
|
|
297
303
|
ReactNativePodsUtils.updateOSDeploymentTarget(installer)
|
|
298
304
|
ReactNativePodsUtils.set_dynamic_frameworks_flags(installer)
|
|
299
305
|
ReactNativePodsUtils.add_ndebug_flag_to_pods_in_release(installer)
|
|
300
|
-
|
|
306
|
+
|
|
307
|
+
if privacy_file_aggregation_enabled
|
|
308
|
+
PrivacyManifestUtils.add_aggregated_privacy_manifest(installer)
|
|
309
|
+
else
|
|
310
|
+
PrivacyManifestUtils.add_privacy_manifest_if_needed(installer)
|
|
311
|
+
end
|
|
301
312
|
|
|
302
313
|
NewArchitectureHelper.set_clang_cxx_language_standard_if_needed(installer)
|
|
303
314
|
NewArchitectureHelper.modify_flags_for_new_architecture(installer, NewArchitectureHelper.new_arch_enabled)
|
package/sdks/.hermesversion
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
hermes-2024-
|
|
1
|
+
hermes-2024-06-05-RNv0.74.2-f007ae633a05700f23f4ef8678958b30600eb0d6
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @generated SignedSource<<
|
|
7
|
+
* @generated SignedSource<<8f82962343a5146622f36c2de071ff6a>>
|
|
8
8
|
* @flow strict-local
|
|
9
9
|
*/
|
|
10
10
|
|
|
@@ -24,10 +24,12 @@ import * as TurboModuleRegistry from '../../../Libraries/TurboModule/TurboModule
|
|
|
24
24
|
|
|
25
25
|
export interface Spec extends TurboModule {
|
|
26
26
|
+commonTestFlag?: () => boolean;
|
|
27
|
+
+androidEnablePendingFabricTransactions?: () => boolean;
|
|
28
|
+
+batchRenderingUpdatesInEventLoop?: () => boolean;
|
|
29
|
+
+destroyFabricSurfacesInReactInstanceManager?: () => boolean;
|
|
27
30
|
+enableBackgroundExecutor?: () => boolean;
|
|
28
31
|
+useModernRuntimeScheduler?: () => boolean;
|
|
29
32
|
+enableMicrotasks?: () => boolean;
|
|
30
|
-
+batchRenderingUpdatesInEventLoop?: () => boolean;
|
|
31
33
|
+enableSpannableBuildingUnification?: () => boolean;
|
|
32
34
|
+enableCustomDrawOrderFabric?: () => boolean;
|
|
33
35
|
+enableFixForClippedSubviewsCrash?: () => boolean;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @generated SignedSource<<
|
|
7
|
+
* @generated SignedSource<<b7ebc6e4360a4b7733335f283300a4bb>>
|
|
8
8
|
* @flow strict-local
|
|
9
9
|
*/
|
|
10
10
|
|
|
@@ -41,10 +41,12 @@ export type ReactNativeFeatureFlagsJsOnlyOverrides = Partial<ReactNativeFeatureF
|
|
|
41
41
|
export type ReactNativeFeatureFlags = {
|
|
42
42
|
...ReactNativeFeatureFlagsJsOnly,
|
|
43
43
|
commonTestFlag: Getter<boolean>,
|
|
44
|
+
androidEnablePendingFabricTransactions: Getter<boolean>,
|
|
45
|
+
batchRenderingUpdatesInEventLoop: Getter<boolean>,
|
|
46
|
+
destroyFabricSurfacesInReactInstanceManager: Getter<boolean>,
|
|
44
47
|
enableBackgroundExecutor: Getter<boolean>,
|
|
45
48
|
useModernRuntimeScheduler: Getter<boolean>,
|
|
46
49
|
enableMicrotasks: Getter<boolean>,
|
|
47
|
-
batchRenderingUpdatesInEventLoop: Getter<boolean>,
|
|
48
50
|
enableSpannableBuildingUnification: Getter<boolean>,
|
|
49
51
|
enableCustomDrawOrderFabric: Getter<boolean>,
|
|
50
52
|
enableFixForClippedSubviewsCrash: Getter<boolean>,
|
|
@@ -96,6 +98,18 @@ export const shouldUseRemoveClippedSubviewsAsDefaultOnIOS: Getter<boolean> = cre
|
|
|
96
98
|
* Common flag for testing. Do NOT modify.
|
|
97
99
|
*/
|
|
98
100
|
export const commonTestFlag: Getter<boolean> = createNativeFlagGetter('commonTestFlag', false);
|
|
101
|
+
/**
|
|
102
|
+
* To be used with batchRenderingUpdatesInEventLoop. When enbled, the Android mounting layer will concatenate pending transactions to ensure they're applied atomatically
|
|
103
|
+
*/
|
|
104
|
+
export const androidEnablePendingFabricTransactions: Getter<boolean> = createNativeFlagGetter('androidEnablePendingFabricTransactions', false);
|
|
105
|
+
/**
|
|
106
|
+
* When enabled, the RuntimeScheduler processing the event loop will batch all rendering updates and dispatch them together at the end of each iteration of the loop.
|
|
107
|
+
*/
|
|
108
|
+
export const batchRenderingUpdatesInEventLoop: Getter<boolean> = createNativeFlagGetter('batchRenderingUpdatesInEventLoop', false);
|
|
109
|
+
/**
|
|
110
|
+
* When enabled, ReactInstanceManager will clean up Fabric surfaces on destroy().
|
|
111
|
+
*/
|
|
112
|
+
export const destroyFabricSurfacesInReactInstanceManager: Getter<boolean> = createNativeFlagGetter('destroyFabricSurfacesInReactInstanceManager', false);
|
|
99
113
|
/**
|
|
100
114
|
* Enables the use of a background executor to compute layout and commit updates on Fabric (this system is deprecated and should not be used).
|
|
101
115
|
*/
|
|
@@ -108,10 +122,6 @@ export const useModernRuntimeScheduler: Getter<boolean> = createNativeFlagGetter
|
|
|
108
122
|
* Enables the use of microtasks in Hermes (scheduling) and RuntimeScheduler (execution).
|
|
109
123
|
*/
|
|
110
124
|
export const enableMicrotasks: Getter<boolean> = createNativeFlagGetter('enableMicrotasks', false);
|
|
111
|
-
/**
|
|
112
|
-
* When enabled, the RuntimeScheduler processing the event loop will batch all rendering updates and dispatch them together at the end of each iteration of the loop.
|
|
113
|
-
*/
|
|
114
|
-
export const batchRenderingUpdatesInEventLoop: Getter<boolean> = createNativeFlagGetter('batchRenderingUpdatesInEventLoop', false);
|
|
115
125
|
/**
|
|
116
126
|
* Uses new, deduplicated logic for constructing Android Spannables from text fragments
|
|
117
127
|
*/
|
package/template/package.json
CHANGED
|
@@ -13,16 +13,16 @@
|
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"expo": "^50.0.11",
|
|
15
15
|
"react": "18.2.0",
|
|
16
|
-
"react-native": "npm:react-native-tvos@0.74.0
|
|
16
|
+
"react-native": "npm:react-native-tvos@0.74.2-0"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"@babel/core": "^7.20.0",
|
|
20
20
|
"@babel/preset-env": "^7.20.0",
|
|
21
21
|
"@babel/runtime": "^7.20.0",
|
|
22
|
-
"@react-native/babel-preset": "0.74.
|
|
23
|
-
"@react-native/eslint-config": "0.74.
|
|
24
|
-
"@react-native/metro-config": "0.74.
|
|
25
|
-
"@react-native/typescript-config": "0.74.
|
|
22
|
+
"@react-native/babel-preset": "0.74.84",
|
|
23
|
+
"@react-native/eslint-config": "0.74.84",
|
|
24
|
+
"@react-native/metro-config": "0.74.84",
|
|
25
|
+
"@react-native/typescript-config": "0.74.84",
|
|
26
26
|
"@types/react": "^18.2.6",
|
|
27
27
|
"@types/react-test-renderer": "^18.0.0",
|
|
28
28
|
"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.
|