有时候我们需要下载或者缓存一些静态文件到设备上,比如pdf, mp3, mp4等。rn-fetch-blob是一个可以将你的HTTP返回作为文件存在设备上的native库。他其实就是react-native-fetch-blob,但是react-native-fetch-blob没有继续维护了,所以就fork过来改了个名字继续维护。
你只要在请求的配置里面设置fileCache : true,他就会将返回值作为文件存起来,同时返回给你物理路径,默认存的文件是没有后缀名的,你可以加参数设定后缀,比如:appendExt : 'zip'
拿到这个路径可以直接用
imageView = <Image source={{ uri : Platform.OS === 'android' ? 'file://' + res.path() : '' + res.path() }}/>这个库还可以支持文件上传
RNFetchBlob.fetch('POST', 'https://content.dropboxapi.com/2/files/upload', { // dropbox upload headers Authorization : "Bearer access-token...", 'Dropbox-API-Arg': JSON.stringify({ path : '/img-from-react-native.png', mode : 'add', autorename : true, mute : false }), 'Content-Type' : 'application/octet-stream', // Change BASE64 encoded data to a file path with prefix `RNFetchBlob-file://`. // Or simply wrap the file path with RNFetchBlob.wrap(). }, RNFetchBlob.wrap(PATH_TO_THE_FILE)) .then((res) => { console.log(res.text()) }) .catch((err) => { // error handling .. })在下载和上传过程中,还可以拿到他的进度:
RNFetchBlob.fetch('POST', 'http://www.example.com/upload', { //... some headers, 'Content-Type' : 'octet-stream' }, base64DataString) // listen to upload progress event .uploadProgress((written, total) => { console.log('uploaded', written / total) }) .then((resp) => { // ... }) .catch((err) => { // ... }) RNFetchBlob .config({ // add this option that makes response data to be stored as a file, // this is much more performant. fileCache : true, appendExt : 'zip' }) .fetch('GET', 'http://www.example.com/file/example.zip', { Authorization : 'Bearer access-token...', //some headers .. }) // listen to download progress event .progress((received, total) => { console.log('progress', received / total) }) .then((res) => { // the temp file path console.log('The file saved to ', res.path()) })要注意点的是,rn-fetch-blob并不会记录你的下载历史,就是说你关掉APP再打开,你就不知道你下载的文件哪儿去了。我们可以用AsyncStorage配合着记录下载的历史。
下载完成后记录地址到AsyncStorage:
检查是不是已经下过这个文件了:
componentDidMount() { AsyncStorage.getItem('fileCache').then((data) => { this.setState({ cachedFile: data, }); }); }用完了也可以删除这个文件,同时删除记录
clearCache() { const { cachedFile } = this.state; RNFetchBlob.fs.unlink(cachedFile).then(() => { this.setState({ cachedFile: null, }); AsyncStorage. removeItem('fileCache'); }); }