I am writing to you in order to get advice about a vexing problem. My React Native Apps tries to open the camera resp. the image library when clicking on a Button, which works perfectly fine on Android, but when trying on ios, the launchCameraAsync and the launchImageLibraryAsync functions will not be executed. I am using expo v49.0.0 for my project, the expo-image-picker v14.3.0 and expo-image-manipulation v11.3.0 libraries to add this functionality.
Here a shortened version of my Code:
import { Dimensions, StyleSheet, View, Image, Text, TouchableOpacity, Modal, Alert, Pressable } from "react-native";
import { TextInput } from "react-native-gesture-handler";
import { useEffect, useState, useRef, forwardRef } from "react";
import Services from "../../Service/Services";
import Icon from "../../components/Icon";
import * as ImagePicker from "expo-image-picker";
import ImageViewer from "../../components/ImageViewer";
import Ionicon from "react-native-vector-icons/Ionicons";
import * as ImageManipulator from 'expo-image-manipulator';
import BasicModal from "../../components/modals/BasicModal";
import colors from "../../config/colors";
function AccountModification({navigation}){
useEffect(()=>{
loadProfile();
}, [navigation]);
const pickImageAsync = async () => {
if((await ImagePicker.getMediaLibraryPermissionsAsync()).status == 'denied' && (await ImagePicker.getMediaLibraryPermissionsAsync()).granted == false){
alert("Bitte gehen sie in Ihre Einstellungen und erlauben sie den Zugriff auf Ihre Galerie!")
}else{
await ImagePicker.launchImageLibraryAsync({
allowsEditing:true,
base64:true,
quality:0.2,
}).then(async (response) => {
console.log("5")
delete response.cancelled;
if (!response.canceled) {
let manipResult = await ImageManipulator.manipulateAsync(response.assets[0].uri,[{resize:{height:250}}],{base64:true})
setSelectedImage(manipResult.base64);
ProjectStore.user.image = manipResult.base64;
await Services.setProfilePicture(manipResult.base64);
}
}).catch(error =>{
console.log(error)});
}
}
const makePictureAsync = async () => {
if((await ImagePicker.getCameraPermissionsAsync()).status == 'denied' || (await ImagePicker.getCameraPermissionsAsync()).granted == 'false'){
alert("Bitte gehen sie in Ihre Einstellungen und erlauben sie den Zugriff auf Ihre Kamera!");
}else if(((await ImagePicker.getCameraPermissionsAsync()).status == 'undetermined')){
await ImagePicker.requestCameraPermissionsAsync();
}else{
await ImagePicker.launchCameraAsync({
allowsEditing:true,
base64:true,
quality:0.2
}).then( async (response)=>{
delete response.cancelled;
if (!response.canceled) {
let manipResult = await ImageManipulator.manipulateAsync(response.assets[0].uri,[{resize:{height:250}}],{base64:true})
setSelectedImage(manipResult.base64);
ProjectStore.user.image = manipResult.base64;
await Services.setProfilePicture(manipResult.base64);
}
}).catch(error => {console.log(error)});
}
}
return(
<View style={{flex:1}}>
<View style={styles.topContainer}>
<TouchableOpacity style={styles.profilePictureContainer} onPress={()=>{setModalVisible(!modalVisible)}}>
<ImageViewer
placeholderImageSource={PlaceHolder}
selectedImage={selectedImage}
/>
<Text style={styles.link}>Profilbild ändern</Text>
</TouchableOpacity>
<Text style={styles.userName}>{ProjectStore.userName}</Text>
</View>
<View style={styles.middleContainer}>
<Text style={styles.lable}>Vorname</Text>
<TextInput
style={styles.input}
value={profileFirstname}
onChangeText={text => {setProfileFirstname(text);}}
/>
<Text style={styles.lable}>Nachname</Text>
<TextInput
style={styles.input}
value={profileLastname}
onChangeText={text =>{ setProfileLastname(text);}}
/>
<Text style={styles.lable}>Email</Text>
<TextInput
style={styles.input}
value={profileEmail}
onChangeText={text =>{ setProfileEmail(text);}}
/>
<Text style={styles.lable}>Postleitzahl</Text>
<TextInput
style={styles.input}
value={profileZipcode}
onChangeText={text => setProfileZipcode(text)}
/>
</View>
<Modal
visible={modalVisible}
animationType='slide'
transparent={true}
>
<View style={styles.centeredView}>
<View style={styles.modal}>
<TouchableOpacity style={styles.modalButton} onPress={()=>{setModalVisible(!modalVisible); makePictureAsync()}}>
<Ionicon name='camera-outline' size={40}></Ionicon>
<Text>Kamera öffnen</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.modalButton} onPress={()=>{setModalVisible(!modalVisible); pickImageAsync()}}>
<Ionicon style={styles.icon} size={40} name='images-outline'></Ionicon>
<Text>Galerie öffnen</Text>
</TouchableOpacity>
</View>
</View>
</Modal>
</View>
);
}
const styles = StyleSheet.create({
topContainer:{
flex:1,
flexDirection:"row",
height:"45%",
},
middleContainer:{
flex:3,
width:"90%",
alignSelf:"center",
},
profilePictureContainer:{
marginLeft:10,
width:Dimensions.get('window').width*0.3,
height:Dimensions.get('window').width*0.3,
alignSelf:'center',
borderRadius:Math.round(Dimensions.get('window').width + Dimensions.get('window').height) / 2
},
userName:{
fontSize:20,
fontWeight:"bold",
alignSelf: "center",
marginLeft:"15%",
borderBottomColor:"black",
borderBottomWidth: 1,
width:"40%",
textAlign:"center",
},
lable:{
fontSize:12,
color:"grey",
backgroundColor:"transparent",
marginTop:10
},
input:{
fontSize:16,
borderBottomColor: "lightgrey",
borderBottomWidth:1,
padding:5,
marginTop:-5
},
link:{
color:'dodgerblue',
paddingTop:4,
alignSelf:'center'
},
centeredView:{
flex:1,
marginTop:40,
alignItems:'center',
justifyContent:'flex-end'
},
modal:{
flexDirection:'row',
justifyContent:'space-evenly',
width:'100%',
height:"20%",
backgroundColor:'white',
alignItems:"center"
},
modalButton:{
alignItems:'center',
},
icon:{
}
})
export default AccountModification;
For clarification, permissions have been granted and look like this:
{"status":"granted","canAskAgain":true,"expires":"never","granted":true}
I tried to ask for permissions again, but await ImagePicker.requestCameraPermissionsAsync() is also not executeable.
I hope someone can help me!
If you need further details please feel free ask.