How to download and update local images under monotouch app - ios

I have a question regarding how to update local images embedded as content in the application.
My application is built using 30 images stored as "Content" (embedded in the app) for a image gallery that I have to show. Every 2 days the application check server info to see if the images have been changed in the database, in that case then I have to compare files and if any file has changed then I have to download it and update the local image.
I have read the the best way to store images for this kind of porposses is under "Library" folder of the application, but the images that comes with the app are built as "Content" (embedded)...
Any clue on the best way to do that in monotouch?
Thanks.

Resources, like images, that you bundle inside your .app becomes part of your application. Since the application is signed you cannot update (or remove) those files as it would invalidate the signature (there's also file permissions that won't allow this to happen).
note: it can work in the iOS simulator since it does not require (or check) for application signatures, however it won't works for application on devices.
What you can do is:
Bundle default images with your applications;
Download new images (when needed) and install them outside your application (in the appropriate directory);
Have your application checks if there are downloaded images (or if images needs to be downloaded) and fallback to the images that ships with your application;

You can't change any file from your app (they're read-only).
What you can do is to save the files to a read-write directory, and at runtime check if those images are there (and not then use the ones bundled with the app).

Related

In Unity3D for iOS when loading on demand resources, how can I check the latest version is already loaded and if not, what is the download size?

I've recently transitioned my iOS Unity app to use asset bundles as on demand resources. This all works great! The only problem is that when the application first starts up and all the ODRs are preloaded it just starts to download them from the apple servers. I need to know before preloading them if they require downloading and if so, how big of a download. I need this info to show a prompt for the user to let them know that additional data needs to be downloaded and maybe turn on their wifi etc.
If you are using WWW class then there is this WWW.LoadFromCacheOrDownload, this function takes in a version parameter which you can probably use for checking on versions.
If you are using UnityWebRequest, then maybe you can use the meta files which get generated with asset bundle and then download it and read version or a hash (You will probably have to google a little bit on this what to use) to actually look if you have a version change and do you need to download new version or not.
If none of the above suits you then the hard coded way would be to setup a list of your asset bundles with your versions on a webserver and download it to match it with your local version everytime you start the app.
I hope this atleast helps you look in the correct direction.
I've managed to do this myself in the end. My current setup is the following:
I have a bunch of assetbundles marked as On Demand Resources.
When I build the assetbundles I save a file containing the CRC and file sizes of all these bundles and I save it in StreamingAssets to always have it available
Whenever the app starts up, I try to load the assetbundles from PersistentDataPath against their latest CRC (at first launch there will be no bundles there)
If any bundles are missing or have invalid CRC, show a prompt to the user that x MB of data needs to be downloaded (taken from the file made at build time)
After the ODR resources are downloaded, I reencrypt the assetbundle from res:// (the only way I could access it) and move it to PersistentDataPath
Whenever a new updated comes it, it should contain new CRCs for the changed bundles and the process should restart
It seems to work quite well. The only real issues that I have is that I currently don't know how to delete the downloaded ODR data, and there could be a version mismatch if a user installs the app and defers downloading the extra data, and only opts to do so when an updated version of the app (with different bundle CRCs) is available on the server but they still stay on the older version. This would probabily load the new bundles but will fail the CRC checks for them...

Updating iOS application content which include images

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.

Protect Images inside my app from copying

I have an app that uses copyrighted images that I have permission to use. If a user downloads my app onto their computer using iTunes, they can basically unzip the app file (change filename to add .zip, unzip then show package contents), and see the images.
Is there a way to prevent this? Or am I wrong about this?
To the best of my knowledge there is no way to stop this method of accessing the images; the only alternative I can think of is to encrypt the images and store the encrypted files in the app. Then decrypt the images at runtime.
This won't stop the most determined adversary but would stop people accessing the images without some effort on their part.
A determined adversary will likely be able to get at any files used by an app on a device in their possession.
To defeat a lazy adversary, you might only have to change the file names into something they won't recognize as an image file. Or change a few bytes containing the file type signature at the beginning of each file, rendering the file corrupt. Your app can copy them into a temp file and fix the signatures to display.
Apple reportedly encrypts an App store distributed app's compiled C code. So another possibility might be to embed (portions of) the copyrighted images as hex data inside your source code.

deploying app separately from data on iPad

I'm working on an iPad app which is deployed manually from iTunes. The app requires a large amount of data (videos). The data is static, the app is being developed. It is inconvenient to deploy all the data each time the app is deployed.
What are my options to deploy the application itself separately from the data?
Use iOS file sharing to get the files into the Documents directory for your app. The documents directory will be preserved across upgrades as you develop the app, so you only have to copy it once.
If there's a lot of files, you can copy a zip file instead and unpack it on the first run of your app using SSZipArchive.
Another option would be to stick the data on a web server and retrieve it on the first run, again storing it in the Documents directory.
If you want to use any of these approaches in your final deployed app, be sure to make the files so that they're not backed up to iCloud.

Where in the filesystem do I store app's data files?

I need to store some data files for my blackberry app. These are usually small png files that I download and store locally for performance reasons. Also I need to store an xml file locally.
My question is where are these files supposed to be saved on a blackberry? Is there such a thing as an application's home folder or settings folder in the blackberry filesystem?
What would be the path to such a folder?
This is for blackberry os 4.7 or later.
Thanks!
If it's not a huge amount of data (and by the sounds of it, it's not), take a look at the PersistentStore mechanism. You can store many types of data including native types (String, Integer, etc.) and even byte[] data (for images) using PersistentContent. The nice thing about PersistentStore is that it doesn't require any sort of filesystem access -- it doesn't leave files hanging around -- and if you include a custom class in the persistent store for your app (even a simple subclass of an existing persistible class such as Hashtable), it will automatically delete your persisted data if the app is deleted.
There's no official home folder for your application. In blackberry you can basically read/write just about anything/anywhere (well, you might get a SecurityException/IOException if you'll try do change some files).
You can write to the SDCard/Internal memory using the paths described here.
If you're worried about someone seeing and altering your data there's not much you can do except setting your files and directories as hidden using FileConnection.setHidden(true) but this is very lame since they can still be seen even from the native BlackBerry file browser if the user chooses to show hidden files from the menu.
Edit: You could of course encrypt/decrypt your data but this won't prevent someone from deleting it.

Resources