I've not found a answer to this question anywhere, but this seems like a typical problem:
I have in my "Resources" Folder a XML File that my App needs to show some informations. But I have to check in my Server, if the server has a newer XML available, so I should replace my XML (in the resources folder) for this new one.
How can I achieve that?
Thanks in advance for any help!
I'm not sure you get write access to the Resources section. A better way to do it, is to download the folder to your "Documents" directory. Then when you app checks to load the XML file, it should see if there is a version in the documents directory and load that first. If it doesn't find a replacement one, then it uses the original version.
This means the original XML file can be used if there is some issue with the downloaded one. Which happens, either the network got cutoff and didn't finish, or the server gave the wrong xml file and it doesn't validate.
You can access the document directory using:
NSArray *docPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *destinationpath = [docPaths lastObject];
If you are wanting to check the versions, you can use an element inside the XML to give you the version number or you can use the Last-Modified date. An example of the version could be:
<myxml version="234">
Then you could check this value.
You can let the API, a method to check The most recent modified date. And in the client site, you can get your most recent modified date of the XML file and compare with the one in the server. You can get the description of the XML file and return true or false to replace.
U need some way to distinguish the new XML from the old one. I assume you have some mechanism to do that. Typically some kind of Version node inside the XML.
If the server's version and the one on ur phone is different, get the new one else don't do anything.
Related
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.
I have an app that when first launched reads in its data from a local XML file and is then archived for subsequent loads.
In future app updates its envisioned that this XML file might be updated with more data. To determine if I should re-load the XML data I have placed a custom key/value (a version number for the XML file) in the info.plist.
Now when I update the version number from 1.0 to 1.1 in the plist file, the app still reads it as 1.0. I'm guessing there is some kind of caching going on. Is there a way I can get the updated version on each load?
NSDictionary* infoDict = [[NSBundle mainBundle] infoDictionary];
NSString* version = [infoDict objectForKey:#"IdeasVersionNumber"];
NSLog(#"version = %#",version); // always 1.0?!!
Is there a better method to do this? I didn't want to create a separate plist/XML file just to hold the version number as it seems like a waste of resources to load/parse these each time when the info.plist is always read.
Many thanks for any advice.
I am surprised by this behavior, but as it looks like the Info.plist is not always read, you might as well make a separate file for it. Or use NSUserDefaults.
A simple clean build did the trick! Thanks to #MCannon for the tip. I should have copped onto it.
i make a localized iphone application and in run time i want to modify the property list, so i at the first run of the application i copied the plist file but i don't sure if the copy operation also copied the localized version which the system store in a folder like: lp.fr
my quetion is: what i must do for the system to recognise the two files? should i make two directory in documents folder like lp.en and lp.fr and copy the two files?
also also xcode make the two plist with the same name, how i can determine every version and copy it?
i am waiting for some one to direct me to write way.
thanks
Take a look at NSBundle's pathForResource:ofType. It clearly states that it will return a non localized file if it exists or else pick a file in the order of user's language preferences. As you wan't to copy a localized resource, don't create a non localized copy and this will return the path for the most suitable resource. You can just copy that file and make changes to it.
If you are interested in getting the path to a resource of a specific language, take a look at pathForResource:ofType:inDirectory:forLocalization.
I would like to save a file downloaded from the internet in iPhone.
Can I use the url as the file name? If not, what transformation should I apply to the url to obtain a valid file name?
I need to find the local copy of the file later using its url.
Edit: Not asking where or how to write a file to disk. The question is limited to getting a valid file name from an url.
Can I use the url as the file name?
You can use just about anything you want for a file name. As long as it's a valid file name for the underlying file system.
If
not, what transformation should I
apply to the url to obtain a valid
file name?
This is unanswerable because there's no way to specify what "valid" means here.
I need to find the local copy of the
file later using its url.
You probably want to save it to your application's Documents directory. There already are plenty of questions relating to saving files on iPhone here on Stack Overflow, and I urge you to read some of them.
For lack of a better method, I'm using a persistent dictionary to map the urls to unique names.
Hi all what i want to do is to download plist from server http:// and i'd like to know how and where it is stored.
Can the iphone compare date from 2 plist files ? ?
thanks to all, if you do not want to post code or explain please link it. !Because i'm really stuck and need help
thanks
If you're downloading the file, you can use the Last-Modified header in the (e.g.) NSHTTPURLResponse object to determine if the file has been modified on the server since it was last modified locally. Use the -compare: method on two NSDate objects (one parsed from the header, one obtained from the local file system) to determine which is later.