react-native-image-picker
In this lab, we aimed that developing a profile screen with the 3rd party libraries, React Native API's and persistence(deviceStorage).
Index
Entry file
Open your project which name is react-native-advance/setup
. After that run these commands.
Android:
npm install
react-native run-android
iOS:
npm install
cd ios && pod install
react-native run-ios
After open your project you are ready to start next step of react-native-advance lab. :D
NativeBase Integration
NativeBase is a component library which is ready to use for developers. For more details: https://nativebase.io/
Now, we are going to start adding native-base to our project for theming.
npm install native-base --save
Image Picking from Gallery or Camera
We want to upload picture to react-native so that we should use react-native-image-picker.
To install react-native-image-picker to your project.
npm install react-native-image-picker --save
First of all, define permissions for platform:
Android:
Add permission of Android app. Open your AndroidManifest.xml
file which is under android/app/src/main/AndroidManifest.xml
.
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
And then:
npm install react-native-image-picker --save
react-native run-android
iOS:
Add permission of ios app. Open info.plist
,
<plist version="1.0">
<dict>
...
<key>NSPhotoLibraryUsageDescription</key>
<string>Please give us access to your photo library in order to change your profile photo and other informations.</string>
<key>NSCameraUsageDescription</key>
<string>Please give us access to your camera in order to verify your identity.</string>
</dict>
</plist>
cd ios && pod install
react-native run-ios
In your Profile
container (src/containers/Profile/index.js). Let's import to ImagePicker
library.
import ImagePicker from 'react-native-image-picker';
After importing ImagePicker
library, we are going to write a new function for picking images.
selectImage() {
const options = {
title: 'Select Avatar',
storageOptions: {
skipBackup: true,
path: 'images',
},
};
ImagePicker.showImagePicker(options, (response) => {
if (response.didCancel) {
console.log('User cancelled image picker');
} else if (response.error) {
console.log('ImagePicker Error: ', response.error);
} else if (response.customButton) {
console.log('User tapped custom button: ', response.customButton);
} else {
let source = { uri: 'data:image/jpeg;base64,' + response.data };
this.setState({
avatarSource: source,
});
}
});
}
Finally, we are ready to update render section. We must just editing the onPress
function.
<TouchableOpacity onPress={() => { this.selectImage() }}>
<Thumbnail large source={this.state.avatarSource} />
</TouchableOpacity>
We are ready to upload image :D
Using Device Storage
As you know, we should store our profile picture in somewhere. State solution is not good for the user and us. To solve this problem, we are going to use device storage for profile picture and etc. To create device storage, we have to use react-native-async-storage. Let's start to implement this library.
npm install @react-native-community/async-storage --save
// Only ios
cd ios/ && pod install
Let's turn back to Profile
screen. Import AsyncStorage first
import AsyncStorage from '@react-native-community/async-storage';
And now, we must use two function. One of them is saving data
and the other is loading data
. Let's start to with saving data to our device.
saveImageAsync = async () => {
await AsyncStorage.setItem("@profilePicture", JSON.stringify(this.state.avatarSource));
};
After adding this saving function. We should add load
function.
loadProfilePicture = () => {
try {
AsyncStorage.getItem("@profilePicture").then(response => {
this.setState({
avatarSource: response ? JSON.parse(response) : images.user
});
});
} catch (e) {
console.error('GET DATA ERROR', e)
}
}
This functions must be called now. Let's examine together.
Calling Save Function:
selectImage() {
ImagePicker.showImagePicker(options, (response) => {
console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled image picker');
} else if (response.error) {
console.error('ImagePicker Error: ', response.error);
} else {
const source = { uri: response.uri };
this.setState({
avatarSource: source,
});
this.saveImageAsync(); // Add Saving Function like this
}
});
}
Calling Load Function:
We will call the load function to get Image from the device storage in the componentDidMount()
lifecycle.
componentDidMount(){
this.loadProfilePicture()
}
Now, we should bind
our loadProfilePicture()
function for fixing rendering issues.
NOTE: This bind issue important for getting profile picture while moving between screens.
export default class Profile extends React.Component {
constructor(props) {
super(props)
this.state = {
avatarSource: images.user
}
this.loadProfilePicture = this.loadProfilePicture.bind(this)
}
}
If you want to see final result, you can see under solution/src/containers/Profile
or link.