Read/write file in Documents directory problem - iphone

I am trying to write a very basic text string to my documents directory and work from there to later save other files etc.
I am currently stuck with it not writing anything into my Documents directory
(In my viewDidLoad)
NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)
NSString *documentsDirectory = [pathArray objectAtIndex:0];
NSString *textPath = [documentsDirectory stringByAppendingPathComponent:#"file1.txt"];
NSString *text = #"My cool text message";
[[NSFileManager defaultManager] createFileAtPath:textPath contents:nil attributes:nil];
[text writeToFile:textPath atomically:NO encoding:NSUTF8StringEncoding error:NULL];
NSLog(#"Text file data: %#",[[NSFileManager defaultManager] contentsAtPath:textPath]);
This is what gets printed out:
2011-06-27 19:04:43.485 MyApp[5731:707] Text file data: (null)
If I try this, it also prints out null:
NSLog(#"My Documents: %#", [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectory error:NULL]);
What have I missed or am I doing wrong while writing to this file?
Might it be something I need to change in my plist or some frameworks/imports needed?
Thanks
[EDIT]
I passed a NSError object through the writeToFile and got this error:
Error: Error Domain=NSCocoaErrorDomain Code=512 "The operation couldn’t be completed. (Cocoa error 512.)" UserInfo=0x12aa00 {NSFilePath=/var/mobile/Applications/887F4691-3B75-448F-9384-31EBF4E3B63E/Documents/file1.txt, NSUnderlyingError=0x14f6b0 "The operation couldn’t be completed. Not a directory"}
[EDIT 2]
This works fine on the simulator but not on my phone :/

Instead of using NSFileManager to get the contents of that file, try using NSString as such:
NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)
NSString *documentsDirectory = [pathArray objectAtIndex:0];
NSString *textPath = [documentsDirectory stringByAppendingPathComponent:#"file1.txt"];
NSError *error = nil;
NSString *str = [NSString stringWithContentsOfFile:textPath encoding:NSUTF8StringEncoding error:&error];
if (error != nil) {
NSLog(#"There was an error: %#", [error description]);
} else {
NSLog(#"Text file data: %#", str);
}
Edit: Added error checking code.

How are you getting documentsDirectory?
You should be using something like this:
NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)
NSString *documentsDirectory = [pathArray lastObject];

Put an NSLog statement after every line where you are setting a variable's value, so that you can inspect those values. This should help you quickly pinpoint where things start to go wrong.

The problem got solved by setting a non standard Bundle ID in die info.plist
I used the Bundle ID from iTunes Connect for this specific app. Now everything works perfectly.

You can also use NSFileHandle for writing data in file and save to document directory:
Create a variable of NSFileHandle
NSFileHandle *outputFileHandle;
use the prepareDataWrittenHandle function with passing file name in parameter with file extension
-(void)prepareDataWrittenHandle:(NSString *)filename
{
//Create Path of file in document directory.
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *outputFilePath = [documentsDirectory stringByAppendingPathComponent:filename];
//Check file with above name is already exits or not.
if ([[NSFileManager defaultManager] fileExistsAtPath:outputFilePath] == NO) {
NSLog(#"Create the new file at outputFilePath: %#", outputFilePath);
//Create file at path.
BOOL suc = [[NSFileManager defaultManager] createFileAtPath:outputFilePath
contents:nil
attributes:nil];
NSLog(#"Create file successful?: %u", suc);
}
outputFileHandle = [NSFileHandle fileHandleForWritingAtPath:outputFilePath];
}
then write the string value to file as:
//Create a file
[self prepareDataWrittenHandle:#"file1.txt"];
//String to save in file
NSString *text = #"My cool text message";
//Convert NSString to NSData to save data in file.
NSData* data = [text dataUsingEncoding:NSUTF8StringEncoding]
//Write NSData to file
[_outputFileHandle writeData:data];
//close the file if written complete
[_outputFileHandle closeFile];
at the end of file written you should close the file.
You can also check the content written in file as NSString for debug point of view as mention above by #Glenn Smith:
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *outputFilePath = [documentsDirectory stringByAppendingPathComponent:#"file1.txt"];
NSError *error;
NSString *str = [NSString stringWithContentsOfFile:outputFilePath encoding:NSUTF8StringEncoding error:&error];
if (error != nil) {
NSLog(#"There was an error: %#", [error description]);
} else {
NSLog(#"Text file data: %#", str);
}

Related

Reading file's content downloaded from dropbox -objective-c

I want to read and print the file's content which downloaded from dropbox but my "readFile" method prints null. I am sure the file is downloaded successfully.
-(void)download
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#", #"File.txt"]];
[[self restClient] loadFile:#"/File.txt" intoPath:filePath];
}
- (void)restClient:(DBRestClient*)client loadedFile:(NSString*)localPath
contentType:(NSString*)contentType metadata:(DBMetadata*)metadata {
[self readFile:#"File.txt"];
NSLog(#"File loaded into path: %#", localPath);
}
-(void)readFile:(NSString *)fileName
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fileNameData=[NSString stringWithFormat:#"%#",fileName];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileNameData];
NSString *str = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:NULL];
NSError *error;
NSString *str = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:&error];
NSLog(#"%#", error);
}
and this is output:
---------******** CONTENT OF THE DOWNLOADED FILE *********------------(null)
I updated my code for capture erorr and I am getting this error from stringWithContentsOfFile:
Error Domain=NSCocoaErrorDomain Code=261 "The operation couldn’t be completed. (Cocoa error 261.)" UserInfo=0x1669c2b0 {NSFilePath=/var/mobile/Applications/11B10727-E372-1147-26BD-1D24S60B8E54/Docume‌​nts/File.txt, NSStringEncoding=4} 2013-08-05 22:06:03.229 DBApp[496:60b]
It looks like your code is reading a file called "File.txt" rather than the actual file that was downloaded from Dropbox. Am I missing something?
EDIT
Based on the comments below, it looks like the error is 261, related to string encoding. You might want to try a different encoding or ensure that the text file is encoded the way you expect it to be.

Error while moving file in Cache Directory in Iphone

I am facing problem to move image file in Cache Directory. My requirement is when I am deleting one file for example image3.png then all other files (suppose there is 9 files like image1.png,image2.png,.....image9.png)after that position (image4.png,....,image9.png) will move to their previous position. I want to rename that files like image4.png to image 3.png.
Below is my code
NSError *error=nil;
NSString *imgName = [NSString stringWithFormat:#"image%d.png",3];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:imgName];
[fileManager removeItemAtPath: fullPath error:NULL];
for (int i=3; i<=9 ; i++) {
NSString *imgName1 = [NSString stringWithFormat:#"image%d.png",i];
NSString *getImagePath1 = [documentsDirectory stringByAppendingPathComponent:imgName1];
NSString *imgName2 = [NSString stringWithFormat:#"image%d.png",i+1];
NSString *getImagePath2 = [documentsDirectory stringByAppendingPathComponent:imgName2];
if ([fileManager moveItemAtPath:getImagePath2 toPath:getImagePath1 error:&error] != YES)
NSLog(#"Unable to move file: %#", [error localizedDescription]);
// Show contents of Documents directory
NSLog(#"Documents directory: %#",
[fileManager contentsOfDirectoryAtPath:documentsDirectory error:&error]);
}
But its showing following error
Unable to move file: The operation couldn’t be completed. (Cocoa error 516.)
Please help me .
Thanks in advance.
From NSFileManager docs on moveItemAtPath:toPath:error::
If an item with the same name already exists at dstPath, this method
aborts the move attempt and returns an appropriate error
Delete the file you want to overwrite first.

how to append tags in xml in iphone?

i am new developer in iphone application. i would like write a content in xml file for that, i have created xml file and write tags with element, attribute and value with some data in that xml as follows.
-(void)writexmlfile:(NSString *)data toFile:(NSString *)fileName NodeName:(NSString *)Node{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
// the path to write file
NSString *fileExtension = [NSString stringWithFormat:#"%#%#",fileName,#".xml"];
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:fileExtension];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:appFile];
if(fileExists) {
NSError *error = nil;
NSString *docStr;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
// the path to write file
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:fileName];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:appFile];
if(fileExists)
{
NSLog(#"file exist in document");
NSData *myData1 = [NSData dataWithContentsOfFile:appFile];
if (myData1) {
docStr = [[NSString alloc] initWithData:myData1 encoding:NSASCIIStringEncoding];
XMLString = [[NSMutableString alloc]initWithString:docStr];
[self XMLString];
NSLog(#"data%#",XMLString);
}
}
// [XMLString insertString:data atIndex:index];
[XMLString appendFormat:#"<%#>%#</%#> \n",Node,data,Node];
BOOL success = [XMLString writeToFile:appFile atomically:YES encoding:NSUTF8StringEncoding error:&error];
if (!success) {
NSLog(#"Error: %#", [error userInfo]);
}
else {
NSLog(#"File write is successful");
}
}
}
i want add new tag with new elements,new attributes,etc.,if i enter element at the place of tag it is modifying with previous tag .
here how can i append the new tag to previous appended tags
please any body could help me
Thanks in advance
As a suggestion, you can use APXML to create XML documents it is very simple and easy to use. This post can guide you further.

iphone, write csv file in sandbox

i must write (at start of app) and delete is content (at the end of app) a csv in my sandbox file with a stream of data.
For your experience, what's the best way to do this?
edit:
i'm trying with this:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filename =#"test.csv";
NSString *fullPathToFile = [documentsDirectory stringByAppendingPathComponent:filename];
if(![[NSFileManager defaultManager] fileExistsAtPath: fullPathToFile]) {
[[NSFileManager defaultManager] createFileAtPath: fullPathToFile contents:nil attributes:nil];
}
NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath: fullPathToFile];
NSString *data = [NSString stringWithFormat:#"%#,%#\n", latitudine.text, longitudine.text];
[handle writeData:[data dataUsingEncoding:NSUTF8StringEncoding]];
it work but.... every time writedata is call i got only one row, no append. i want to collect all values of my two textlabel.
Where my mistake?
edit2:
yessss, find the solution with this code:
first i've create this one:
- (NSString *)dataFilePath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:#"myfile.csv"];
}
and in my viewDidLoad i check and if does not exist, create my file
if (![[NSFileManager defaultManager] fileExistsAtPath:[self dataFilePath]]) {
[[NSFileManager defaultManager] createFileAtPath: [self dataFilePath] contents:nil attributes:nil];
NSLog(#"Route creato");
}
and in one of my method i add the code for retrieve data and append to my file:
NSString *data = [NSString stringWithFormat:#"%#,%# ", latitudine.text, longitudine.text];
//create my data to append
NSFileHandle *handle;
handle = [NSFileHandle fileHandleForWritingAtPath: [self dataFilePath] ];
//say to handle where's the file fo write
[handle truncateFileAtOffset:[handle seekToEndOfFile]];
//position handle cursor to the end of file
[handle writeData:[data dataUsingEncoding:NSUTF8StringEncoding]];
//write data to with the right encoding
Hope this helps!
If you put it in NSTemporaryDirectory(), I think it's supposed to be cleaned up on app exit — it's probably worth checking if this is the case.

iphone writeTofile error

im getting a "CFDictionaryAddValue(): immutable collection 0xd5aea0 given to mutating function"
error when i try to write a string to a file using the follwowing code
NSString *xmlString = [NSString stringWithString:xmlData];
NSError *error = nil;
if ([xmlString writeToFile:filePath atomically:NO encoding:NSASCIIStringEncoding error:&error])
xmlData was a mutable string but xmlString is not.
any ideas?
It works for me in cocoa.
NSString * xmlData = #"This is some random string";
NSString * xmlString = [NSString stringWithString:xmlData];
NSError * error = nil;
if (![xmlString writeToFile:#"data.txt"
atomically:NO
encoding:NSASCIIStringEncoding
error:&error])
{
NSLog(#"writeToFile failed: %#", error);
}
I would check:
How do you get xmlData? Is it a NSString?
Do you specify file path within your app bundle? You will not be able to write outside your application directory apart from Documents (?) I think.
This is how you would specify file in Documents directory:
// Documents directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
// <Application Home>/Documents/foo.plist
NSString *fooPath = [documentsPath stringByAppendingPathComponent:#“foo.plist”];