Strangely I can't find a lot of information on this.
I am making an application that downloads images, they are downloaded and saved into my apps /Documents/ folder. To avoid an initial huge download I want to ship the app with ~100 images already "downloaded" into the folder.
How can I do this?
They have to go into your Resources bundle. You can then copy them into Documents on first launch. Yes, this means they take twice the space; if you can compress the ones in Resources effectively, I would.
An ideal answer is to have your loading routine be willing to look in both Documents and your Resources bundle and merge the results. I don't believe any built-in controllers will do this for you, however.
Related
Currently i was saving my application data (Media) to the CacheDirectory i.e
/var/mobile/Applications/BEAFC76C-C450-4A3A-9765-A0385A9580F3/Library/Caches
and things were going fine. But recently i got a bug report that the application data has been deleted. When i searched over it, i got this Apple Doc. According to it, DocumentsDirectory should be the ideal place to store the User/Application data.
Put user data in the /Documents/. User data is any
data that cannot be recreated by your app, such as user documents and
other user-generated content.
And Cache should not be used to store the User Data that could not be reproduced by the application.
Put data cache files in the /Library/Caches
directory. Examples of files you should put in this directory include
(but are not limited to) database cache files and downloadable
content, such as that used by magazine, newspaper, and map apps. Your
app should be able to gracefully handle situations where cached data
is deleted by the system to free up disk space.
What should be the ideal place to store it.
EDIT:
I have an application that allows user to store Videos and Photos in the application. For that i used CacheDirectory. But i am getting bug reports that the Data (Videos/Photos) is getting deleted. What conclusion i draw is that the data is being getting delete by the Device itself in order to provide space.
Secondly i also wanna give the iTunes sharing function. So only the particular files has to be stored in the DocumentsDirectory. Some files can never be exposed and some has has to be shared. What should be the ideal way to store the files.
Use Documents (NSDocumentDirectory) for files you wish to share via iTunes.
Use Application Support (NSApplicationSupportDirectory) for files you wish to hide from the user but still be backed up and never deleted by the OS.
Starting iOS 5, Apple says that it's no longer a good thing to save all kind of files in Documents Directory - if you do that, your app will be rejected for sure because this folder is backed up to iTunes & iCloud, unless otherwise specified.
It says that we should save files into Caches or Tmp Directory - these won't be backed up, but it's not a good thing to do because files from these directories can disappear if low memory happens.
So I think the best think to do is to save the important files that you need all the time in your app into Documents Directory and mark them not to be backed up, like this.
Library/Application Support Folder is the folder you should be using.
This directory doesn't always exist, and thus you may need to create it.
You can enable or disable whether you want to backup this data with iTunes or not.
This data is not accessible even if you enable file sharing. Only data that you put in Document directory would be shared with iTunes sharing, so you can still protect your data and get it backed up as well. Apple's documentation
I developed an Ipad app which download different kind of files, but after a week or some days the downloaded files are removed and the app that open the file can find it anymore.
Could anybody help me, Where should I save downloaded files in my app to avoid that the file came automatically deleted?. IOS usually remove downloaded files after certain time?.
I already read this apple documentation
I know that maybe is not something complicated but I can't figure out why the file is removed If anybody can help me I'll appreciate that.
Put data cache files in the /Library/Caches
directory. Examples of files you should put in this directory include
(but are not limited to) database cache files and downloadable
content, such as that used by magazine, newspaper, and map apps. Your
app should be able to gracefully handle situations where cached data
is deleted by the system to free up disk space.
Most probably you are using caches/temp directory which the system can clear contents of in case of low space. To avoid deletion use Documents Directory.
If you are already storing in documents directory, then the file can appear missing if you are storing its hardcoded path , which can change during app update. Try storing relative path and log the contents of your documents directory to see what files exist.
save the files in your local sqlite db, data core or if you can serialize them with the standard user defaults
My app have too much dynamic app resources like images, html+css and xml or json files..that can be updated, So I cannot put these resources in app bundle it will not get updated once on app store i need to have it updated there...secondly i also cannot put these resources on server where I can request the content from server every time i need it...
So my question is that is good to store data locally in document directory??? how does apple app review team will react to it? I have heard that there is an iCloud problem while putting data in document directory is it right?
So where to store data of iOS application locally on device?
Thanks in Advance.... Looking for some good solid answer!
This kind of data should be copied to ~/Library/Application Support. See the File System Programming Guide for full details on where everything goes and how it will be treated.
You may want to consider having the initial assets you are referring to be resident in your application bundle. And then when you have updated versions, save them in your Documents directory (or any legal path you want).
The reason for this is for failover, in case there is a problem, it allows you to revert back. When you are dynamically loading content, you have to factor in you can encounter various problems during a download such as corrupt data or even a dependency not being downloaded yet.
FWIW, I implemented this for a game that supported dynamic loading of content. The bundle had the original assets. There was a temp download directory. When data was validated, it was moved to a locale where it was consumable. On app start, the first step was to just copy the data from the bundle to the consumable directory. While it seems perhaps wasteful and several steps, it worked surprising well and most would not even know this sort of thing was happening.
I am working on a Vegetable gardening application. Apart from the vegetable name and description I also have vegetable image. Currently, I have all the images in the Supported Files folder in the Xcode project.
But later on I want to update the application dynamically without having the user download a new version. When the user updates the application or downloads new data from the server that data will include the images. Can I store those images in the supporting file folder or somewhere where they can be references by just the name.
RELATED QUESTION:
I will also allow the user to take pictures of their vegetables and then write notes about the vegetables like "just planted", "about to harvest" etc. What is the recommended approach for storing pictures/photos. I can always store them in the user's photo library and then store the reference in the local database and then fetch and display the picture using the reference. The problem with that approach might be that if the user accidentally deletes the picture from the library then it will no longer be displayed in my application.
The only way I see if to store the picture in the app local database as a BLOB.
No you can't put the downloaded images with the others inside the supporting file folder. Also I would suggest you put the images inside an Images or Resources folder instead... If you want to download any data after the app is compiled, then they will not be in the bundle. It is the bundle you are referring to when talking about the Supported Files folder in Xcode. This is read only for your application.
Just to be clear, once compiled, there are no folder structures for your application, these "folders" are just groups in the Xcode project to keep things tidy.
If you download say a zip file containing a set of images, it's up to you to write them to disk after you download them. You should put these images in either the tmp, the cache or the documents directory.
But then you'll have to build your path before loading the images. You won't be able to just provide the name of the file such as:
[UIImage imageNamed:#"something.jpg"];
Because this will look in your bundle. Instead you must do something like this to load your image from the Documents directory for example.
Your challenge is that you will end up in a state where you'll have some images in the Bundle (the ones from when you uploaded your app), and the newer ones in the documents directory. You must them check the bundle first and if there is no image there, check the documents directory.
For user generated data, I suggest also saving the images in the Documents directory, and maintaining an SQLite database of the users data, so you can map an image name to an entry in the database. You don't want to save the images as BLOB because this will inevitably slow down the performance of your queries and add extra unnecessary load on the CPU to convert to UIImage and back.
You don't want to save their images to the gallery for 2 reasons, first this means you'll be saving in 2 places because keeping a reference in your database to an external image is very fragile and you're just asking for trouble, and secondly, once the image isn't under your wing, you don't control it anymore, the user will delete it at some point, if they go back to your app they expect to see it there.
I currently have a large .sqlite data store of long string text. It's about 160MB and will grow to about 200MB when I'm completely done. This is a "read only" data set.
What I do now is simply place that file in my bundle and read it during runtime. However, that means the app requires you to download 160MB. Not optimal.
One solution is to gzip that file, ship the gzipped version in the bundle, uncompress it on first run, and put it in the Documents/ folder. This means you'd download far less, but the total size the app uses on the device is (size of gzip'd + size of ungzip'd) which is obviously not optimal either.
I want to use the gzip solution, but after application's first run, I want to delete the .gz version. Is this possible? How do I achieve it? What would another good solution be?
It is not possible to delete a file in the bundle. The app must be signed and if the bundle is modified in any way, it will not pass the signature.
The only other solution I can think of, is to setup a web service, and have your app download portions of your content as necessary. This may or may not be a viable solution, depending on what your app is actually doing.
As Paul says, anything in your bundle is part of the signature.
I can't see this changing as it is a fundamental part of signing apps.
The other classic approach is to compress the data in your bundle, as heavily as possible, so you unpack it when you build the working storage.