Apr 07

First you need to add your file to the Resources folder of your Xcode project. Then you can access the file like this (assuming the file is called MyFile.txt):

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"MyFile" ofType:@"txt"];
NSData *myData = [NSData dataWithContentsOfFile:filePath];
if (myData) {
	// do something useful
}

Here’s a complete example reading a help text file into a UIWebView.

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"HelpDoc" ofType:@"htm"];
NSData *htmlData = [NSData dataWithContentsOfFile:filePath];
if (htmlData) {
	[webView loadData:htmlData MIMEType:@"text/html" textEncodingName:@"UTF-8" baseURL:[NSURL URLWithString:@"http://iphoneincubator.com"]];
}

If you want to read the file into a string, which you can then display in a UITextView, for example, then do this:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"important" ofType:@"txt"];
if (filePath) {
	NSString *myText = [NSString stringWithContentsOfFile:filePath];
	if (myText) {
		textView.text= myText;
	}
}

written by Nick \\ tags: , , ,

87 Responses to “How To Read a File From Your Application Bundle”

  1. Ben Chatelain Says:

    It is possible to add a file to a bundle at runtime? I’m working on an app that downloads a file from the web and I’d like to save it to the iPhone’s file system within the app’s sandbox for later use.

  2. Nick Dalton Says:

    Ben,

    It’s not possible (or at least strongly discouraged) to update files in the app bundle.

    If you’re downloading files and want to store them on the device you should use the Documents directory. You can get the path to this directory with:

    - (NSString *)getDocumentsDirectory {
    	NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    	return [paths objectAtIndex:0];
    }
    
  3. rey Says:

    To replace htmlData = [NSData dataWithContentsOfFile:filePath]; with a non-autoreleased version, it would be htmlData = [[NSData alloc] initWithContentsOfFile:filePath]; right?

    But how would one create a non-autoreleased version of NSString *filePath = [[NSBundle mainBundle] pathForResource:@”MyFile” ofType:@”txt”]; ?

  4. Nick Says:

    @rey: Yes, you can manage the allocation of the NSData yourself with alloc and initWithContentsOfFile. And if it’s a large file you definitely want to do that.

    Regarding the second line, you typically don’t manage allocation of NSString yourself, and in this case the file path returned is going to be a string with a reasonable length.

  5. Simon Says:

    Hello Nick,
    Is it also possible to read a specified line from the file?

  6. Nick Says:

    @Simon: One way to get at a specific line in the file is to use stringWithContentsOfFile as described above, and then split the string into lines with componentsSeparatedByString:@”\n”. See http://www.cocoadev.com/index.pl?ReadFileLines for more information.
    Reading the entire file into a string is obviously not a good idea if the file is large. But as far as I can tell there are no framework methods for reading a line of text from a file. You’ll have to use the standard methods in C.

  7. Olivia Says:

    Hey Nick,
    Great Blog. I just had a quick question. Hopefully you still check for questions on here. I have figured out how to display local html content inside a UIWebView. I have a UITableView that loads its data from a .plist similar to Apple’s DrillDownSave sample, and want each cell’s Detail View to load a separate html file. How would I reflect this in the code that you provided:

    1. NSString *filePath = [[NSBundle mainBundle] pathForResource:@”HelpDoc” ofType:@”htm”];
    2. NSData *htmlData = [NSData dataWithContentsOfFile:filePath];
    3. if (htmlData) {
    4. [webView loadData:htmlData MIMEType:@”text/html” textEncodingName:@”UTF-8″ baseURL:[NSURL URLWithString:@”http://iphoneincubator.com”]];
    5. }

    I am thinking that somewhere in my .plist, I need to make strings assigned to the names of each of the html files and somehow modify the above code to assign the pathForResource to……????

    Hopefully you can point me in the right direction.

  8. Nick Says:

    @Olivia: Displaying mulitple UIWebViews on one screen can be problematic, so I would advise against having UITableViewCells with its own UIWebView inside it. A more efficient solution would be to make the entire screen be one UIWebView that has HTML that is made to look like a standard iPhone list.

    That said, if you want to use the approach that you’re suggesting, read your plist into an array. Each item in the array maps to a cell in your table view. Add the code above to the cellForRowAtIndexPath method. You can have the HTML for each cell in the plist itself, or just have the filename in the plist.

  9. Olivia Says:

    Nick,

    Thanks a lot for the response. It is much appreciated. Off to tackle this!

  10. sanket Says:

    hi,
    i am trying an application which read text file from specified url.
    i tried like this

    NSData *webData = [NSData dataWithContentsOfURL:url];

    NSString* data = [[[NSString alloc] initWithData:webData encoding:NSUTF8StringEncoding] autorelease];

    but it is not working

    please help

    thanks in advance

  11. Nick Says:

    @sanket: You don’t have to take a detour via NSData. You can get a string directly with NSString *myString = [NSString stringWithContentsOfURL:url];

  12. frosties Says:

    Hi Nick,

    Just discovered your blog and found much useful material 🙂

    I would like to get a javascript in the bundle (why not jquery ?) and to be able to use it in webpages that are not in the bundle but that get loaded on runtime.
    Is that possible ?

    best regards

  13. Nick Says:

    @frosties: Welcome to the blog! I’m happy to hear that you’ve found a lot of useful material.

    If the web page that you are loading runtime does not include any other assets than the JavaScript that’s in the bundle, then you can follow the steps in this post: UIWebView – Loading External Images and CSS

    If the web page contains assets that need to be loaded from its own domain as well as the JavaScript that’s in the bundle, then things get a little bit more tricky. If you can adjust that web page so that all assets, except your special JavaScript, are loaded using absolute URLs, then it will also work.

  14. frosties Says:

    Thank’s for the answer !
    Changing the baseurl is good idea but as you said you need to have everything in the webpage 🙁 Maybe I’ll figure out how to do that or find a hack to do that.
    But:
    if you can get this url and put it as a baseurl, why wouldn’t it be possible to have it for other links ?

  15. john Says:

    Hi,
    I need to save a webpage to my application folder and want to access it later. How can I do it? Please help

    -John

  16. Nick Says:

    @john: You should never store any data in the application bundle. Store data in the Documents directory. You can get the path to the Documents directory with this code:

    - (NSString *)documentsDirectory {
    	NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    	return [paths objectAtIndex:0];
    }
  17. speeddemon Says:

    Hi,Nick

    i get the NSData from a rtf file from my app bundle,and how can i get the plain text from that NSData?

    Please help.

    Best Regards!

  18. Nick Says:

    @speeddemon: If you want to read a file into a NSString instead of a NSData, then use the third code snippet in the blog post. If you are stuck with a NSData object and you need to convert it to a NSString, you can do that if you know the string encoding used. Example: [myString initWithData:myData encoding:NSUTF8StringEncoding];

  19. pierre Says:

    thanks for your website. I’m new in the business, how do I go about to read a pdf file from within an iPhone app. My pdf has got text and pictures, please assist if you can. I believe I have to use UIWebView, s this true, I’m waiting for your response.

  20. BP Says:

    i have one question,
    i need to browse and select files with in iPhone or iPod and then upload to HTTP server.
    if any one have idea please share with me i need very very urgent please ..

    Thanks is advance.

  21. kryptonics Says:

    Hi! I’m still having problems understanding the basics of this. I want to read a single Int from a file and assign it to ‘lv’. I believe my problem lies with pulling the data from the file, but I’m not sure.

    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@”dlData” ofType:@”txt”];
    if (filePath) {
    NSInteger myInt = [prefs integerForKey:@”integerKey”];
    if (myInt) {
    lv = myInt;
    }
    }

    Thank you! 🙂

  22. Nick Says:

    @kryptonics: If you’re reading from a file then you don’t need NSUserDefaults, that’s something entirely different.
    Use the example in the post to read the text file into a string. Then convert your string to an int.

  23. Tom Says:

    Simple question here,

    I need to get the contents of an .rtf file (a single line “Hello, World!”) and display it in a textView when the application loads. I presume the third piece of code you have here is to be used. Where should I put the code and how do I make the .xib file work to do this simple task?

    Thanks

  24. Nick Says:

    @Tom: The iPhone cannot natively parse .rtf files. If you just read the first line as if it were a text file, then you’re probably going to get some header data relevant to the .rtf file format, instead of “Hello, World!”.
    You can’t write code like this inside a .xib file. If you need to show text like this in a view, then adding the code to viewDidLoad or viewWillAppear would work.

  25. xnanoob Says:

    thank you very much. i try read data from xml in local file.

    until search meet this Entry and your website.

    thank you very much.

  26. kris Says:

    Reg. Olivia comments. Even i am looking for the same apps. can i get any sample code to UIWebView for UITableView. Right now I am using DetailView for the last row. Appreciate your help.

  27. lufasz Says:

    hi! is there a way to add files to your bundle via xcode, such that they will be available in the app Documents directory at runtime?

  28. Nick Says:

    @lufasz: Yes, this is a common thing to do. Particularly with SQLite files which are added to your project in Xcode but need to be moved to the Documents directory at runtime. Apple’s Books sample code was a good example of this. (I haven’t checked the latest version, called CoreDataBooks, but I suspect that they’re still using the same technique to store the database file in the bundle and then copy it to the Documents directory.)

  29. BP Says:

    Hi All,
    it’s really wonder full blog,
    i have one quick question,
    i am downloading and displaying wor or pdf document in UIWebView this is working fine
    now i want to save this document in to my iphone .
    could any one please tell me how can i do this
    thanks in advance

  30. Mayur Says:

    Hey Nick —

    Am trying to load an excel/ppt file in my UIWebView. Am downloading the file into NSData Object and then invoking the “loadData” method on UIWebview

    Below is the code :
    [webView loadData:documentData MIMEType:[self getMIMEType:documentURL] textEncodingName:@”UTF-8″ baseURL:[NSURL URLWithString:fName]];

    The getMIMEType — returns the mime type depending on the file extension.
    Anyway, PDFs load beautifully. But, no excel, word or ppt. It throws an error — as it invokes the “didFailLoadWithError” delegate method of UIWebView.

    Can someone help please ??

    Cheers

    Mayur

  31. Nick Says:

    @Mayur: I’ve read in Apple’s support forums that the loadData and loadRequest behave slightly different when it comes to displaying Excel, Word and PowerPoint documents. See this thread for example.

  32. Sharif Says:

    The solution: If you’re just using the plist as a nested data structure, you could
    even put the file name in there, add all the html files to your
    project, then load up the html file via the
    tableView:didSelectRowAtIndexPath: method I’m assuming you’re using to
    unpack the plist into the tableview/webview you’re displaying this
    information in.

    To any one that can help. I am trying to implement the above suggestion without success. In my FAQDetailViewController.h I have…

    NSString *bundle = [[NSBundle mainBundle] bundlePath];
    NSString *webFile = [bundle stringByAppendingPathComponent:{htmlFilename}];
    UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 200, 300)];
    [browser loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:webFile]]];
    [self addSubview:webView];

    Then in my FAQViewController.h I unpack the html file from the plist here…

    – (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    NSDictionary *dictionary = [self.tableDataSource objectAtIndex:indexPath.row];
    NSArray *Children = [dictionary objectForKey:@”Children”];

    if([Children count] == 0) {
    NSInteger ViewNumber = [[dictionary objectForKey:@”View”] integerValue];
    switch (ViewNumber) {
    case 1: {
    FAQDetailViewController *faqdvController = [[FAQDetailViewController alloc] initWithNibName:@”FAQDetailView” bundle:[NSBundle mainBundle]];
    faqdvController.webFile = [dictionary objectForKey:@”faqDesc”];
    faqdvController.hidesBottomBarWhenPushed = NO;
    [self.navigationController pushViewController:faqdvController animated:YES];
    [faqdvController release];
    }

    This approach is not working. Am I on the right path? Am I missing something? Can this work?

  33. Clyde Says:

    thanks for the tut’s Nick, just got some questions.

    1. Can we use the info written on the text file for comparison to the users input?
    ex: “compare the coordinates (x,y) of users touch to the one listed on the text file and if the coordinates match do this… and if not do that….”

    2. And in what format do we need to write on the text file for the program to read? do we need to follow the xml format like in plist?

    Thanks and hope to see more tutorials.

  34. Nick Says:

    @Clyde: 1. Yes, you can store any information you want in the file. 2. You can use any format you want, e.g. text, binary, XML. I like using the plist format because it’s easy to create and maintain as well as easy to load into your app.

  35. Sanniv Says:

    @Nick: If we want to show and edit rtf files, then what should be our approach?

  36. Nick Says:

    @Sanniv: To show RTF files, see this Technical Q&A from Apple: http://developer.apple.com/iphone/library/qa/qa2008/qa1630.html
    There is no built-in functionality for editing RTF files on the iPhone. You will have to build that yourself from scratch.

  37. Pierre Says:

    All this is great but, can I get the name of a file – the last part of its path – from the string of its path?
    Thanks

  38. Pierre Says:

    I mean: is there a way to get it other than painfully parsing the path string?

  39. Pierre Says:

    Sorry! Had I but read the doc…
    lastPathComponent in NSString is the solution.
    Yet it’s hardly advertized as such.

  40. Hardik Says:

    hello,
    I want to use .txt file in my iphone application.i.e for example say helpmenu.h file and helpmenu.m file are the two files now i wish to convert helpmenu.h file into helpmenu.txt file and then i want to use this helpmenu.txt file in my application.Is it possible? if yes then how.
    Thanks in advance.

  41. Hardik Says:

    I have used the same code as given below…

    NSString *filePath = [[NSBundle mainBundle] pathForResource:@”help” ofType:@”txt”];
    if (filePath) {
    NSString *myText = [NSString stringWithContentsOfFile:filePath];
    if (myText) {
    textView.text= myText;
    }
    }

    but the problem I CANT SEE the text which is written in the help.text file.
    can anybody help me when I am wrong.
    Thanks in advance.

  42. jAmster Says:

    How can my app legally (i.e without Jailbreak) access the iPhone file system ….in either read / write mode.

  43. Nick Says:

    @jAmster: You can access the iPhone file system within the application’s sandbox. Any files that reside outside the sandbox is off limits. You should only write to the Documents and tmp directories. In the past there have been some loopholes where you were able to access files that you shouldn’t be allowed to. For each OS release it seems that Apple is plugging the known holes.

  44. Hardik Says:

    hello,
    Can we use the .xls file the same way as we use .txt file.
    If yes then how.
    Thanks in advance

  45. hardik Says:

    I have used it but It is not displaying ” (null) ”

    my code is:

    NSString *myFilePath = [[NSBundle mainBundle]pathForResource:@”help” ofType:@”txt”];

    NSString *myFileContents = [NSString stringWithContentsOfFile:myFilePath encoding:NSUTF8StringEncoding error:nil];

    NSString *s = [NSString stringWithFormat:”” @”%@\n”,myFileContents];

    textView.text = s;

  46. Nick Says:

    @hardik: There are too many double-quotes in one of your code examples, otherwise they look fine to me.
    You can’t read and display an .xls file in the same way as a text file.

  47. Frans Says:

    Hi i am very new to iphone programing. I am trying to change this code to get the plist from my server.:

    NSString *Path = [[NSBundle mainBundle] bundlePath];
    NSString *DataPath = [Path stringByAppendingPathComponent:@”Data.plist”];

    NSDictionary *tempDict = [[NSDictionary alloc] initWithContentsOfFile:DataPath];
    self.data = tempDict;
    [tempDict release];

    I cant seem to make it work any sugestions?

    thanks in advance

  48. Nick Says:

    @Frans: Many classes that can be initialized with the contents of a file, can also do it from a URL. For example: [[NSDictionary alloc] initWithContentsOfURL:myURL];

  49. GreenMan Maple Says:

    When I try to use loadHTMLString or loadData, the webview ends up displaying a blank screen. I’ve confirmed that the data is valid going in, and using the webview loadURL method loads content and displays it fine. Got any idea what’s wrong?

  50. Nick Says:

    @GreenMan: Make sure the HTML is valid and doesn’t display white text on a white background, for example. You can also download the sample project here, which uses these methods extensively.

  51. mira Says:

    Hi!
    I have .plist that looks like this:

    used
    YES
    webAddress
    http://www.google.com
    duration
    20

    And code:
    NSBundle* saverBundle = [NSBundle bundleForClass: [self class]];
    filePath = [[saverBundle pathForResource: @”Webpages” ofType:@”plist”] retain];
    NSDictionary *plistData = [[NSDictionary dictionaryWithContentsOfFile:filePath] retain];
    NSString *budeSeNacitatStranka = [NSString stringWithFormat:@”v%@”, [plistData objectForKey:@”webAddress”]];
    webView = [[WebView alloc] initWithFrame:[self frame] frameName: nil groupName: nil];
    [self addSubview:webView];
    [[webView mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString: budeSeNacitatStranka ]]];

    I want to load key “webAddress” as a webpage in WebView..but makes only white page… What’s wrong? Thank you.

  52. Nick Says:

    @mira: If you look at the value of the variable that should hold your webAddress, it is most likely nil. The reason is the structure of your plist which has an outer array that wraps the dictionary. Either remove the array and have the plist root be a dictionary, or you have to find the correct entry in the array before attempting objectForKey.

  53. mira Says:

    Sorry, there is the plist:

    -plist version=”1.0″-
    -array-
    -dict-
    -key-used -/key-
    -string- YES -/string-
    -key- webAddress -/key-
    -key- duration -/key-
    -string- 20 -/string-
    -/dict-
    -/array-
    -/plist-

  54. matthew Says:

    This is great. I have been searching everywhere and I appreciate you sharing your knowledge.

    I am trying to accomplish a similar task as mira. I am trying to create detail pages for multiple points on a map. All of the name, subtitle, lat, long, icon and detail html page information are loaded into the plist.

    name
    Title
    address
    Subtitle
    latitude
    28.416721
    longitude
    -81.581667
    imageName
    Custom_icon.png
    bulletName
    Custom_icon.png
    detailURL
    test.html

    These items repeat for each item located on the map. Clicking the “calloutAccessoryControlTapped” loads a new detailView, which is a UIWebView and that is where I want these detailed pages to load.

    I have the detailView loading fine and pulling a local HTML file, but it is hardcoded in the filepath. I would like to load the unique “detailURL” pages from the plist.

    Would you have any idea (he asks hopingly) on how I might accomplish this? Again, thanks for sharing your knowledge with the community.

  55. Nick Says:

    @matthew: If you’re trying to load a local HTML file into your detailView, then this post might help.

  56. Bigo Says:

    Nick,
    first thanks for your kindness

    I want to read in data from an rss(xml) feed and populate that data in iphone accordingly—- images, headlines and subtext.

    I have to achieve this dynamically as many times throughout the day this rss will be updated.

    My concerns, how do I read in this data —
    and upon getting this data and parsing it how do I manage it so it is availble offline (core data) or (sqlite) ???

    I know memory is an issue, I guess thats another convo

    Please help out kinf SIR!!!

  57. Nick Says:

    @Bigo: Caching content from news feeds that change frequently is a big task. I have literally spent weeks on some projects to implement and fine-tune this particular feature. And there’s no one recipe that fits all situations. So your question is a little bit beyond the scope of a blog post.

  58. Steven Says:

    Hey, I thank you in advance – I’ve learned a lot from your blog so far and was hoping you can help me answer a question:

    How would I go about either downloading a group of files from a manifest on my server, which I’d then use as assets within in a UIWebView

    OR – keep a loading screen up until all of the content within a UIWebView has been loaded?

  59. Nick Says:

    @Steven: To download a group of files you could package them in a zip archive and then unpack them on the iPhone. But since there’s no native support for zip archives containing multiple files, this is a bit tricky.

    It is much easier to have an activity indicator while the web assets are loading. See the sample code attached to this post for an example of how to do that.

  60. Bigo Says:

    Thank you very much

    I am new to Objective C
    I have tons of web and script development knowledge, but this by far is the toughest project I have ever embarked on, but I guess I am going to have to take baby steps with this one.

    Thank you very much

  61. Joe Says:

    This is great! However I can’t get a UITextView to display a simple string from a text file. I even used your exact code:

    – (void)viewDidLoad {
    [super viewDidLoad];

    NSString *filePath = [[NSBundle mainBundle] pathForResource:@”untitled” ofType:@”txt”];
    if (filePath) {
    NSString *myText = [NSString stringWithContentsOfFile:filePath];
    if (myText) {
    textView.text= myText;
    }
    }
    }

  62. miss e. Says:

    can i have full simple code about reading from txt file using xcode??

    please..i am still new on this

    thank you.

  63. Phil Says:

    Hi and thanks for the help,

    I have sucessfully read the text file in, however it isn’t full justified. How can I achieve full justification?

    Thanks

  64. Ram Says:

    What is the maximum size of data that i can write in the documents folder? Right now i am writing 150Mb of data into a file, when i try adding more data into the file, my device terminates the app.

  65. Nick Says:

    @Ram: I’m not aware of any file size limitation, other than the available disk space.

  66. Adriana Says:

    Hi,

    Have you ever experienced that if the amount of data you have to load into the UIWebView is very large, then the app crashes? I’m loading the data the same way as you. It works fine until a certain amount of data, but it crashes if the amount of data is high. I have no idea how to handle this problem. Do you have any suggestion?

    Thanks.

  67. Nick Says:

    @Adriana: Yes, the iPhone has very limited amount of memory compared to your browser on your desktop computer. It’s not very difficult to run out of memory by loading too much data into a web view. If you have control over the web page you’re trying to display you can try to remove stuff until it gets down to a reasonable size. If you don’t have control over the web page then you could try to load the HTML into a mutable string and then delete stuff from it before you load it into the web view. But this is dicey too since you may run out of memory when you’re loading data into the string, and you will probably have two instances of the data in memory as you load the HTML from the string into the web view.

  68. Ayaz... Says:

    i have one Question on NSData.

    i have one File It name is “my book” this is “.doc” file i want to download it so tell me one thing is this possible to download file of this name i mean to say in this file name there is a space so tell me it is possible or not…

  69. Nick Says:

    @Ayaz: Yes that is definitely possible. With local file names, spaces are typically not a problem.
    For generic URLs you need to replace spaces in the URL in some situations. See the stringByAddingPercentEscapesUsingEncoding method in NSString.

  70. Tyler Says:

    I have a blog app, and want to feature a save button where the user can save the article they are reading, and read it later. All of the HTMLs save fine in the documents directory, but I am unsure of how to get the tableview to show those htmls from the documents directory. any suggestions?

  71. Nick Says:

    @Tyler: Keep track of the articles that the user saves. Store information about the articles (name, URL, etc) in a data file. The datafile can be created in many ways: a serialized NSArray object, a serialized array of your own objects, a plist, etc. When displaying the table view, read the data from the data file and show one table row per entry in the data file.

  72. SHAYIN Says:

    I want to use Iphone to communicate with the Windows MS SQL database, what is the best methods that I can try? export sql data into *.txt than read from iphone??

  73. Nick Says:

    @SHAYIN: There are many ways to do this depending on your requirements. Here are a few examples:

    Create a web service on the Windows servers side. The app communicates with the web service to read/write data.
    Export the data from the MS SQL database and import it into a SQLite database that you can store in the app bundle.

Leave a Reply