Compiling an XML file into a binary - iphone

I want to parse and XML file in an iPhone app without going to disk for it.
Can I do this? How? I have included a TXT helpfile in an app using MSVC.
I put the XML file in a Folder/Group named Resources in the project.
I have the XML file in the proj directory.
I right clicked on Resources folder and selected add -> Existing File.
I right-click on the XML file and select GetInfo.
There I have tried altering the Path Type {Absolute, Relative to Project , etc}
My program runs fine on the simulator when I use:
NSString * const DG_XmlRecipeFile = #"/Users/appleuser/Cocoa/iHungry6/Recipes.xml";
It seems to me it should also work with:
NSString * const DG_XmlRecipeFile = #"Recipes.xml";
If I set the Path Type correctly. It does not.
I am a first timer. Thanks for reading this , Mark

Xcode copies the project resources to the app bundle. You can access your file within your bundle as follows:
NSString *DG_XmlRecipeFile = [[NSBundle mainBundle] pathForResource:#"Recipes" ofType:#".xml"];
Files in the bundle are read-only. If you want to modify the file you will need to copy it somewhere that you can modify it. Your app's Documents directory works well for this.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDirectory = [[paths objectAtIndex:0] retain];
NSString *newFilePath = [docsDirectory stringByAppendingPathComponent:#"Recipes.xml"];
NSError *error = nil;
[[NSFileManager defaultManager] copyItemAtPath:DG_XmlRecipeFile toPath:newFilePath error:&error];

I don't think the path type you are referring to is the path to the resource within the app bundle that is produced. It is how the file should be referenced within the .proj file.

Related

iOS : NSString file path to NSURL

I have this :
NSURL *url = [NSURL fileURLWithPath:#"/Users/myusername/Library/Application Support/iPhone Simulator/4.2/Applications/5ABF1395-4A80-46C0-BD4A-419ED98CE367/Documents/DBV/v.m4v"];
Then I launch movieViewController but it always crashes.. This code doesn't work on the iPhone simulator neither on the device... How can I fix it ?
EDIT :
Before to write file path by hand, I used the correct way to select a folder.
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]
Then i got this log:
file://localhost/Users/myusername/Library/Application%20Support/iPhone%20Simulat‌​or/4.2/Applications/5ABF1395-4A80-46C0-BD4A-419ED98CE367/Documents/DBV/v.m4v
Then I thought it was because of spaces in folder name , so i decided to write the full path by hand for debugging (replacing each %20 by space)
EDIT 2 : Notice : I'm trying to access a dynamically created file in Documents folder, not a file from my bundle.
For files in documents, you should be getting the path from NSSearchPathForDirectoriesInDomains.
//get list of document directories in sandbox
NSArray *documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//get one and only document directory from that list
NSString *documentDirectory = [documentDirectories objectAtIndex: 0];
Then you append the file name to that.

How to download file and save in local iphone application?

I have locally saved one xml file and showing the details by using NSXmlParser(Which is stored in Resource folder). But, now i want to download new xml from url(from client side) and need to store that new xml file in local and also need to delete existing one from the application. How can i do this? Any suggestions? There is any sample code/project for reference? Please help me. Thanks for reading my poor english. Thanks is advance.
although u can delete file from yr resource directory and save new one but the my way is to perform file operation mostly on app diretories like document directory or cache directory.
first u will to save yr xml file from app resource to cache directory then access file from there.And u can also remove file from resource directory ,its no longer needed.
any new file available in internet then first remove old one from cache and add new one to cache directory.
whole thing is as follows:-
//get your cachedirectory path
NSArray *imagepaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachdirectory = [[NSString alloc] initWithString:[imagepaths objectAtIndex:0]];
//first save your file from resource directory to app's cache directory
NSString * path = [[NSBundle mainBundle] pathForResource:#"fileinresource" ofType:#"xml"];
NSData *filedata = [NSData dataWithContentsOfFile:path];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *savename = [cachdirectory stringByAppendingPathComponent:#"mynewfile.xml"];
[fileManager createFileAtPath:savename contents:filedata attributes:nil];
//remove file from resource directory
[fileManager removeItemAtPath:path error:nil];
//new file from internet is avilable then do following:first remove old file from cache
[fileManager removeItemAtPath:cachdirectory error:nil];
//save new file from internet
NSData *newfiledata=[NSData dataWithContentsOfURL:[NSURL URLWithString:myxmlurlstringpath]];
[fileManager createFileAtPath:savename contents:newfiledata attributes:nil];

iOS - Can I modify a property list file live in iPhone?

I have a property list file which gets to the bundle when I build my program. Now, I would like to be to modify it with my Mac and get it updated while my program is running. I guess bundling the file is not the correct approach, as I do not seem to have any access to the contents of the bundle after it has been built.
How should I approach? It would be nice to work at least with the iPhone simulator but it would be veeery nice to work with the device too.
Your application bundle is signed, so it can not be modified after it is created/signed.
In order to modify the plist, you need to copy it to the Documents directory for your application first. You can then modify the copy. Here is a method that I have in one of my apps that copies a file called FavoriteUsers.plist from the bundle to the documents directory during app start up.
/* Copies the FavoritesUsers.plist file to the Documents directory
* if the file hasn't already been copied there
*/
+ (void)moveFavoritesToDocumentsDir
{
/* get the path to save the favorites */
NSString *favoritesPath = [self favoritesPath];
/* check to see if there is already a file saved at the favoritesPath
* if not, copy the default FavoriteUsers.plist to the favoritesPath
*/
NSFileManager *fileManager = [NSFileManager defaultManager];
if(![fileManager fileExistsAtPath:favoritesPath])
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"FavoriteUsers" ofType:#"plist"];
NSArray *favoriteUsersArray = [NSArray arrayWithContentsOfFile:path];
[favoriteUsersArray writeToFile:favoritesPath atomically:YES];
}
}
/* Returns the string representation of the path to
* the FavoriteUsers.plist file
*/
+ (NSString *)favoritesPath
{
/* get the path for the Documents directory */
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
/* append the path component for the FavoriteUsers.plist */
NSString *favoritesPath = [documentsPath stringByAppendingPathComponent:#"FavoriteUsers.plist"];
return favoritesPath;
}
Sort of. You have read-only access to the bundle, so what you need to do is copy over the plist from your bundle into your app's documents folder.
The documents folder is an area of your application's sandbox where you can read and write to files. So if you copy the plist there upon the very first launch of your app, you'll be able to edit and modify it to your heart's content.
There's a tutorial somebody wrote online that basically answers your exact question, so rather than try to do my own explanation here's a much better one!
http://iphonebyradix.blogspot.com/2011/03/read-and-write-data-from-plist-file.html

Simplest way on iPhone to unzip downloaded file?

Goal: download a zipped file, unzip it, and save it in the iPhone app's Documents directory.
The following code makes use of the initWithGzippedData method that was added to NSData in the Molecule app found here:
http://www.sunsetlakesoftware.com/molecules
As adapted to my app:
NSString *sFolder = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents"];
NSString *sFileName = [sFolder stringByAppendingPathComponent:#"MyFile.db"];
NSURL *oURL = [NSURL URLWithString: #"http://www.isystant.com/Files/MyFile.zip"];
NSData *oZipData = [NSData dataWithContentsOfURL: oURL];
NSData *oData = [[NSData alloc] initWithGzippedData:oZipData];
[oZipData release];
b = [oData writeToFile:sFileName atomically:NO];
NSLog(#"Unzip %i", b);
Result: A zip file is successfully downloaded. From it a new, supposedly unzipped file is created in the Documents directory with the desired name (MyFile.db) but it has zero bytes.
Anybody see the problem? Or else is there a simpler way to unzip a downloaded file than the one used in the Molecules app?
I think that your problem may be that you are attempting to gzip-deflate a Zip file. Those are two different compression algorithms.
I based the gzip-deflating code in Molecules on this NSData category (the code of which I've copied into this answer) provided by the contributors to the CocoaDev wiki. What you'll want to do is use their -zlibDeflate implementation, which should properly unzip a Zip file.
Unrelated to your problem, instead of using NSHomeDirectory() and appending a path component, the recommended approach for finding the documents directory is the following:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
You should make sure your file is never too big, as you are loading it fully into memory before the unzip starts.

How can i change sqlite ReadOnly to ReadWrite on the iPhone?

i deployed my App to my iPhone and get
Unknown error calling sqlite3_step (8: attempt to write a readonly database) eu
on Insert / Update Statements.
On the Simulator it all works like it should.
My sqlite Database is placed in the Resource Folder (Xcode).
Thanks for help!
Your application bundle is not writable on the iPhone. You MUST copy the file somewhere else, like your documents folder. It works in the simulator because the Mac does not enforce all the sandboxing restrictions the iPhone does.
You can copy your database from the application bundle directory to the Documents directory in viewDidLoad. You can read/write from/to your database in the Documents directory after this. Of course, you need to check if the database in the Documents directory exist before you do the copy in order not to overwrite it the next time you bring up the app.
Assuming you have defined your database name '#define kFilename #"yourdatabase.db"' in the .m file.
In viewDidLoad add:
// Get the path to the main bundle resource directory.
NSString *pathsToReources = [[NSBundle mainBundle] resourcePath];
NSString *yourOriginalDatabasePath = [pathsToResources stringByAppendingPathComponent:kFilename];
// Create the path to the database in the Documents directory.
NSArray *pathsToDocuments = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [pathsToDocuments objectAtIndex:0];
NSString *yourNewDatabasePath = [documentsDirectory stringByAppendingPathComponent:kFilename];
if (![[NSFileManager defaultManager] isReadableFileAtPath:yourNewDatabasePath]) {
if ([[NSFileManager defaultManager] copyItemAtPath:yourOriginalDatabasePath toPath:yourNewDatabasePath error:NULL] != YES)
NSAssert2(0, #"Fail to copy database from %# to %#", yourOriginalDatabasePath, yourNewDatabasePath);
}
Good luck!
aobs