Loading data files in iPhone project - iphone

How does one read a data file in an iPhone project? For example, lets say I have a static file called "level.dat" that is structured as follows:
obstacles: 10
time: 100
obstacle1: 10,20
...
I would like to read the contents of the file into a NSString then do the parsing. How do I read the contents of a file into a string? Also, where in the project should the "level.dat" file reside? Should it be under "Resources" or just in the main directory?
Thanks in advance!

See this answer: How to fopen() on the iPhone? which shows how to get access to resources in your bundle. Once you have the path, just use [NSString stringWithContentsOfFile:encoding:error:].
NSString *path = [[NSBundle mainBundle] pathForResource: #"level" ofType: #"dat"]
NSError *error = nil;
NSString *data = [NSString stringWithContentsOfFile: path
encoding: NSUTF8StringEncoding
error: &error];

While this isn't what you asked for, consider turning your files into plists. You will have to reformat them into XML, but then you can load them straight into a NSDictionary with:
dict = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"levels" ofType:#"plist"]];

Have you considered putting the data in an SQLite database instead of a flat file? I find that the API is very easy to use on the iPhone.
It is how I do all of my data storage on the phone now.

If you need help parsing the data string, there's a helpful article on Cocoa For Scientist

Related

Can't parse json Data via YAJLiOS

At first i'm trying to access local file in my app folder:
NSData *data = [NSData dataWithContentsOfFile:
[#"countries.json" stringByExpandingTildeInPath]];
result is always NULL
then i tried to check is file exists:
NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString* foofile = [documentsPath stringByAppendingPathComponent:#"countries.json"];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:foofile];
it doesn't exist, and i use following code to access my json file:
NSString *data1 = [[NSBundle mainBundle] pathForResource:#"countries" ofType:#"json"];
NSData *data2 = [[NSData alloc] initWithContentsOfFile:data1];
it getting the file but when i try to parse it:
NSDictionary *dict1 =[data2 yajl_JSON];
i getting an error:
[NSConcreteData yajl_JSON]: unrecognized selector sent to instance 0x6838d60
My questions is next:
Is there any chance to convert NSData to NSConcreteData?
Am i using the right approach to access data?
Api documentation - http://gabriel.github.com/yajl-objc/
Screenshot of my Xcode Build Phases:
According to the YAJL documentation the method you are trying to invoke does in fact exist.
That leaves only one option; you have not fully linked against the YAJL framework.
Make sure it shows up within the list of linked frameworks/libraries of your App target just like CFNetwork.framework shows up in my example.
Since the method you are trying to invoke is in fact part of a category on NSData, make sure you include -ObjC in your Other Linker Flags.
From Apple's Technical Q&A.
This flag causes the linker to load every object file in the library
that defines an Objective-C class or category. While this option will
typically result in a larger executable (due to additional object code
loaded into the application), it will allow the successful creation of
effective Objective-C static libraries that contain categories on
existing classes.

NSKeyedUnarchiver: iPhone .v. Simulator

I'm doing:
NSString *current_path = [[NSBundle mainBundle] bundlePath];
NSString *string_path = [NSString stringWithFormat:
#"%#/filedstring", current_path];
my_string_ = [[NSKeyedUnarchiver unarchiveObjectWithFile:string_path] retain];
The archived string is the text from a UITextField which we unarchive here. I've tried with and without current_path.
This all works fine when running in simulator (class member NSString *my_string_ is not nil) but when run on my iPhone my_string_ is nil.
Why is that?
Thanks for the quick responses all.
Adding to Jason Coco's answer, archive to and unarchive here:
NSString *library_path = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,
NSUserDomainMask, YES) objectAtIndex:0];
NSString *username_path = [library_path
stringByAppendingPathComponent:#"Caches/filedstring"];
You can't write into the main bundle on the phone, it's not allowed. That's why you don't find your archive there later. The simulator, since it actually runs on Mac OS X doesn't work this way, so it will actually write the file.
If you need to write something, you have to use one of the writeable paths available to your application. For more information, see the iOS Application Programming Guide / The File System. If you're going to do iOS Application Development, you should definitely read and understand this entire document.
As #middaparka says, there is probably something wrong with that file. Here's how I would debug this problem:
First step,
[[NSFileManager defaultManager] fileExistsAtPath: string_path];
Second step,
NSError *err;
NSString *tmp = [NSString stringWithContentsOfFile:string_path encoding:NSUTF8StringEncoding error:&err];
NSLog(#"Contents of string %#",tmp);
Once you've done those, you should have a much clearer idea why your NSKeyedUnarchiver is failing.
Also, check out NSString's stringByAppendingPathComponent: method.

can i update my local text file on iphone

i have a text file so can i update this text file from web ???
lets say i have
1. NSString *filePath = [[NSBundle mainBundle] pathForResource:#"MyFile" ofType:#"txt"];
2. NSData *myData = [NSData dataWithContentsOfFile:filePath];
3. if (myData) {
4. // do something useful
5. }
right now Myfile.text is having 10 data so how to insert 10 more to this data??
plz help
Files stored inside your app bundle will not be writable.
You will have to make a copy of the file and store it in the Documents or Library folder before you will be able to edit it.

How can I locally save an XML file on an iPhone for when the device is offline?

My app is accessing data from a remote XML file. I have no issues receiving and parsing the data. However, I'd like to take the most current XML data and store it locally so - in the event that the user's internet service isn't available - the local data from the previous load is used.
Is there a simple way to do this? Or am I going to have to create an algorithm that will create a plist as the xml data is parsed? That seems rather tedious... I was wondering if there was an easier way to save the data as a whole.
Thanks in advance!
I don't know what format your XML data is in as you receive it, but using NSData might be helpful here, because it has very easy-to-use methods for reading/writing data from either a URL or a pathname.
For example:
NSURL *url = [NSURL URLWithString:#"http://www.fubar.com/sample.xml"];
NSData *data = [NSData dataWithContentsOfURL:url]; // Load XML data from web
// construct path within our documents directory
NSString *applicationDocumentsDir =
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *storePath = [applicationDocumentsDir stringByAppendingPathComponent:#"sample.xml"];
// write to file atomically (using temp file)
[data writeToFile:storePath atomically:TRUE];
You can also easily convert an NSData object to/from a raw buffer (pointer/length) in memory, so if your data is already downloaded you might do:
NSData *data = [NSData dataWithBytes:ptr length:len]; // Load XML data from memory
// ... continue as above, to write the NSData object to file in Documents dir

read single line from text file in objective-C

i'm new to iPhone programming and coding in XCode SDK.I want to access and read the configuration file which i have placed in Resource folder in XCode,my configuration file looks like this
#key=value$
#vinu=flower$
#cathy=fruit$
I want to compare the key and access the value from configuration file.
Since i'm working with iPhone OS, i cant use NSWorkspace.Hence i'm using NSFileHandle.
This is how my code looks like,
NSString *path = [[NSBundle mainBundle] pathForResource:#"configuration" ofType:#"txt"];
NSFileHandle *readHandle = [NSFileHandle fileHandleForReadingAtPath:path];
NSString *txtString = [[NSString alloc] initWithData:
[readHandle readDataToEndOfFile] encoding:NSUTF8StringEncoding];
please let me know is the procedure correct, and how to proceed. ??
Thank You.
Do yourself a favor and save it as a plist, and not a straight text file.
However, if you need to read it in like that, the simplest way is to read it into a string and then go from there, ie:
NSString * fileContents = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
If the file is super large and the only reasonable way to read it is line-by-line, then you can quickly see that this is something that has come up before (Particularly: Objective-C: Reading a file line by line).