I am building a internationalized app on iOS, where the app suppose to download a few images from the server (say 01.png, 02.png, 03.png, 04.png, where 01 and 03 are the English version of 2 images, and 02 and 04 are the Chinese version of 2 images).
I know how to set internationalization locally (naming both files to the same name, and put one to en.lproj folder and the other one to zh-Hant.lproj folder).
I'm just wondering is there a better way to do this programatically?
or I'll have to programatically download from server -> put files in their language dependend server-> rename ?
P.S. I do not have control of the server, so renaming files from server will not be an option. those image files are shared between iOS and Android devices. (I know Android append language and resolution specific text to the file name)
You need to manage the download and usage of these files yourself. The standard localisation system is based upon resources which are part of the main bundle. You (broadly speaking) have 2 options:
Download the individual files, name them and store them in the cache folder (probably not the documents folder as this content doesn't need to be backed up), load them yourself as required by referring to the appropriate name.
Download a prepared bundle which contains the strings and images you want to use for the localised app. Use a combination of NSLocalizedStringFromTableInBundle and a custom implementation similar to imageNamed: (throughout your app) so you can obtain resources from the specified bundle.
You need to mediate between content in the main bundle and your additional storage.
Related
I want to be able to update localized strings by code from the app. What I actually want to do is to make changes to the localization on a server and then let the iPhone application fetch updated localization strings from a server and then save them to the localizable.strings file.
You can't ! Those files are part of the bundle and can't be updated. You will have to setup the whole translation framework by yourself (which is not that much work) and implement caching using either core data or serialized dictionaries (one for each language I suppose).
You won't be able to modify the Localizable.strings file in your app bundle because the app bundle is read-only on iOS devices. To grab localized strings from a strings file in your app's Library directory, you could programmatically create a bundle at that location, put a Localizable.strings file in it and then grab the localized strings with NSLocalizedStringFromTableInBundle(). (I haven't tried this but it should work.)
There's service (Get Localization) that allows you to upload those .strings files to server and fetch them via API. However there's no client for iPhone yet but it would be quite simple to do. You can contribute one or then wait that there's official available.
I have a data file that I need to include with my app when I distribute it. When loading any files in the app, I prefix the file name with:
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
This works great for anything I create within the app (and for reading back), like files I download in response to a user action. But I can't for the life of me figure out how to place files there when I build my app in Visual Studio.
I've tried making a "Documents" subdirectory in the special "Resources" folder, but that didn't work (I tried setting the "Build Action" to both BundleResource and Content). When I look at the folder for my app (from using the simulator) I can see that in the "Documents" folder there's all the files I downloaded, but I can't find my data file that I'm trying to bundle ahead of time. I even searched my entire hard drive on the Mac and still couldn't find said data file.
The data file isn't an image, if it matters. Just raw binary data. How do I set it up so that this file goes into the proper documents directory at compile time, so that I can read it using the SpecialFolder.MyDocuments prefix? Thanks.
You can't. You can include files in your app bundle, and then at startup copy them from the bundle into a user folder. But this won't happen automatically.
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).
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 have a plist in my Resources folder that I'm using to store conversion information. I'd like to give the user the ability to "turn off" certain units so that those units will never be used in conversions. I don't want to have to maintain two lists with the conversion information in it.
I am able to save data back to that plist file in the stimulator. (using writeToFile and the pathForResource). I'm wondering if this is a problematic approach.
Will there be an issues with this on deployment? (i.e. will Apple seal the plist)
What will happen if I push out an upgrade? What if that upgrade contains new units added to the list?
Would doing something like copying the plist to the user's documents directory make sense?
It is not possible to change the app bundle. Further the app is signed. Instead copy the plist to the documents directory on first start and access from there.
No whatever is in the application bundle is offlimit has the DRM on iPhone needs it to stay the same. You should save your preferences in the Apllication Document folder or Preference folder.
Use an iOS Settings Bundle...