Content is not retrieved from file - ios

I've got this wired problem, I cannot get the content from the file and initiate my NSMutableArray with it.
Here's my code:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSLog(#"Does file exist?: %i", [[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat: #"%#/length.txt", documentsDirectory]]);
NSMutableArray *tempArr;
tempArr = [[NSMutableArray alloc] initWithContentsOfFile:[NSString stringWithFormat: #"%#/length.txt", documentsDirectory]];
When trying this, initWithContentsOfFile returns (null). The row checking if the file exist prints '1' to the console.
This is the code I'm using to save the data:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
[length.text writeToFile:[NSString stringWithFormat: #"%#/length.txt", documentsDirectory] atomically:NO];
I'm using more or less exactly the same code in a different program without problems.
Really need some help here, perhaps I'm just blind for the moment...

When you try to create an array from the contents of a file, the file must be in plist format, and the outer-most plist element must be <array>. If it doesn't have that format, initialization will fail and your array will be nil.
You're creating the file by writing an NSString to a file, which means you should probably be reading it in to an NSString, not an NSArray.

The docs for NSArray's initWithContentsOfFile: method say:
Return Value An array initialized to contain the contents of the file
specified by aPath or nil if the file
can’t be opened or the contents of the
file can’t be parsed into an array.
The returned object might be different
than the original receiver.
You don't include the declaration of length in your code snippet, but I'm guessing that length.text returns an NSString object, not an NSArray. So you'd need to read that back from a file using initWithContentsOfFile: from NSString, not NSArray.

Related

How do i save multiple strings and not overwrite while writing to a plist file in iOS?

I'm using a "facts.plist" to display a fact(string) after pressing a button, i have a button there that writes that string to a "favourites.txt" file and there i can use it for future use.
Here is the code for that:
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fileName = [documentsDirectory stringByAppendingPathComponent:#"MyFavorites.txt"];
//documentsDirectory];
[self.displayJoke.text writeToFile:fileName
atomically:NO
encoding:NSStringEncodingConversionAllowLossy
error:nil];
NSError *error;
NSString *str = [NSString stringWithContentsOfFile:fileName encoding:NSUTF8StringEncoding error:&error];
NSLog(#"%#", str);
But every time I tap that button the previous string gets overwritten with the new string. How do i create a dictionary or Array to prevent this?
every time i tap that button the previous string gets overwritten with the new string
It doesn't "get overwritten". You are overwriting it:
[self.displayJoke.text writeToFile:fileName
atomically:NO
encoding:NSStringEncodingConversionAllowLossy
error:nil];
That line replaces the file fileName with a new file. If that's not what you want to do, then don't do that. If you want to include the existing contents of the file, it's up to you to read the file first and include that in what you write. (Alternatively, you could look into NSFileHandle, which allows you to append to a file.)

Loading files from disk to NSMutableArray removes NSMutableArray from memory

I'm loading a file to a NSMutableArray. I'm doing it like this:
if(!self.dataArray){
self.dataArray = [[NSMutableArray alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *arrayPath = [[paths objectAtIndex:0]
stringByAppendingPathComponent:#"array.out"];
self.dataArray = [NSMutableArray arrayWithContentsOfFile:arrayPath];
}
The array that is loaded into the file consists of multiple NSDictionaries.
However, this somehow deallocates the array in the memory because when I log dataArray after doing this, it logs nil. How come?
Update
I've figured out that [NSMutableArray arrayWithContentsOfFile:arrayPath] is logging nil because the code in which I'm uploading the content to the file, doesn't create the file:
// write data to disk
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *arrayPath = [[paths objectAtIndex:0]stringByAppendingPathComponent:#"array.out"];
[self.dataArray writeToFile:arrayPath atomically:YES];
NSLog(#"uploaded file: %#", arrayPath); // logs an arrayPath, but one that doesn't exists.
Check the following,
Check the dataArray is a weak property ? If so, change to strong.
Check the file exists at path, using
[[NSFileManager defaultManager] fileExistsAtPath:arrayPath];
Verify the file have expected content, by logging it.
Confirm the File content is organized as a property list (plist). Verify it in plist editor/Xcode.
If you dynamically creating it, check the path you are writing to.
Confirm the method of writing NSArray to plist. Use
[array writeToFile:path atomically:YES];
Note:
If you are dynamically creating the file and you are testing on Simulator; you can
find the file by logging file path and following it on Finder.
Property List Reference
Apple documentation
Per Apple documentation, the array returns nil if the file can’t be opened or if the contents of the file can’t be parsed into an array.
Did you use the [writeToFile:atomically:] method to write the array to a file?
Also, make sure that the filePath string matches exactly on both write and read ends. I've wasted a lot of time trying to hunt down a bug when it turned out I had misspelled the name of the file or used the wrong file extension.
Another possibility: have you confirmed that this code is being executed? Sometimes I've had to change (!self.someProperty) to (self.someProperty != nil) in my if condition to get code like this to run.
Peter Segerblom and wildBillMunson are right: the array returns nil if the file can't be opened or if its content can't be parsed into an array.
You said "array.out" is an array of NSDictionaries. Whenever I have that set of data, I use the plist type of file and read it this way:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
NSString *directory = [paths objectAtIndex:0];
NSString *fullPath = [directory stringByAppendingPathComponent:#"data.plist"];
NSString *errorDesc = nil;
NSPropertyListFormat format;
NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:fullPath];
NSArray *data = (NSArray *)[NSPropertyListSerialization propertyListFromData:plistXML mutabilityOption:NSPropertyListMutableContainersAndLeaves format:&format errorDescription:&errorDesc];
Be sure to check if fullPath is not returning nil.
Hope this helps!

How to save 2 NSMutableDictionary on disk

The development is in Xcode for iOS. I used 2 separate NSmutabledictionary.
I DON´T want to add them (when searching I found that often, but that is not what I try to do)
The app has to store them on the disk and when the app launches it can read the dictionary.
It is not a custom class so initWithCoder and the other one is not necessary (is this right?)
NSArray *data = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [data objectAtIndex:0];
path = [path stringByAppendingPathComponent:#"location"];
[NSKeyedArchiver archiveRootObject:"Dictionary" toFile:path];
This works but when I want to save another dictionary it won't work. My first thought would be to change the objectAtIndex to 1. But Xcode gives me an error when I do that. When I only give another name it simply won't save, but Xcode don't give an error.
What am I doing wrong?
// Find out where the documents folder is
NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
// Create the file path for a file named 'location' inside the documents folder
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"location"];
// Write an array containing both of your arrays to a file at that path
[NSKeyedArchiver archiveRootObject:#[myFirstArray, mySecondArray] toFile:path];
Then, to read them back:
// Read back the array containing the two arrays
NSArray *arrays = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
// Get the individual arrays from the array
NSMutableArray *myFirstArray = arrays[0];
NSMutableArray *mySecondArray = arrays[1];

Retrieve by specific file name from document directory in iOS

Now i am retrieving file from document directory by specific name in iOS with following code.
NSMutableArray *arrayToSearch = [[NSMutableArray alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSError * error;
arrayToSearch = (NSMutableArray *)[[NSFileManager defaultManager] contentsOfDirectoryAtPath:[NSString stringWithFormat:#"%#/Manual.txt",documentsDirectory] error:&error];
I am sure i have the Manual.txt file in document directory.
However it doesn't show anything in tableView.
I also reload tableView.
Is there anything wrong?
The method is contentsOfDirectoryAtPath:. Read the name of the method. Read the description in the docs. The path you pass must reference a directory, not a file.
What you are trying to do doesn't make sense logically. If you know a specific file, then why search for it? Why create an array?
If you want to see if the file exists, use the fileExistsAtPath: method of NSFileManager.
If you just want the filename in the array then do:
NSString *filename = [documentsDirectory stringByAppendingPathComponent:#"Manual.txt"];
[arrayToSearch addObject:filename]; // since the array was pre-allocated
Please don't use stringWithFormat to create the filename. Use the proper NSString path methods like I did above.

How can I permanently save AVAudioRecorder files for later access?

I have my code all set up to actually record the files. What I need, though, is a way to see where they are all saved and list them in a UITableView. I'm not asking the the implementation for the table; I only need a way to see where they are all saved.
All your data is saved into your application's document folder. You can access it with:
NSString *documentsDirectory;
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
if ([paths count] > 0) {
documentsDirectory = [paths objectAtIndex:0];
}
Assign an array to get a list of all your recorded files.
Your url where you are going to save the recorded file:
NSURL *urlOfRecordedFile = [NSURL fileURLWithPath:[NSString stringWithFormat:#"5#/recordFile.caf",[[NSBundle mainBundle] resourcePaht]]];
And here is the actual path of you file
NSLog(#"%#",url);

Resources