How to save file temporary? - flutter

I am using dio and path_provider to save pdf from url, I am going to show that pdf to user using open_file. But I have problem with saving path.
Where I can save file temporary, show that file, and after some time or when user will not look at the app delete file? File can be even deleted after 2 days. Time when pdf will be removed is not that important.
It can be even longer time, but sooner or later it must happen. This is in order to not have old pdf's stored on the phone in case of pdf's change on the web
Right now it is my path:
var tempDir = await getTemporaryDirectory();
String fullPath = "${tempDir.path}/test.pdf";
edit: there is also a second option, to check if something is in this place saved, if yes, then remove it and download again, but this place can not be shown to a users, I found "getApplicationDocumentsDirectory", this allows me to save pdf in place where users can not read a pdf.
After that reaserch my question will be, If I download my pdf in a way as you can see above it will stay in that place and will never be moved? Now I need to only creade a methode that will see if my pdf is there end will remove it? How to extract name of my pdf I will need that?

I guess you have selected the right path if you just needed to delete the file for the space on device because when you use the getTemporaryDirectory() the system will automatically delete files in this directory as disk space is needed elsewhere on the device. The system will always delete older files first, based on the lastModifiedTime.
But if you want to check if the file changed or not you can send in the response of the file a flag that contains the last updated date and this value can be the file name prefix, so when ever you open the app you can check if the date has changed you will delete the old one manually and store the new one.
If you follow this solution it will be no need to use getTemporaryDirectory() you have to use the getApplicationDocumentsDirectory()

Related

Checking for a new version of a plist on my server

I've experimented with several ways on seeing if I need to update my user's UITableView data source only if the server one is newer. Over the past few years I've done these scenarios: 1: Having a seperate .txt file with a character as the version # then simply comparing them through code and downloading the new .plist, then saving that .txt to the user's NSDocumentDirectory along with the .plist to compare again in the future, and 2: Actually checking the server's file modification date, which worked even better, as there was no .txt file to download along with the .plist (the less stuff to download the better)
But, now I want to try a different way to account for the fact that I ship a .plist file in the App Bundle. Since the .plist file creation date is always later then the server date for new users, they don't get the new .plist file, whereas older users of the app get the new file. Sure, on the first app launch I could grab the server's modification date and overwrite the app's since I copy it from the main bundle to the NSDocumentDirectory, but I don't think I want to go that route, as I've never liked checking launch counts.
Basically, it needs to continue to be lightweight in network request time and be reliable like it's been for me. I was thinking about creating a version # key in my .plist and simply comparing that with the local .plist, but I highly doubt this will be as lightweight, as I would have to download the whole .plist into an NSDictionary first before I can compare the key values.
I'm really sorry this post is long, and I appreciate your help!
Why not ship the app with out the data_source.plist file and download it on first launch, or any other time it does not exist on disk (you never know). After that, you could send a HEAD request and check the modification date (maybe even the e-tag), and download as necessary.
UPDATE:
Depending on how much control you have over the server, you could add a hash of the file to the response headers (as mentioned in the comments: MD5,SHA*) along side Last-Modified.
You could add the data_source.plist to the bundle at build time, along with last_modified.plist where you can set the hash, last modified, and any other meta data you want, as starting point.
Checking for updates could look something like:
Send HEAD request for http://server.com/data_source.plist
Pull Last-Modified (and hash if you can send it) from the response headers
Validate against corresponding values in last_modifed.plist
Download updated data_source.plist if needed
If the download was successful, update last_modifed.plist with new meta data (last modified and has, be sure pull this from actual download response headers).
This way, the user has something to start with, and the app can download the resource when needed.
The advantage of a HEAD request is it is light weight since there is no message body, but returns the same response headers as a GET request. It is a common method to check if a resource has been updated. The trick with your scenario is to get a starting point onto the device at build time.

Renaming file with filepicker.io

Here is my use case: the user will click a "save" link and will be presented with a filepicker.export() dialog, choose a location and name and save a file. Here's the exotic part: I won't have the file yet at that time. It needs to be downloaded first with a GET request, and then stored in filepicker. I won't know which file to start downloading until the user clicks "save".
This can be dealt with by first downloading the file when the user clicks "save", and only then displaying the filepicker.export() dialog. However, I find this cumbersome, since the user will have to wait for the download to finish to be able to choose a filename and location.
It would be much better to allow the user to first make their choice, for example "Dropbox/image.png", and store some sort of placeholder while the download is running: "Dropbox/image.png.part". Later, when the download finishes, I could write the data to the file and rename it to "Dropbox/image.png".
Here are my questions:
Is it possible to append ".part" to the filename that the user chose in the filepicker.export() call?
More importantly, while I know how to write to the file when the download is done, is there any way to rename it? I tried creating a new fpfile object with the same filepicker URL and a different filename, the new filename was ignored (though the write succeeded).
My recommendation would be to first call filepicker.export call on an empty file and allow the user to specify both the name of the file they would like and the location in their cloud storage. When the filepicker.export call finishes, it will pass an FPFile into the callback. From there, you can download any necessary contents you need and do a filepicker.write to save the contents to the location selected by the user.
There shouldn't be any need to rename the file, as the user has already provided the name they want to save the file under during the filepicker.export() call.

How to delete file automatically older than 3 months

How to delete file automatically older than 3 months.
I am read pdf file from webservice in UIWebview and store all file in cache directory
and again i came same view its download pdf file its ok
I storing file in cache directory
but i want delete particular file automatically delete in given time.How do this
first make sure that when you create a new file you set a date property to the file.
then you make a method that look at all files in a directory and compare their date to now and delete those who are too old. and you call this method when the app has launched or has return to foreground.

iOS - Allow user to download file from documents directory but not to upload file using iTunes

Here is a situation I have a data file in document directory which is being updated in the application every now and then. So I want to save it to my desktop using iTunes. But I don't want that the file should be uploaded back to my application. i.e. I want that user can download the file but can not upload any.
I was thinking to have the data file on some other location like Library and put a button on application settings saying "Prepare backup" that will copy that data file in Document directory, from where user can download it. If user uploads any thing it won't make any difference as my current file is in Library directory.
This is just a thought,
can anyone suggest me other way or the above way is good to go?
Edit: I just need that after the successful export user can view the data file (may be later) without support of the application.
You can't.
But what you can do is check (using an timer every 10 seconds) if a new file is added to the documents directory and then delete it programmatically.
But this ofcourse doesn't disable the replacement of files.

Replace existing XML file within iPhone app

I have an .xml file that is going to be shipped within my app.
This file contains values that are read from it and saved as an array when the app launches.
Each time the app is run, I want to check with the server if there is an internet connection. If so, I want to get the newest version of the .xml file from the server and replace the one that I currently have saved in my app (this way, the next time the user logs in and doesn't have internet access, he/she will be able to use the old (yet most up to date) data).
What is the best way to do this?
Thanks,
The best way to probably do this is to copy the XML file from the app bundle to a location in the app's sandbox, e.g. the Documents folder. Thereafter you can update the XML content as necessary with newer data from the server. The copy is necessary to allow you to write to the file, since you cannot change the content of your app's bundle because it is signed.
Alternatively, if the data is simple enough, you can just save it to user defaults on first launch and change the defaults on subsequent updates
I might skip the XML altogether, unless it contains a baseline of default settings, and just sync user defaults over the Internet. You can't modify files in the bundle, so your only option would be to copy over a "default-settings" XML file to the application's Documents folder to make it editable.