Reading and displaying simple text from text file - iphone

I am fairly new to iphone development and programming in general and am wondering how to read some text from a text file to be diplayed in a UITextView. I have tried various ways to do it but just can't seem to be able to get it to display:
- (void)viewDidLoad {
[super viewDidLoad];
NSString *filePath=[[NSBundle mainBundle] pathForResource:#"untitled" ofType:#"txt"];
NSString *someText=[NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
textView.text=someText;
Some sample code would be greatly appreciated. Thanks in advance

You shouldn't include the extension in the pathForResource: parameter:
[[NSBundle mainBundle] pathForResource:#"untitled.txt" ofType:#"txt"]
should be
[[NSBundle mainBundle] pathForResource:#"untitled" ofType:#"txt"].

I had to change the name of the text file to 'untitled.txt' from just plain 'untitled' in Xcode. It was a text file but didn't have the extension of .txt. This doesn't seem to be automatically appended if you create the text file in Xcode.

Is untitled.txt actually where you think it is? Try logging filePath and see if it's what you expect. (You could do [[NSFileManager defaultManager] isReadableFileAtPath:filePath] to be completely certain.)
If the path is correct then the problem must be with loading the text. One such problem could be that the file is not encoded in UTF8. Mike Ash recently blogged about character encoding. At the end of the post he describes how to handle text files of unknown encoding.

Related

How to find path to localized directory?

I need to distribute a directory containing html files and images with my app.
The app has support for different languages. I have created a directory for each language and then pick the right one based on current locale:
NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0];
NSString *path = [[NSBundle mainBundle] pathForResource:#"index"
ofType:#"html"
inDirectory:[language stringByAppendingPathExtension:#"html"];];
if (![[NSFileManager defaultManager] fileExistsAtPath:path])
{
// Fallback to english
path = [[NSBundle mainBundle] pathForResource:#"index"
ofType:#"html"
inDirectory:#"en.html"];
}
How can I better deal with this instead of having to do the above (which is a bit messy)?
I'm thinking perhaps using the xx.lproj directories for this somehow and putting a localized html directory in each xx.lproj directory and use NSBundle pathForResource to find the correct file. Couldn't get it to work though.
Using the xx.lproj folders with [NSBundle pathForResource:ofType:] is straight-forward.
You can add index.html to your Xcode's project file and then make it localizable from its "Get Info" window. Add another language like "de", and Xcode will copy index.html into the newly created de.lproj. If you remove that file, the app will fall back on the English version.
You can test it with logging:
NSLog([[NSBundle mainBundle] pathForResource:#"index" ofType:#"html"]);
I too am unable to get this to work:
NSLog([[NSBundle mainBundle] pathForResource:#"index" ofType:#"html"]);
But this does, using the standard Xcode language.lproj structure (e.g., en.lproj):
NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0];
NSString *htmlPath = [[NSBundle mainBundle] pathForResource:#"index"
ofType:#"html"
inDirectory:[language stringByAppendingPathExtension:#"lproj"]];
also removed extra ; in Martin's original question above ...
Extra tip: make sure that you remove the unlocalized versions of the files in your built product, otherwise pathForResource will find those files instead of the localized ones.
Why not the forLocalization way:
htmlFile = [[NSBundle mainBundle] pathForResource:#"myContent"
ofType:#"html"
inDirectory:#"de.lproj"
forLocalization:#"de"];
This works fine here with Xcode 5.1.1 and iOS 7.1
Add the generalization of #Martin Wickman (with the fallback) and everything should be great.
You could use this:
NSString *filename = [NSString stringWithFormat:#"html_%#.html", NSLocalizedString(#"abbr", #"")];

NSBundle returns nil

I wanted to read version information of my application from the plit file.
For this I am using a code as shown below.
NSString *myFilePath = [[NSBundle mainBundle]
pathForResource:#"MyApp-Info"
ofType:#"plist"];
// Format output
NSLog(#"%#",myFilePath);
The output
2010-08-31 17:14:10.095 MyApp[8759:20b] (null)
It always returns nil even if I tried to Import an existing file of type, text.txt still return nil, where text.txt is imported in the application.
I have goggled for the problem dont every one recommends to use NSBundel to read an pre imported file, but no use.
Any help, or an better way to read application version.
Got the solution via another link in the stack overflow here.
NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleVersion"];
NSLog(#"%#",version);
The reason this doesn't work is because pathForResource looks for stuff inside "MyApp.app/Contents/Resources". The Info.plist file does not reside inside the resources folder, so it's going to return nil if you look for it there. The correct way to get at it is to use the "infoDictionary" method on NSBundle.

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).

How to display the current project version of my App to the user?

I would like to add the current version into the "about" section of my app.
As seen in this attached screenshot Apple offers versioning.
How do you display these settings in your app?
After further searching and testing, I found the solution myself.
NSDictionary* infoDictionary = [[NSBundle mainBundle] infoDictionary];
NSLog(#"%i Keys: %#", [infoDictionary count],
[[infoDictionary allKeys] componentsJoinedByString: #" ,"]);
This snipplet gave me the following output:
20 Keys : NSBundleResolvedPath ,CFBundleVersion ,NSBundleInitialPath ,CFBundleIdentifier ,NSMainNibFile ,CFBundleIconFile ,CFBundleInfoPlistURL ,CFBundleExecutable ,DTSDKName ,UIStatusBarStyle ,CFBundleDevelopmentRegion ,DTPlatformName ,CFBundleInfoDictionaryVersion ,CFBundleSupportedPlatforms ,CFBundleExecutablePath ,CFBundleDisplayName ,LSRequiresIPhoneOS ,CFBundlePackageType ,CFBundleSignature ,CFBundleName
So the solution is as simple as:
NSString *version =[[[NSBundle mainBundle] infoDictionary] valueForKey:#"CFBundleVersion"];
However, this is not the Current Project Version as seen in the screenshot but the Bundle Version of the plist file.
Look into your Info.plist file which should have keys like CFBundleVersion and CFBundleShortVersionString
Those items in the Build Info are not available to your built app. They are placeholders that you could possibly pull into your app. What is in your app is anything that you place in, say, the Resources folder of your app, like any text files, or plists, or a nice picture of your versioning engineer.
Now, you could pull some of the items in the Build Info window into a info.plist, using special identifiers, such as ${VERSION_INFO_PREFIX} or other token. The tokens are available if you click on any of the items on the left hand side in the window you have included above. For example, click on the word "Current Project Version" and copy the token that you see at the bottom, "CURRENT_PROJECT_VERSION". Then go to your plist file, and add an entry. Give it any name you want or "Current Project Version". Paste in ${CURRENT_PROJECT_VERSION} on the right hand side. Now that value is available to you from your app, programmatically. Of course, someone now has to enter that value into the appropriate place either in the Build Info window or elsewhere. It might just be easier just to manage this and fields like this in the info.plist file. It's up to you how you'd like to handle these things.
Here is how I get version info out of my info.plist:
+ (NSString *) getAppVersionNumber;
{
NSString *myVersion,
*buildNum,
*versText;
myVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleShortVersionString"];
buildNum = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleVersionKey];
if (myVersion) {
if (buildNum)
versText = [NSString stringWithFormat:#"Version: %# (%#)", myVersion, buildNum];
else
versText = [NSString stringWithFormat:#"Version: %#", myVersion];
}
else if (buildNum)
versText = [NSString stringWithFormat:#"Version: %#", buildNum];
NSLog(versText);
return versText;
}
NSString *currentVersion = [[[NSBundle mainBundle] infoDictionary] valueForKey:#"CFBundleVersion"];
returns me always the same value(initial version) even if i change the version from the project settings but.
NSString * appVersionString = [[NSBundle mainBundle] objectForInfoDictionaryKey:#"CFBundleShortVersionString"];
does the trick.
For the lazy here is the swift version :
NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString")!
NSBundle.mainBundle.infoDictionary[#"CFBundleShortVersionString"];

Loading data files in iPhone project

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