iOS persistence: storing and retrieving items in directory - ios

I want to save a file to a folder, and then retrieve all the contents of that folder, so I do:
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:storageFolder];
// StorageFolder is just a string like: "#"/FavoritesFolder"
// Filename is just a title given like "myTune.mp3"
NSString *destinationString = [NSString stringWithFormat:#"%#/%#",dataPath,filename];
BOOL success = [object writeToFile:destinationString atomically:YES];
Then I want to retrieve the object, so I do
NSArray *dirContents = [[NSFileManager defaultManager]contentsOfDirectoryAtPath:dataPath error:nil];
But all I get an array of filename (like myTune.mp3). not the Object which is a NSDictionary. What am I doing wrong?

You aren't strictly 'doing' anything wrong. It's your expectations that are wrong. The method you're using (contentsOfDirectoryAtPath:)
Performs a shallow search of the specified directory and returns the paths of any contained items.
If you want to load the file back into memory you need to:
Decide which file you want
Get the full path to the file (directory path and file name)
Load the file (if it's a dictionary, dictionaryWithContentsOfFile:)

Related

Define Entity's Attribute's Value

I am trying to edit rawURL so that it looks in the correct folder within my application bundle. I looked at Apple's documentation, but when I opened up my application's .xcdatamodeld, the attribute whose String value I'm looking to edit, didn't appear to be set to anything:
I looked in the entire code base, and I couldn't find it set anywhere programatically. However, I put a print statement in the code I'm looking to change, and it does in fact print a string. I want to change the value of this string so that it looks in FindSpecies/[species name]/[img file] not FindSpecies/species/[species name]/images/[img file].
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString* cachePath = [paths objectAtIndex:0];
NSString* resourcePath = [[NSBundle mainBundle] resourcePath];
NSLog(#"self.rawurl: %#", self.rawURL);
NSString* stringURL = [self.rawURL stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSLog(#"stringURL: %#", stringURL);
NSURL* url = [NSURL URLWithString:stringURL];
NSString* path = [url path];
NSString* query = [url query];
//...
returnString = [NSString stringWithFormat:#"%#/%#%#", resourcePath, kThumbnailDirectoryName, path];
Can I edit rawURL if I don't even know where/how its set in the first place?
EDIT: This app was built in 2011 by my professor's former grad students. I am in the process of modernizing it.
There's no reason to expect rawURL to have a value in the model editor you show in your screenshot. That defines the schema for the Core Data persistent store, not the data. It might have default values but those aren't required.
If rawURL has a value then it's being set somewhere. You have the source code, so you should be able to find it. If you can't, look again, because you can see it's happening somewhere. If your entity has a subclass of NSManagedObject, it might help to put a breakpoint at the rawURL property declaration in that class. The breakpoint should trigger any time the value changes.
You can of course also change it any time you want on any object instance that has the property. Just assign a value, like any other string property.

CSV to NSString results in empty null object

I'm trying to retrieve content of a csv file to NSString. Thats what I do:
NSString *strBundle = [[NSBundle mainBundle] pathForResource:#"socs" ofType:#"csv"];
NSLog(#"bundle path: %#",strBundle);
NSString *file = [NSString stringWithContentsOfFile:strBundle
encoding:NSUTF8StringEncoding
error:nil];
if ([[NSFileManager defaultManager]fileExistsAtPath:strBundle]) {
NSLog(#"file is there!!!");
}else {
NSLog(#"no file");
}
NSLog(#"file: %#",file);
NSArray *allLines = [file componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
NSLog(#"lines: %lu",(unsigned long)[allLines count]);
file manager shows that the file is there. When i try to log the NSString or number of files it says null. I even created NSData object with the content of exactly the same file and when I logged the NSData object, I clearly saw that there is some data. Then when I tried to create NSString with the content of NSData, I had the same result as before - null. Maybe the problem is somewhere in the formatting of the file?
Any help will be appreciated :)
I see 3 issues:
You are passing a nil argument to the error: parameter in your stringWithContentsOfFile: line. If there's a possibility something might go wrong (and apparently there is), you should pass a real argument there so you can figure out what went wrong.
You can use componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet], but that has a tendency to produce blank "components" between every line. Plain old #"\n" works better in virtually all cases I've run into.
You should be checking fileExistsAtPath before you try to load it into the NSString
If you were truly able to create an NSData object from the path it doesn't necessarily mean it's correct data. But let's say it is, if you were not able to convert it to a NSString then you need to check your encoding parameter.

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.

Custom playlist saving/retrieving

I have an app that allows the user to build a simple playlist which is stored as an array of MPMediaItems. When the app quits or enters the background, I want to store the playlist in a file and retrieve it when the user opens the app again.
Should I just be saving an id in a file as opposed to a whole MPMediaItem object?
Also, as the user's library may have changed how would I compare the saved list against the iPod library, do I loop through and run a bunch of queries?
Save this array into plist file, which is a effective way to save and read from local file.
Here in below are metheds to create, save, read data from plist. Hope it is helpful for you.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *doc = [paths objectAtIndex:0]; //path of document folder
NSString *path = [doc stringByAppendingPathComponent:#"nameOfPlist.plist"]; //get the path of your plist in document folder.
NSDictionary* dic = [NSDictionary dictionaryWithObjectsAndKeys:#"123456",#"number", nil]; //save your data into a dictionary or array.
[dic writeToFile:path atomically:YES]; //then write the dic/array into the plist file.
NSDictionary* dic2 = [NSDictionary dictionaryWithContentsOfFile:path]; //read data from plist.
NSLog(#"dic2 is:%#",[dic2 objectForKey:#"number"]);

Where does [NSData writeToFile] write to?

I wrote a simple program to help me debug.
#import "UIImage+saveScreenShotOnDisk.h"
#implementation UIImage (saveScreenShotOnDisk)
-(void)saveScreenshot{
NSData * data = UIImagePNGRepresentation(self);
[data writeToFile:#"foo.png" atomically:YES];
}
#end
After it's executed, I want to know where foo.png is located.
I went to
~Library/Application Support
and I can't find foo.png. Where is it?
If I do
BOOL result = [data writeToFile:#"foo.png" atomically:YES];
the result will be NO, which is kind of strange given that the simulator, unlike the iPhone, can write anywhere.
You need to direct the NSData object to the Path you want the data to be saved in:
NSString *docsDir;
NSArray *dirPaths;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
NSString *databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent:#"foo.png"]];
[data writeToFile:databasePath atomically:YES];
This will save your file in your App's Folder on the device (or the simulator).
The default place, where the files are stored, is the folder your executable is stored.
See where your executable is stored via right clicking Products->YourExecutable :
Then open in finder.
Here pawel.plist resource create via
NSArray *a = #[#"mybike", #"klapki", #"clapki", #"ah"];
[a writeToFile:#"pawel.plist" atomically:NO];
For Swift, based on Shachar's answer:
let path = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] + "/foo.png"
data?.writeToFile(path, atomically: true)
U forgot to provide location or path where u want to write.Check this writeToFile:options:error:
Writes the bytes in the receiver to the file specified by a given path.
- (BOOL)writeToFile:(NSString *)path options:(NSDataWritingOptions)mask error:(NSError **)errorPtr
Parameters
path
The location to which to write the receiver's bytes.
mask
A mask that specifies options for writing the data. Constant components are described in “NSDataWritingOptions”.
errorPtr
If there is an error writing out the data, upon return contains an NSError object that describes the problem.
You can give a search for "NSDocumentsDirectory", I usually search the path for the documents directory using this method, and then append my file name to it. in the method writeToFile:, this appended path is provided. Then using iTunes>application, scroll to bottom, select your app, and you should be able to see the saved file.
PS: you should have set a valur in plist that specifies that you application uses the phone storage.

Resources