I am trying to get an "add to favourites" feature working on my app. I just can't seem to get it working correctly. Basically everytime my phone restarts, all the favourites are deleted from the array and dictionary. Is there anyway to save this data so that it is kept and restored everytime the app launches? Many thanks.
Here is some of the code: in appDidFinishLaunching:
//============== Add To Favourites ==============
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"Saved.data"];
NSArray *pathsArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryArray = [pathsArray objectAtIndex:0];
NSString *filePathArray = [documentsDirectoryArray stringByAppendingPathComponent:#"savedArray.data"];
delegateFavouritesDictionary = [NSMutableDictionary dictionary];
[delegateFavouritesDictionary writeToFile:filePath atomically:YES];
delegateFavouritesArray = [[NSMutableArray alloc]init];
In the detailViewController viewDidLoad:
self.addToFavouritesArray = [[NSMutableArray alloc] init];
self.addToFavouritesDictionary = [NSMutableDictionary dictionary];
TabBar_NavigationBasedAppDelegate *mainDelegate = (TabBar_NavigationBasedAppDelegate *)[[UIApplication sharedApplication]delegate];
//addToFavouritesArray = [[NSMutableArray alloc] init];
NSMutableArray *tempArray1 = mainDelegate.delegateFavouritesArray;
//NSMutableDictionary *tempDictionary1 = mainDelegate.delegateFavouritesDictionary;
addToFavouritesArray = tempArray1;
//self.addToFavouritesDictionary = tempDictionary1;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"Saved.data"];
addToFavouritesDictionary = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
In the detailViewController, in the addToFavourites Function:
NSString *ID = [[NSUserDefaults standardUserDefaults]objectForKey:#"ID"];
if([[addToFavouritesDictionary allKeys] containsObject:ID]) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"Saved.data"];
[addToFavouritesDictionary removeObjectForKey:ID];
[addToFavouritesArray removeObject:Name];
[favouritesButton setTitle:#"+ Favourites" forState:(UIControlState)UIControlStateNormal];
[addToFavouritesDictionary writeToFile:filePath atomically: YES];
NSLog(#"New Dictionary: %#", addToFavouritesDictionary);
} else {
[addToFavouritesArray addObject:Name];
NSString *ID = [[NSUserDefaults standardUserDefaults]objectForKey:#"ID"];
[addToFavouritesDictionary setObject:Name forKey:ID];
[favouritesButton setTitle:#"- Favourites" forState:(UIControlState)UIControlStateNormal];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"Saved.data"];
[addToFavouritesDictionary writeToFile:filePath atomically: YES];
NSLog(#"Mutable Dictionary: %#", addToFavouritesDictionary);
//[addToFavouritesDictionary release];
}
In the FavouritesViewController, in viewDidLoad:
TabBar_NavigationBasedAppDelegate *mainDelegate = (TabBar_NavigationBasedAppDelegate *)[[UIApplication sharedApplication]delegate];
favouritesArray = [[NSMutableArray alloc] init];
NSMutableArray *tempArray1 = mainDelegate.delegateFavouritesArray;
favouritesArray = tempArray1;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"Saved.data"];
favouritesDictionary = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
Many thanks for any help
In your applicationDidFinishLaunching: method (so every time your app launches), you're first creating an empty NSMutableDictionary and then writing that to Saved.data, potentially overwriting anything that might have been there.
Related
Hi I implemented this object PlistManager to write/read plist in my project.The problem is that the plist is populated fine will running (I hope) and when entering in background (I used notification and NSlog the [Plistmanager readPlist:#"Database"]) i still can read the data entered before.
The point is when I stop the simulation on xcode and run again the plist is now empty. Why?
#interface ReadWritePlist : NSObject
+(void)writeToPlist:(NSString*)filePlist dic:(NSDictionary*)dic;
+ (NSMutableDictionary *)readPlist:(NSString*)filePlist;
#end
#implementation ReadWritePlist
+ (void)writeToPlist:(NSString*)filePlist dic:(NSDictionary*)dic
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
[dic writeToFile:[documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.plist",filePlist]] atomically:YES];
}
+ (NSMutableDictionary *)readPlist:(NSString*)filePlist {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [[documentsDirectory stringByAppendingPathComponent:filePlist] stringByAppendingPathExtension:#"plist"];
NSMutableDictionary *dic=[[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
return dic;
}
solved
I just found these new methods for read/write plist and it is working.I had to add the "initializeFileDic" method inside appdelegate (didFinishLaunchingWithOptions):
#implementation PlistManager
+ (NSMutableDictionary *)readPlist:(NSString*)filePlist {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [[documentsDirectory stringByAppendingPathComponent:filePlist] stringByAppendingPathExtension:#"plist"];
NSMutableDictionary *dic=[[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
return dic;
}
+ (void)writeToPlist:(NSString*)filePlist dic:(NSDictionary*)dic
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
if ([dic writeToFile:[documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.plist",filePlist]] atomically:YES]) {
NSLog(#"Ok done!");
}
else{
NSLog(#"Noo not done!");
}
}
+ (void)initializeFileDic:(NSString*)FileNameExt
{
NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *startPath = [[path stringByAppendingPathComponent:FileNameExt]stringByAppendingPathExtension:#"plist"] ;
NSString *documentsDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [[documentsDirectoryPath stringByAppendingPathComponent:FileNameExt]stringByAppendingPathExtension:#"plist"];
NSLog(#"%# \n,\n %# ",startPath,filePath);
if([NSDictionary dictionaryWithContentsOfFile: startPath]){
NSLog(#"File %# exists",filePath);
}
if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]){
if([[NSDictionary dictionaryWithContentsOfFile:startPath] writeToFile:filePath atomically:NO])
NSLog(#"File copied inside App DocumentsDirectory\n\n");
else
NSLog(#"Error while trying to copy into DocumentsDirectory\n\n");
}
}
#end
Could Anybody explain what was wrong?
Thanks
When do you make the call to save the data to the plist? If you quit your app from Xcode then it is terminated immediately, and doesn't go through any of the application delegate methods related to terminating or entering the background, which is where I suspect your code is.
Pressing the home button on the simulator is the way to get those methods to run.
i try to delete Dirty Memory and u se VMTRACE but i dont know why this code have dirty memory
NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"Info.plist"];
NSDictionary *dict =[[[NSDictionary alloc] initWithContentsOfFile:path] autorelease];
I can't getting my stored data.... This is the code:
if ([string isEqualToString:#""]) {
//RECUPERO DATA
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *pathToDocuments=[paths objectAtIndex:0];
pathToDocuments=[pathToDocuments stringByAppendingString:#"getSubscriptionsListShowOnlyWithUnreadFeeds.txt"];
NSLog(pathToDocuments);
dataReply=[[NSData alloc] initWithContentsOfFile:pathToDocuments];
NSString *string = [[NSString alloc] initWithData:dataReply encoding:NSASCIIStringEncoding];
NSLog(#"string recuperata %#",string);
}
if ([string isEqualToString:#""]==NO) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *pathToDocuments=[paths objectAtIndex:0];
pathToDocuments=[pathToDocuments stringByAppendingString:#"getSubscriptionsListShowOnlyWithUnreadFeeds.txt"];
NSLog(pathToDocuments);
[dataReply writeToFile:pathToDocuments atomically:YES];}
Is there something wrong?
EDIT
No bugs no crashes but the NSLog(#"string recuperata %#",string); prints an empty string! (data are stored in the device because I had running at least one time my app when string!= empty
Thanks
I think there is a else missing on the second if. I'm not sure if that is what you wanted or if it is a typo on your part. check if that is the problem.
if ([string isEqualToString:#""]) {
//RECUPERO DATA
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *pathToDocuments=[paths objectAtIndex:0];
pathToDocuments=[pathToDocuments stringByAppendingString:#"getSubscriptionsListShowOnlyWithUnreadFeeds.txt"];
NSLog(pathToDocuments);
dataReply=[[NSData alloc] initWithContentsOfFile:pathToDocuments];
NSString *string = [[NSString alloc] initWithData:dataReply encoding:NSASCIIStringEncoding];
NSLog(#"string recuperata %#",string);
} else if ([string isEqualToString:#""]==NO) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *pathToDocuments=[paths objectAtIndex:0];
pathToDocuments=[pathToDocuments stringByAppendingString:#"getSubscriptionsListShowOnlyWithUnreadFeeds.txt"];
NSLog(pathToDocuments);
[dataReply writeToFile:pathToDocuments atomically:YES];
Try changing to NSUTF8StringEncoding if you are unsure about the encoding, usually it works.
if ([string length]<=0) {
//RECUPERO DATA
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *pathToDocuments=[paths objectAtIndex:0];
pathToDocuments=[pathToDocuments stringByAppendingString:#"getSubscriptionsListShowOnlyWithUnreadFeeds.txt"];
NSLog(pathToDocuments);
dataReply=[[NSData alloc] initWithContentsOfFile:pathToDocuments];
NSString *string = [[NSString alloc] initWithData:dataReply encoding:NSASCIIStringEncoding];
NSLog(#"string recuperata %#",string);
}
else {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *pathToDocuments=[paths objectAtIndex:0];
pathToDocuments=[pathToDocuments stringByAppendingString:#"getSubscriptionsListShowOnlyWithUnreadFeeds.txt"];
NSLog(pathToDocuments);
[dataReply writeToFile:pathToDocuments atomically:YES];
}
I have the following block of code:
NSMutableArray* mergedSymbolsArray = [NSMutableArray array];
for (NSDictionary* aSymbol in localSet) {
NSLog(#"Symbol:%#",[aSymbol valueForKey:#"symbol"]);
[mergedSymbolsArray addObject:aSymbol];
}
[Utils writeObjectToPList:mergedSymbolsArray];
tickers = [Utils getDataFromPList];
Here is my code to read/write to a plist:
+ (void)writeObjectToPList:(id)myData {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"mobile-watchlist.plist"];
[myData writeToFile:path atomically:YES];
}
+(NSMutableArray*)getDataFromPList
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"mobile-watchlist.plist"];
NSMutableArray* myArray = [[NSMutableArray alloc] initWithContentsOfFile:path];
NSLog(#"READING -- PList Data Count: %d", [myArray count]);
return [[NSMutableArray alloc] initWithContentsOfFile:path];
}
For some reason mergedSymbolsArray will not write to a plist. I am not sure why?
I am able to write the following into a plist:
[tickers addObject:[NSDictionary dictionaryWithObjectsAndKeys:#"GOOG", #"symbol", #"2044", #"id", nil]];
[tickers addObject:[NSDictionary dictionaryWithObjectsAndKeys:#"AAPL", #"symbol", #"686", #"id", nil]];
[tickers addObject:[NSDictionary dictionaryWithObjectsAndKeys:#"YHOO", #"symbol", #"4177", #"id", nil]];
[Utils writeObjectToPList:tickers];
Why doesn't the first block of code write to a plist?
ADDITIONAL NOTES:
Here is an example of a dictionary the mergedSymbolsArray contains:
{
"charts_count" = 2;
"created_at" = "2010-04-12T16:37:32Z";
exchange = NASDAQ;
"followers_count" = 259;
id = 8404;
industry = "<null>";
"messages_count" = 1436;
ric = "GRPN.O";
sector = "<null>";
symbol = GRPN;
title = Groupon;
"updated_at" = "2011-09-05T04:17:56Z";
}
I am guessing the writeToFile:atomically method is failing because cannot be written?
Make sure all the objects you keep in the array are the property list objects (NSString, NSData, NSArray, or NSDictionary).
It fails because dta contains sector = "<null>" whose value is interpreted as NSNull and cannot be written to a plist.
I convert NSArray or NSDictionary to NSData before serializing. Following is a category on nsarray for serializing and deserializing. This comfortableby handles some data being nsnull
-(BOOL)writeToPlistFile:(NSString*)filename{
NSData * data = [NSKeyedArchiver archivedDataWithRootObject:self];
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * documentsDirectory = [paths objectAtIndex:0];
NSString * path = [documentsDirectory stringByAppendingPathComponent:filename];
BOOL didWriteSuccessfull = [data writeToFile:path atomically:YES];
return didWriteSuccessfull;
}
+(NSArray*)readFromPlistFile:(NSString*)filename{
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * documentsDirectory = [paths objectAtIndex:0];
NSString * path = [documentsDirectory stringByAppendingPathComponent:filename];
NSData * data = [NSData dataWithContentsOfFile:path];
return [NSKeyedUnarchiver unarchiveObjectWithData:data];
}
Check the return value of [myData writeToFile:path atomically:YES]; please. If it's NO, some errors have occurred while writing.Try to alloc-init the NSMutableArray instead of creating an autoreleased one.
Try adding a forward slash to your file name Ie:
NSString *path = [documentsDirectory stringByAppendingString:#"/mobile-watchlist.plist"];
I'm trying to get a UITableView to read it's data from a file. I've attempted it like this:
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullFileName = [NSString stringWithFormat:#"%#/entries.plist", documentsDirectory];
self.dataForTable = [[NSMutableArray alloc] initWithContentsOfFile:fullFileName];
This compiles fine, but when saving something to the file in the following snippet, the file is not saved nor anything is written to the array:
NSMutableDictionary*userDictionary;
userDictionary = [[NSMutableDictionary alloc] init];
[userDictionary setObject:name.text forKey:#"name"];
[userDictionary setObject:email.text forKey:#"email"];
[userDictionary setObject:serial.text forKey:#"serial"];
[userDictionary setObject:notes.text forKey:#"notes"];
[userDictionary setObject:[NSNumber numberWithInt:[licenseType selectedRowInComponent:0]] forKey:#"license_type"];
[userDictionary setObject:[date date] forKey:#"date"];
[userDictionary setObject:[NSNumber numberWithBool:[paymentSwitch isOn]] forKey:#"payment"];
NSString*dirToSaveTo = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents"];
NSString*fileName = [NSString stringWithFormat:#"%#.plist",name.text];
NSString*saveName = [dirToSaveTo stringByAppendingPathComponent:fileName];
[userDictionary writeToFile:saveName atomically:NO];
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullFileName = [NSString stringWithFormat:#"%#/entries.plist", documentsDirectory];
[self.dataForTable addObject:name.text];
NSLog(#"%#",self.dataForTable);
[self.dataForTable writeToFile:fullFileName atomically:YES];
The NSLog just returns (null). The *plist file is never written. What am I doing wrong?
Almost certainly this line is failing, and you're not checking whether it returned nil:
self.dataForTable = [[NSMutableArray alloc] initWithContentsOfFile:fullFileName];
Once it does return nil, every other call to it does nothing. The most likely problems are that the file path you have constructed is incorrect and doesn't point to the file, or that the file is not a proper plist.