react native(expo)选择图片/视频并上传阿里云oss

1.引入相关库:

复制代码
@ant-design/react-native ant风格UI库
expo-file-system 文件访问
expo-image-picker 图片/视频选择器

2.新建图片选择并上传的帮助类

复制代码
import { Toast } from '@ant-design/react-native';
import * as FileSystem from "expo-file-system";
import * as ImagePicker from 'expo-image-picker';
import AppService from "../api/app";
import Loading from "../components/ui/Loading";
import LogUtil from "./log_util";

// 从后端api获取
export let ossUrl = 'https://oss-2008.oss-cn-hongkong.aliyuncs.com';
let ossConfig = null;

/**
 * @desc 选择相册图片
 */
export const pickImage = async (mediaTypes = ImagePicker.MediaTypeOptions.Images) => {
    // No permissions request is necessary for launching the image library
    let result = await ImagePicker.launchImageLibraryAsync({
        mediaTypes: mediaTypes,
        allowsEditing: true,
        aspect: null,
        quality: 0.5,
    });

    LogUtil.log('pick image result = ', result);

    if (result.canceled) {
        return null;
    }
    if (mediaTypes === ImagePicker.MediaTypeOptions.Images) {
        if (result.assets[0]?.fileSize/(1024*1024) > 2) {
            Toast.fail('图片不能超过2MB');
            return null;
        }
    } else if (mediaTypes === ImagePicker.MediaTypeOptions.Videos) {
        if (result.assets[0]?.fileSize/(1024*1024) > 10) {
            Toast.fail('视频不能超过10MB');
            return null;
        }
    } else {}

    return result.assets[0].uri;
};

export const uploadImage = async (fileName, filePath, nav) => {
    Loading.show();
    // 从后端获取阿里云oss相关凭证
    const res = await AppService.getAliyunOssToken({}, nav);
    if (res.code === 200) {
        /*
        *
        * host = obj['host']
            policyBase64 = obj['policy']
            accessid = obj['accessid']
            signature = obj['signature']
            expire = parseInt(obj['expire'])
            callbackbody = obj['callback']
            key = obj['dir']
        *
        *  */
        ossConfig = res.data;
        ossUrl = ossConfig['host'];
    } else {
        Loading.hide();
        Toast.info('获取oss token信息失败')
        return null;
    }

    if (filePath && filePath.length > 0) {
        const split = filePath.split('.');
        let realFileName = (!fileName || fileName.length === 0) ? `${random_string()}.${split[split.length - 1]}` : `${fileName}.${split[split.length - 1]}`;
        let key = `${ossConfig['dir']}${realFileName}`;
        let imageServicePath = `${ossConfig['host']}/${key}`;

        try {
            LogUtil.log('ossUrl = ', ossUrl)
            // 使用FileSystem.uploadAsync上传文件至阿里云oss
            const response = await FileSystem.uploadAsync(`${ossUrl}`, filePath, {
                fieldName: 'file',
                httpMethod: 'POST',
                uploadType: FileSystem.FileSystemUploadType.MULTIPART,
                parameters: {
                    'name': realFileName,
                    'key': key,
                    'policy': ossConfig['policy'],
                    'OSSAccessKeyId': ossConfig['accessid'],
                    'success_action_status': '200',
                    'callback': ossConfig['callback'],
                    'signature': ossConfig['signature']
                }
            })

            LogUtil.log('response', JSON.stringify(response), 'imageServicePath', imageServicePath)
            Loading.hide();
            if (response.status !== 200) {
                return null;
            }
            return { imageServicePath, fileName: key };
        } catch (error) {
            LogUtil.error(error)
        }
    }
    Loading.hide();
    return null;
}

const random_string = (len) => {
    len = len || 32;
    let chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
    let maxPos = chars.length;
    let pwd = '';
    for (let i = 0; i < len; i++) {
        pwd += chars.charAt(Math.floor(Math.random() * maxPos));
    }
    return pwd;
}

3.代码中调用:

3.1 只选择图片、视频后用于展示

复制代码
pickImage(mediaTypes).then(uri => {
            if (uri) {
                // uri可直接使用ImageView组件展示
            }
        })

3.2 选择图片、视频再上传阿里云oss后展示

复制代码
    const ChatTypes = {
        voice: 6,
        image: 2,
        video: 3,
        text: 1,
        systemTips: 4,
        autoText: 5,
    }    
    
    let imageSendValue = '';
    let videoSendValue = '';
    let imageUri = '';
    let videoUri = '';
    const pickAndUploadImage = (type) => {
        let mediaTypes = type === ChatTypes.image ? ImagePicker.MediaTypeOptions.Images : ImagePicker.MediaTypeOptions.Videos;
        pickImage(mediaTypes).then(uri => {
            if (uri) {
                uploadImage(null, uri, navigation).then(res => {
                    if (!res) {
                        Toast.info(i18n.t("Chat.UploadFail"));
                        return;
                    }
                    LogUtil.log('imageServicePath = ', res?.imageServicePath, 'fileName = ', res?.fileName)

                    switch (type) {
                        case ChatTypes.image:
                            imageSendValue = res?.fileName;
                            imageUri = uri;
                            // sendMessage(ChatTypes.image, imageSendValue, imageUri);
                            break;
                        case ChatTypes.video:
                            videoSendValue = res?.fileName;
                            videoUri = uri;
                            // sendMessage(ChatTypes.video, videoSendValue, videoUri);
                            break;
                        default:
                            break;
                    }
                })
            }
        })
    }
相关推荐
Database_Cool_9 小时前
在 RDS PostgreSQL 中实现 RaBitQ 量化
数据库·阿里云·ai·postgresql
沐言人生10 小时前
React Native 源码分析1——HybridData 机制深度分析
android·react native
空中海10 小时前
01 React Native 基础、核心组件与布局体系
javascript·react native·react.js
空中海10 小时前
05 React架构设计、项目实践与专家清单
前端·react.js·前端框架
空中海13 小时前
04 工程化、质量体系与 React 生态
前端·ubuntu·react.js
Yue16813 小时前
一文教你五分钟学会Zustand,React状态管理更加方便!
react native
空中海13 小时前
03 性能、动画与 React Native 新架构
react native·react.js·架构
空中海15 小时前
02 React Native状态、导航、数据流与设备能力
javascript·react native·react.js
空中海16 小时前
04 React Native工程化、质量、发布与生态选型
javascript·react native·react.js
郑生zs18 小时前
Hooks-useEffect
react.js