fix app crashes when navigating back from the post screen
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
diff --git a/ios/ExpoPrivacySensitive.podspec b/ios/ExpoPrivacySensitive.podspec
|
||||
index fa9a44c2668571bb22da7d817960c89d84b37266..ff415bfac2885ed3029b3440c2eb3859f60c0e05 100644
|
||||
--- a/ios/ExpoPrivacySensitive.podspec
|
||||
+++ b/ios/ExpoPrivacySensitive.podspec
|
||||
@@ -2,6 +2,9 @@ require 'json'
|
||||
|
||||
package = JSON.parse(File.read(File.join(__dir__, '..', 'package.json')))
|
||||
|
||||
+new_arch_enabled = ENV['RCT_NEW_ARCH_ENABLED'] == '1'
|
||||
+new_arch_compiler_flags = '-DRCT_NEW_ARCH_ENABLED'
|
||||
+
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'ExpoPrivacySensitive'
|
||||
s.version = package['version']
|
||||
@@ -23,6 +26,7 @@ Pod::Spec.new do |s|
|
||||
# Swift/Objective-C compatibility
|
||||
s.pod_target_xcconfig = {
|
||||
'DEFINES_MODULE' => 'YES',
|
||||
+ 'OTHER_SWIFT_FLAGS' => "$(inherited) #{new_arch_enabled ? new_arch_compiler_flags : ''}",
|
||||
}
|
||||
|
||||
s.source_files = "**/*.{h,m,mm,swift,hpp,cpp}"
|
||||
diff --git a/ios/ExpoPrivacySensitiveView.swift b/ios/ExpoPrivacySensitiveView.swift
|
||||
index 499b9b4764894a7ccf7dac2ccee6b09bf14d78cc..424ca9109c32e4cc96faed0a8b8204685899355b 100644
|
||||
--- a/ios/ExpoPrivacySensitiveView.swift
|
||||
+++ b/ios/ExpoPrivacySensitiveView.swift
|
||||
@@ -26,6 +26,31 @@ class ExpoPrivacySensitiveView: ExpoView {
|
||||
isSettingUp = false
|
||||
}
|
||||
|
||||
+#if RCT_NEW_ARCH_ENABLED
|
||||
+ // On the new architecture (Fabric), `ExpoView` is an `RCTViewComponentView`
|
||||
+ // subclass and React children are mounted/unmounted via these methods rather
|
||||
+ // than `addSubview`/`insertSubview`. We reparent the children into the secure
|
||||
+ // container here so they stay hidden in screenshots. Crucially, unmount must
|
||||
+ // not fall through to `super`, whose assertion requires the child to be a
|
||||
+ // direct subview of `self`; ours live inside `secureContainer`, so unmounting
|
||||
+ // that way would crash with "Attempt to unmount a view which is mounted inside
|
||||
+ // different view".
|
||||
+ override func mountChildComponentView(_ childComponentView: UIView, index: Int) {
|
||||
+ if let container = secureContainer {
|
||||
+ container.insertSubview(childComponentView, at: index)
|
||||
+ } else {
|
||||
+ super.mountChildComponentView(childComponentView, index: index)
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ override func unmountChildComponentView(_ childComponentView: UIView, index: Int) {
|
||||
+ if secureContainer != nil {
|
||||
+ childComponentView.removeFromSuperview()
|
||||
+ } else {
|
||||
+ super.unmountChildComponentView(childComponentView, index: index)
|
||||
+ }
|
||||
+ }
|
||||
+#else
|
||||
override func addSubview(_ view: UIView) {
|
||||
if isSettingUp || view === secureContainer {
|
||||
super.addSubview(view)
|
||||
@@ -77,6 +102,7 @@ class ExpoPrivacySensitiveView: ExpoView {
|
||||
super.insertSubview(view, belowSubview: siblingSubview)
|
||||
}
|
||||
}
|
||||
+#endif
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
@@ -0,0 +1,46 @@
|
||||
# `expo-privacy-sensitive` patch
|
||||
|
||||
Makes the native iOS view compatible with the React Native new architecture (Fabric).
|
||||
|
||||
## Problem
|
||||
|
||||
`ExpoPrivacySensitiveView` hides its content from screenshots by reparenting its
|
||||
children into a secure `UITextField` container view. It did this by overriding
|
||||
`addSubview`/`insertSubview`.
|
||||
|
||||
On the new architecture, `ExpoView` is an `RCTViewComponentView` subclass, and
|
||||
Fabric mounts/unmounts React children by calling `mountChildComponentView` /
|
||||
`unmountChildComponentView` directly on the component view. The mount path went
|
||||
through the overridden `insertSubview` and reparented the child into the secure
|
||||
container, but `RCTViewComponentView.unmountChildComponentView` asserts that the
|
||||
child is a direct subview of `self`. That assertion failed, crashing the app:
|
||||
|
||||
```
|
||||
NSInternalInconsistencyException: Attempt to unmount a view which is mounted
|
||||
inside different view. (parent: ExpoPrivacySensitive.ExpoPrivacySensitiveView,
|
||||
child: RCTViewComponentView, index: 0)
|
||||
```
|
||||
|
||||
It reproduced reliably when navigating back from the post thread screen (the
|
||||
`GrowthHack` component is the only consumer).
|
||||
|
||||
## Fix
|
||||
|
||||
Two parts, mirroring how `expo-splash-screen` supports both architectures:
|
||||
|
||||
1. `ExpoPrivacySensitive.podspec` now adds `-DRCT_NEW_ARCH_ENABLED` to
|
||||
`OTHER_SWIFT_FLAGS` when `ENV['RCT_NEW_ARCH_ENABLED'] == '1'`. Without this,
|
||||
the flag is never defined for this pod's Swift, so the `#if` below would
|
||||
always be false.
|
||||
2. `ExpoPrivacySensitiveView.swift` gates its implementation on
|
||||
`#if RCT_NEW_ARCH_ENABLED`: on the new architecture it overrides
|
||||
`mountChildComponentView` / `unmountChildComponentView` (reparenting on mount,
|
||||
plain removal on unmount to avoid the superview assertion); the old
|
||||
`addSubview`/`insertSubview` overrides are kept for the old architecture.
|
||||
|
||||
## Important: requires `RCT_NEW_ARCH_ENABLED=1` at install
|
||||
|
||||
The podspec opt-in is gated on `ENV['RCT_NEW_ARCH_ENABLED'] == '1'` at
|
||||
`pod install` time (same as `expo-splash-screen` and `ExpoModulesCore`).
|
||||
|
||||
Should be upstreamed to https://github.com/mozzius/expo-privacy-sensitive.
|
||||
Generated
+3
-2
@@ -224,6 +224,7 @@ patchedDependencies:
|
||||
expo-media-library@18.2.1: 2b84c17999bb0c977eaef7fa8ac297f7074d91c94fb63726b42d2a277b26b39a
|
||||
expo-modules-core@3.0.30: 952fb1c8cb6dc8a0d8ef4e1114942a341d89b025e011f1acfff788929997346e
|
||||
expo-notifications@0.32.17: a45a8dcf3d8c4b5df4ee0e62bc79b755fcf9d28ca51a6f685b85830bf4afc2e5
|
||||
expo-privacy-sensitive@0.1.0: 8f369eafd4ca69611b422861462b11fe2258694161b54531a2a10cf4eaf4ce57
|
||||
expo-updates@29.0.17: 04f28cb005b770e9ae8f0065eab96e43cbb1e58107f5f6ad1bdd18f6deb66487
|
||||
react-native-compressor@1.13.0: 58379dfaace6ced8590cb341c77f2ca8099dfa8f7df6297032ec51de767a9925
|
||||
react-native-date-picker@5.0.13: 92943fb79d17d7342a29bbb12b0d8ee3cf6f7bca12ed322dc8d124a3e9fb75bd
|
||||
@@ -510,7 +511,7 @@ importers:
|
||||
version: 0.2.1(expo@54.0.34(@babel/core@7.29.0)(react-native-webview@13.15.0(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||
expo-privacy-sensitive:
|
||||
specifier: ^0.1.0
|
||||
version: 0.1.0(expo@54.0.34(@babel/core@7.29.0)(react-native-webview@13.15.0(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||
version: 0.1.0(patch_hash=8f369eafd4ca69611b422861462b11fe2258694161b54531a2a10cf4eaf4ce57)(expo@54.0.34(@babel/core@7.29.0)(react-native-webview@13.15.0(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||
expo-screen-orientation:
|
||||
specifier: ~9.0.8
|
||||
version: 9.0.9(expo@54.0.34(@babel/core@7.29.0)(react-native-webview@13.15.0(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))
|
||||
@@ -14391,7 +14392,7 @@ snapshots:
|
||||
react: 19.1.0
|
||||
react-native: 0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0)
|
||||
|
||||
expo-privacy-sensitive@0.1.0(expo@54.0.34(@babel/core@7.29.0)(react-native-webview@13.15.0(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0):
|
||||
expo-privacy-sensitive@0.1.0(patch_hash=8f369eafd4ca69611b422861462b11fe2258694161b54531a2a10cf4eaf4ce57)(expo@54.0.34(@babel/core@7.29.0)(react-native-webview@13.15.0(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0):
|
||||
dependencies:
|
||||
expo: 54.0.34(@babel/core@7.29.0)(react-native-webview@13.15.0(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(patch_hash=2656ac6deb71b92a4df4af4593d13ace6a5740936432e5e7e8ef32bc3cd05194)(@babel/core@7.29.0)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||
react: 19.1.0
|
||||
|
||||
@@ -27,6 +27,7 @@ patchedDependencies:
|
||||
'expo-media-library@18.2.1': patches/expo-media-library@18.2.1.patch
|
||||
'expo-modules-core@3.0.30': patches/expo-modules-core@3.0.30.patch
|
||||
'expo-notifications@0.32.17': patches/expo-notifications@0.32.17.patch
|
||||
'expo-privacy-sensitive@0.1.0': patches/expo-privacy-sensitive@0.1.0.patch
|
||||
'expo-updates@29.0.17': patches/expo-updates@29.0.17.patch
|
||||
'react-native-compressor@1.13.0': patches/react-native-compressor@1.13.0.patch
|
||||
'react-native-date-picker@5.0.13': patches/react-native-date-picker@5.0.13.patch
|
||||
|
||||
Reference in New Issue
Block a user