3

I am currently trying to write to a file using the following code:

NSString *state = @"Oklahoma";

    NSString *filepath = [[NSBundle mainBundle] pathForResource:@"StatesVisited" ofType:@"txt"];
    NSFileHandle *filehandle = [NSFileHandle fileHandleForWritingAtPath:filepath];
    [filehandle seekToEndOfFile];
    [filehandle writeData:[state dataUsingEncoding:NSUTF8StringEncoding]];
    [filehandle closeFile];

From what I can tell, this should work. I have been able to read from the file using the same filepath.

When I run this code, and open my text file nothing exists.

Undo
  • 25,519
  • 37
  • 106
  • 129
Johnrad
  • 2,637
  • 18
  • 58
  • 98
  • 2
    Please keep in mind, having read permission doesn't mean you also have a write permission. – A-Live Apr 25 '13 at 21:25
  • How do I get permission to write and read to the same file? – Johnrad Apr 25 '13 at 21:27
  • @JohnnyWhisman you **cannot** get write permission to the main bundle at run-time. Once an application is compiled and deployed, the bundle is signed. This is to make sure your malware has changed the application. **SandBox** – Black Frog Apr 25 '13 at 22:20

4 Answers4

3

[NSBundle mainBundle] has to be treated as read-only. Instead, copy the file in the bundle to the Application Support directory and then write to it there.

Use this to find/create the application support directory.

taskinoor
  • 45,586
  • 12
  • 116
  • 142
Abhi Beckert
  • 32,787
  • 12
  • 83
  • 110
  • I am also reading from the file often. Will I need to read from the file in the support directory aswell? – Johnrad Apr 25 '13 at 21:38
  • 2
    It's not that the main bundle has to be treated as read-only, it's that the main bundle IS read-only (at least on a real device). – rmaddy Apr 25 '13 at 23:04
  • @rmaddy That depends on the operating system. On Mac OS X it usually will be writable, and in Xcode's iOS simulator it will probably be writable, and on jailbroken iPhones it might be writable (I don't know about that, you'd have to test). Even when you can write to it it's a bad idea, since upgrading to a new version of the app will overwrite the file. – Abhi Beckert Apr 26 '13 at 00:17
  • @JohnnyWhisman yes, you will need to read from app support instead of the main bundle. – Abhi Beckert Apr 26 '13 at 00:18
1

Writing to resources in main bundle is prohibited. You must use /Documents or /Library of sandbox path in this case.

On first launch of your app just copy all bundled documents/files to /Documents, here's a link to follow.

After that just follow your own design - it'll work just fine this time.

Community
  • 1
  • 1
Sebastian Łuczak
  • 1,116
  • 8
  • 19
  • I have added this code to my viewDidLoad method for my view. Will this change any of the code I have written for reading and writing. Or is this all I needed to add? – Johnrad Apr 25 '13 at 21:44
  • Instead of making filepath from NSBundle you'll need to find path from /Documents folder: – Sebastian Łuczak Apr 26 '13 at 11:20
0

You are probably getting a nil filehandle from fileHandleForWritingAtPath: because you are trying to open a file within your app bundle. You can write the data to NSUserDefaults if its suitable. Otherwise you should write a file to your application support directory. The following blog post describes how to get it or follow @Sebastians advice on the Document folder.

aLevelOfIndirection
  • 3,522
  • 14
  • 18
0

Try this

NSString *state = @"Oklahoma";
NSString *strPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
                strPath = [strPath stringByAppendingPathComponent:@"StatesVisited.txt"];
                [state writeToFile:strPath
                          atomically:NO
                            encoding:NSStringEncodingConversionAllowLossy
                               error:nil];
Ravindhiran
  • 5,304
  • 9
  • 50
  • 82