Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

on iOS, store only relative portion of directory path #277

Closed

Conversation

781flyingdutchman
Copy link
Contributor

On iOS the path represented by NSDocumentDirectory changes with every startup. Per Apple documentation, one should therefore never store the entire path, only the relative portion (that follows the NSDocumentDirectory).
In the current downloader code we accept the entire path, and go through some tricks to truncate it to the relative portion only (using [self shortenSavedDirPath:savedDir]). However, the full path is stored in the sqlite database, and this can lead to difficulties when that path is no longer valid by the time the application wakes up following a download.
This fork proposes to only every store the relative portion of the path in the sqlite database, to avoid problems with reconstructing or using it when the app restarts.

The pros of this change are: complies with Apple's advise and avoids errors when a download completes when the app has restarted (these are rare cases, but I use the plugin to download thousands of files and it does happen)

The con of this change is that the bahavior now is slightly different between iOS and Android: on Android we store the full path, whereas on iOS we store only the partial path.

One option to reconcile is to also only store the partial path on Android - I have not implemented that here, and in the app that uses this downloader I do a Platform.isiOS check to treat the savedDir field differently. That works, but it would have to be clearly documented.

@hnvn happy to discuss this a bit further as this is not as obvious a change

version (without NSDocumentDirectory) and converted to a full path
only when the download is complete and the file needs to be copied

This is consistent with Apple's suggestion and prevents errors where
copy is attempted to a directory that no longer exists due to
NSDocumentDirectory changing.  Per documentation, one should not store
a file path that includes NSDocumentDirectory, only the path following
it, and reconstruct at runtime.
@yringler
Copy link
Contributor

I'm very happy to see this being discussed.
I was recently made aware in my own app of ios users losing data on app update, and have become a bit worried about this issue.
This is very important.

@yringler
Copy link
Contributor

@781flyingdutchman, does this mean that currently, the DownloadTask returned by loadTasks() on ios might return an incorrect savedDir?

@781flyingdutchman
Copy link
Contributor Author

Yes. Since iOS8 the NSDocumentDirectory changes for every app launch, so you should always rebuild that path and append the relative directory. For this reason, Apple recommends that you don't store the absolute path ever, only the relative path. In this PR I have changed the code to do that, but - as I explain above - it does mean this is a breaking change and it now behaves differently between iOS and Android.
In my application I use this code and treat the results differently depending on platform, which is of course not ideal but it gets the job done.

version (without NSDocumentDirectory) and converted to a full path
only when the download is complete and the file needs to be copied

This is consistent with Apple's suggestion and prevents errors where
copy is attempted to a directory that no longer exists due to
NSDocumentDirectory changing.  Per documentation, one should not store
a file path that includes NSDocumentDirectory, only the path following
it, and reconstruct at runtime.

Re-applied this fix to the null-safe version 1.6
@kuhnroyal kuhnroyal mentioned this pull request Oct 29, 2021
2 tasks
@kkoken
Copy link

kkoken commented Nov 25, 2021

I forked the repo & applied the changes you have made, for iOS, it does not work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants