-
Notifications
You must be signed in to change notification settings - Fork 759
Description
Bug Report
Problem
What is expected to happen?
The (big) data is correctly written in the file.
What does actually happen?
The application crashes.
💡
I found a workaround but I think it remains an issue in the codebase (and could impact other developers). See below for the workaround.
Information
I use:
- cordova-plugin-file
- react-native
- redux-persist
For the persistance (with redux-persist), I have a custom storage handler to write into a file.
The write part is very simple :
function writeFile(fileEntry: FileEntry, data: any): Promise<void> {
return new Promise((resolve, reject) => {
fileEntry.createWriter(writer => {
writer.onerror = reject
writer.onwriteend = resolve
writer.write(new Blob([JSON.stringify(data)], { type: 'text/plain' }))
}, reject)
})
}
However, with an evolution, our data
passed from ~2Mo to ~20Mo. At this moment, the application crashes when saving the file.
It is the call to writer.write
which seemed to cause the application to crash, if I build the Blob without saving it, I do not have any issue.
The size of the data before crash differs from IOS and ipad version.
Workaround
I corrected (quick-win) the issue by doing so:
function writeFile(fileEntry: FileEntry, data: any): Promise<void> {
return new Promise((resolve, reject) => {
fileEntry.createWriter(writer => {
splitByChunks(JSON.stringify(data), 1000 * 1000) // 1Mo
// Ensure order of execution, could be improved
.reduce((acc, chunk) => acc.then(() => writeChunk(writer, chunk)), Promise.resolve())
.then(resolve)
.catch(reject)
}, reject)
})
}
function writeChunk(writer: FileWriter, chunk: string): Promise<void> {
return new Promise((resolve, reject) => {
writer.onerror = reject
writer.onwriteend = resolve
writer.write(new Blob([chunk], { type: 'text/plain' }))
})
}
function splitByChunks(value: string, chunkLength: number): ReadonlyArray<string> {
return Array(Math.ceil(value.length / chunkLength))
.fill(0)
.map((_, index) => value.slice(index * chunkLength, (index + 1) * chunkLength))
}
Although this correction works in my project there is an issue when the file is not totally written (application closed during write). I resolved it by ignoring incomplete file (= JSON.parse
fails) because my project permits it.
Environment, Platform, Device
- ipad4 / ios10
- ipad5 / ios12
- ipad6 / ios12
Version information
- cordova: 8.1.2
- "cordova-browser": "5.0.1", // also tested on v6.0.1 - same issue
- "cordova-ios": "4.5.4",
- "cordova-plugin-file": "5.0.0",
Checklist
- I searched for existing GitHub issues
- I updated all Cordova tooling to most recent version
- But rolled back because of some incompatibilities in other parts of the application, issue still happening in last versions
- I included all the necessary information above
Thanks for the plugin! 👍