Skip to content

Commit 7aabb74

Browse files
Nareshkumawat-starTest User
andauthored
fix(mobile): request camera permission on iOS to avoid blank screen (#637)
Co-authored-by: Test User <test@example.com>
1 parent 7aa5a91 commit 7aabb74

1 file changed

Lines changed: 75 additions & 6 deletions

File tree

apps/mobile/src/screens/ScanScreen.tsx

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ import {
1010
Share,
1111
Platform,
1212
PermissionsAndroid,
13+
Linking,
14+
AppState,
15+
type AppStateStatus,
16+
NativeModules,
1317
} from 'react-native';
1418
import { SafeAreaView } from 'react-native-safe-area-context';
1519
import { useFocusEffect } from '@react-navigation/native';
@@ -65,6 +69,33 @@ export default function ScanScreen({ navigation }: Props) {
6569
}
6670
};
6771

72+
const checkInitialCameraPermission = useCallback(async () => {
73+
if (Platform.OS === 'android') {
74+
const hasPerm = await PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.CAMERA);
75+
setHasPermission(hasPerm);
76+
} else if (Platform.OS === 'ios') {
77+
try {
78+
const RNCameraKitModule = NativeModules.RNCameraKitModule;
79+
if (RNCameraKitModule) {
80+
const status = await RNCameraKitModule.checkDeviceCameraAuthorizationStatus();
81+
if (status === true) {
82+
setHasPermission(true);
83+
} else if (status === -1) {
84+
const granted = await RNCameraKitModule.requestDeviceCameraAuthorization();
85+
setHasPermission(granted === true);
86+
} else {
87+
setHasPermission(false);
88+
}
89+
} else {
90+
setHasPermission(true);
91+
}
92+
} catch (err) {
93+
console.warn(err);
94+
setHasPermission(false);
95+
}
96+
}
97+
}, []);
98+
6899
const requestCameraPermission = async () => {
69100
if (Platform.OS === 'android') {
70101
try {
@@ -82,10 +113,34 @@ export default function ScanScreen({ navigation }: Props) {
82113
} catch (err) {
83114
console.warn(err);
84115
}
85-
} else {
86-
// iOS permissions would typically be handled via react-native-permissions
87-
// For this demo, assume true if not Android
88-
setHasPermission(true);
116+
} else if (Platform.OS === 'ios') {
117+
try {
118+
const RNCameraKitModule = NativeModules.RNCameraKitModule;
119+
if (RNCameraKitModule) {
120+
const status = await RNCameraKitModule.checkDeviceCameraAuthorizationStatus();
121+
if (status === true) {
122+
setHasPermission(true);
123+
} else if (status === -1) {
124+
const granted = await RNCameraKitModule.requestDeviceCameraAuthorization();
125+
setHasPermission(granted === true);
126+
} else {
127+
setHasPermission(false);
128+
Alert.alert(
129+
'Camera Access Required',
130+
'Please enable camera access in your device settings to scan QR codes.',
131+
[
132+
{ text: 'Cancel', style: 'cancel' },
133+
{ text: 'Settings', onPress: () => Linking.openURL('app-settings:') },
134+
],
135+
);
136+
}
137+
} else {
138+
setHasPermission(true);
139+
}
140+
} catch (err) {
141+
console.warn(err);
142+
setHasPermission(false);
143+
}
89144
}
90145
};
91146

@@ -104,7 +159,7 @@ export default function ScanScreen({ navigation }: Props) {
104159
title: 'My DevCard QR',
105160
url: uri,
106161
});
107-
} catch (err) {
162+
} catch {
108163
Alert.alert('Error', 'Failed to save QR code');
109164
}
110165
}
@@ -126,7 +181,8 @@ export default function ScanScreen({ navigation }: Props) {
126181
useFocusEffect(
127182
useCallback(() => {
128183
fetchCards();
129-
}, [fetchCards])
184+
checkInitialCameraPermission();
185+
}, [fetchCards, checkInitialCameraPermission])
130186
);
131187

132188
useEffect(() => {
@@ -144,6 +200,19 @@ export default function ScanScreen({ navigation }: Props) {
144200
loadStoredCardId();
145201
}, []);
146202

203+
useEffect(() => {
204+
const handleAppStateChange = (nextAppState: AppStateStatus) => {
205+
if (nextAppState === 'active') {
206+
checkInitialCameraPermission();
207+
}
208+
};
209+
210+
const subscription = AppState.addEventListener('change', handleAppStateChange);
211+
return () => {
212+
subscription.remove();
213+
};
214+
}, [checkInitialCameraPermission]);
215+
147216
useEffect(() => {
148217
if (!hasLoadedStoredCard) return;
149218

0 commit comments

Comments
 (0)