R

react-native-image-picker

In this lab:

Integration of NativeBase Adding/Updating Profile Picture Saving Data in Device Storage

Archived project! Repository and other project resources are read-only

Fix: iPhoneX issue
Kerem Çubuk authored
a5a5bd86
Name Last commit Last update
setup Fix: iPhoneX issue
solution Fix: iPhoneX issue
.gitignore Update: ignore
README.md Update: Image Format

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

  1. Entry file
  2. NativeBase Integration
  3. Image Picker
  4. Using Device Storage

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.