我最近将Ionic 4 Angular应用程序发布为Web应用程序和本机Android应用程序。
在本机Android应用程序中,除了保存下载的文件之外,一切都正常。
要下载和保存文件,我一直按如下方式使用file-saver
npm软件包(这是一种共享服务,每次我必须下载某些内容时(从PDF到图像等),我都会调用它。 ..):
import { saveAs } from 'file-saver';
// ...
saveGenericFile(api: string, fileinfos: any, idFile: string): any {
let mediaType = 'application/pdf';
let fileName = '';
if (fileinfos != null) {
mediaType = fileinfos.contentType;
fileName = fileinfos.fileName;
}
const headers = this.base.commonHeader;
const url = this.baseUrl + api + '?id=' + idFile;
this.http.post(url, null, { headers, responseType: 'blob' }).subscribe(
(response) => {
// tslint:disable-next-line: prefer-const
let blob = new Blob([response], { type: mediaType });
saveAs(blob, fileName);
}, e => {
console.error(e);
this.toastsvc.generateToast('ERROR! An error occurred while saving this File, try later or contact support', 'danger');
}, () => {
/* do nothing */
}
);
}
如上所述,该代码段可以正常工作,但是只是在我必须从Web版本中保存某些内容时。
我唯一能找到的在线示例都是有关Cordova和/或先前/已弃用的版本的信息。
关于电容器,我刚发现this documentation,并从中发现了以下代码片段:
import { Plugins, FilesystemDirectory, FilesystemEncoding } from '@capacitor/core';
const { Filesystem } = Plugins;
fileWrite() {
try {
Filesystem.writeFile({
path: 'secrets/text.txt',
data: "This is a test",
directory: FilesystemDirectory.Documents,
encoding: FilesystemEncoding.UTF8
});
} catch(e) {
console.error('Unable to write file', e);
}
}
但是问题是我上面的函数返回一个blob,而这个函数仅接受数据字符串。
那么,在作为Web应用程序运行和作为Android本机应用程序运行时,我是否可以使用任何与Capacitor-Native等效的功能来下载(并保存)Blob文件?
更新
我也尝试了以下方法,但是它不起作用:
saveGenericFile(api: string, fileinfos: any, gidFile: string): any {
let mediaType = 'application/pdf';
let fileName = '';
if (fileinfos != null) {
mediaType = fileinfos.contentType;
fileName = fileinfos.fileName;
}
const headers = this.base.commonHeader;
const url = this.baseUrl + api + '?id=' + gidFile;
this.http.post(url, null, { headers, responseType: 'blob' }).subscribe(
(response) => {
if (!this.useCordovaDl) {
// tslint:disable-next-line: prefer-const
let blob = new Blob([response], { type: mediaType });
saveAs(blob, fileName);
} else {
this.blobFileWrite(fileName, response);
}
}, e => {
console.error(e);
this.toastsvc.generateToast('ERROR! An error occurred while saving this File, try later or contact support', 'danger');
}, () => {
/* do nothing */
}
);
}
blobFileWrite(filename: string, blobfile: Blob) {
const reader = new FileReader();
// This fires after the blob has been read/loaded.
reader.addEventListener('loadend', (e: any) => {
const text = e.srcElement.result;
this.fileWrite(filename, text);
});
// Start reading the blob as text.
reader.readAsText(blobfile);
}
fileWrite(filename: string, filedata: string) {
try {
Filesystem.writeFile({
path: filename,
data: filedata
// ,
// directory: FilesystemDirectory.Documents,
// encoding: FilesystemEncoding.UTF8
});
} catch (e) {
console.error('Unable to write file', e);
}
}
更新#2
关于there's still an opened issue on GitHub与电容器一起保存Blob数据的信息。同时,我将寻找Cordova解决方案。或者,如果平台是android或ios,我将仅禁用每个下载按钮。
如果可以的话,我将在这里发布所有可行的Cordova解决方法
答案 0 :(得分:1)
您可以创建一个插件,可以向其传递URL,该插件将以本地方式下载。您已经发现无法传递blob /文件。
如果没有可用的插件,或者您不想创建一个。
您可以从js
调用本机函数,可以在native
端监听URL等。
答案 1 :(得分:1)
与您分享我的解决方法。
我正在使用Filesystem插件的Web实现。 不知道这是否是一个好的解决方案,但可以帮助解决我的问题。
import { FilesystemDirectory, FilesystemEncoding } from '@capacitor/core'
// const { Filesystem } = Plugins // => Doesn't work with blob in native
// Workaround: Use Web-Implementation of plugin
import { FilesystemPluginWeb } from '@capacitor/core/dist/esm/web/filesystem.js'
const Filesystem = new FilesystemPluginWeb()
答案 2 :(得分:0)
如果要实现的目标是将文件保存在文件系统中,则可以使用字符串base64将其保存到文件系统中
image = "data:image/png;base64,iVBORw0KGgo... bla bla bla"
Capacitor.Plugins.Filesystem.appendFile({
data:image,
path:"directory/image.png",
directory:"DOCUMENTS"
}).then(c=>{console.log("se escribiooo")})
它会在文件系统中生成图像(我刚刚在android仿真器中尝试了此代码),只需使用方法appendFile代替writeFile,并使用base64代替blob,如果只有blob,则只需将其转换为base64 < / p>