前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >React Native 使用react-native-image-picker库实现图片上传功能

React Native 使用react-native-image-picker库实现图片上传功能

作者头像
xiangzhihong
发布2018-02-06 16:54:51
4.8K0
发布2018-02-06 16:54:51
举报
文章被收录于专栏:向治洪向治洪

react-native-image-picker作为一个集成相机和相册的功能的第三方库,因为其使用相对简单受到前端开发人员的喜爱。

react-native-image-picker使用

1, 首先,安装下该插件。

代码语言:javascript
复制
npm install react-native-image-picker@latest --save

2, 针对Android和iOS平台分别进行配置

## android 平台配置

1,在android/settings.gradle文件中添加如下代码:

代码语言:javascript
复制
include ':react-native-image-picker'
project(':react-native-image-picker').projectDir = new File(settingsDir, '../node_modules/react-native-image-picker/android')

2,在android/app/build.gradle文件的dependencies中添加如下代码:

代码语言:javascript
复制
compile project(':react-native-image-picker')

3,在AndroidManifest.xml文件中添加权限:

代码语言:javascript
复制
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

4,最后在MainApplication.Java文件中添加如下代码:

代码语言:javascript
复制
import com.imagepicker.ImagePickerPackage;
 new ImagePickerPackage()

这样Android环境就配置好了。

iOS平台配置

1,打开Xcode打开项目,点击根目录,右键选择 Add Files to ‘XXX’,选中项目中的该路径下的文件即可:node_modules -> react-native-image-picker -> ios -> select RNImagePicker.xcodeproj

这里写图片描述
这里写图片描述

2,添加成功后使用link命令:react-native link react-native-image-picker 。 3,打开项目依次使用Build Phases -> Link Binary With Libraries将RNImagePicker.a添加到项目依赖。

这里写图片描述
这里写图片描述

4,对于iOS 10+设备,需要在info.plist中配置NSPhotoLibraryUsageDescription和NSCameraUsageDescription。

这里写图片描述
这里写图片描述

react-native-image-picker示例

为了项目使用的方便,我们将其封装为一个组件CameraButton.js。代码如下:

代码语言:javascript
复制
import React from 'react'
import {
    TouchableOpacity,
    StyleSheet,
    Platform,
    ActivityIndicator,
    View,
    Text,
    ToastAndroid
} from 'react-native'

var ImagePicker = require('react-native-image-picker');
import Icon from 'react-native-vector-icons/Ionicons';

const options = {
    title: '选择图片', 
    cancelButtonTitle: '取消',
    takePhotoButtonTitle: '拍照', 
    chooseFromLibraryButtonTitle: '图片库', 
    cameraType: 'back',
    mediaType: 'photo',
    videoQuality: 'high', 
    durationLimit: 10,
    maxWidth: 600,
    maxHeight: 600,
    aspectX: 2, 
    aspectY: 1,
    quality: 0.8,
    angle: 0,
    allowsEditing: false,
    noData: false,
    storageOptions: { 
        skipBackup: true, 
        path: 'images'
    }
};

class CameraButton extends React.Component {
    constructor(props){
        super(props);
        this.state = {
            loading:false
        }
    }
    render() {
        const {photos,type} = this.props;
        let conText;
        if(photos.length > 0){
            conText = (<View style={styles.countBox}>
                <Text style={styles.count}>{photos.length}</Text>
            </View>);
        }
        return (
            <TouchableOpacity
                onPress={this.showImagePicker.bind(this)}
                style={[this.props.style,styles.cameraBtn]}>
                <View>
                    <Icon name="md-camera" color="#aaa" size={34}/>
                    {conText}
                </View>
            </TouchableOpacity>
        )
    }

    showImagePicker() {
        ImagePicker.showImagePicker(options, (response) => {
            if (response.didCancel) {
                console.log('User cancelled image picker');
            }
            else if (response.error) {
                console.log('ImagePicker Error: ', response.error);
            }

            else {

                let source;

                if (Platform.OS === 'android') {
                    source = {uri: response.uri, isStatic: true}
                } else {
                    source = {uri: response.uri.replace('file://', ''), isStatic: true}
                }




                let file;
                if(Platform.OS === 'android'){
                    file = response.uri
                }else {
                    file = response.uri.replace('file://', '')
                }


                this.setState({
                    loading:true
                });
                this.props.onFileUpload(file,response.fileName||'未命名文件.jpg')
                .then(result=>{
                    this.setState({
                        loading:false
                    })
                })
            }
        });
    }
}
const styles = StyleSheet.create({
    cameraBtn: {
        padding:5
    },
    count:{
        color:'#fff',
        fontSize:12
    },
    fullBtn:{
        justifyContent:'center',
        alignItems:'center',
        backgroundColor:'#fff'
    },
    countBox:{
        position:'absolute',
        right:-5,
        top:-5,
        alignItems:'center',
        backgroundColor:'#34A853',
        width:16,
        height:16,
        borderRadius:8,
        justifyContent:'center'
    }
});

export default CameraButton;

然后在需要使用的地方引入。

代码语言:javascript
复制
import CameraButton from '../../component/huar/cameraButton'


                    <CameraButton style={styles.cameraBtn}
                                  photos={[]}
                                  onFileUpload={this.onFileUpload} />
点击上传事件:
    onFileUpload(file, fileName){
        return this.props.uploadAvatar({
            id: this.props.user.ID,
            type:'logo',
            obj:'user',
            corpId: this.props.cropId
        }, file, fileName)}
 Action请求代码:
function actions(dispatch) {
    return {
        fileUrl,fileName)=>dispatch(Actions.uploadAvatar(params, fileUrl,fileName))
    }
}

actions中的uploadAvatar函数如下。

代码语言:javascript
复制
function uploadAvatar(params, fileUrl, fileName) {
    return dispatch=> {
        return UserService.uploadImage(params, fileUrl, fileName)
            .then(result=> {
                dispatch({
                    type: UPDATE_AVATAR,
                    path: result.path
                })
                return result
            })
    }
}

//UserService.uploadImage代码如下
export function uploadImage(params, fileUrl,fileName) {
    return http.uploadFile(`${config.UploadImage}`, params, fileUrl,fileName)
}

UserService函数的http异步上传图片代码如下:

代码语言:javascript
复制
let queryString = require('query-string');
import Storage from './storage'
import {
    Platform
} from 'react-native'

const os = Platform.OS;

async function uploadFile(url, params, fileUrl,fileName) {
    let Access_Token = await Storage.getItem('Access_Token');
    let data = new FormData();

    data.append('file', {
        uri: fileUrl,
        name: fileName,
        type: 'image/jpeg'
    });

    Object.keys(params).forEach((key)=> {
        if (params[key] instanceof Date) {
            data.append(key, value.toISOString())
        } else {
            data.append(key, String(params[key]))
        }
    });

    const fetchOptions = {
        method: 'POST',
        headers: {
            'Accept': 'application/json',
            'Access_Token': Access_Token ? Access_Token : '',
            'UserAgent':os
        },
        body: data
    };


    return fetch(url, fetchOptions)
        .then(checkStatus)
        .then(parseJSON)
}

封装上传

如果上面的实现看的比较复杂,那么我们做如下的封装:

代码语言:javascript
复制
let common_url = 'http://192.168.1.1:8080/';  //服务器地址
let token = '';   //用户登陆后返回的token

function uploadImage(url,params){
    return new Promise(function (resolve, reject) {
        let formData = new FormData();
        for (var key in params){
            formData.append(key, params[key]);
        }
        let file = {uri: params.path, type: 'application/octet-stream', name: 'image.jpg'};
        formData.append("file", file);
        fetch(common_url + url, {
            method: 'POST',
            headers: {
                'Content-Type': 'multipart/form-data;charset=utf-8',
                "x-access-token": token,
            },
            body: formData,
        }).then((response) => response.json())
            .then((responseData)=> {
                console.log('uploadImage', responseData);
                resolve(responseData);
            })
            .catch((err)=> {
                console.log('err', err);
                reject(err);
            });
    });
}

然后在使用的地方:

代码语言:javascript
复制
let params = {
    userId:'abc12345',   //用户id
    path:'file:///storage/emulated/0/Pictures/image.jpg'    //本地文件地址
}
uploadImage('app/uploadFile',params )
    .then( res=>{
        //请求成功
        if(res.header.statusCode == 'success'){
            //这里设定服务器返回的header中statusCode为success时数据返回成功
            upLoadImgUrl = res.body.imgurl;  //服务器返回的地址
        }else{
             //服务器返回异常,设定服务器返回的异常信息保存在 header.msgArray[0].desc
            console.log(res.header.msgArray[0].desc);
        }
    }).catch( err=>{ 
         //请求失败
    })

附:http://lib.csdn.net/article/reactnative/58022?knId=1415 使用fetch+formData实现图片上传

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-06-10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • react-native-image-picker使用
    • iOS平台配置
      • react-native-image-picker示例
        • 封装上传
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档