I have read several posts about this but I'm not able to fix the error. If someone could please help.
Here is the code I use. I have an NSMutableArray called list.
-(void) awakeFromNib
{
prefs=[[NSUserDefaults standardUserDefaults]retain];
if ([prefs arrayForKey:#"list"]) {
list=[[NSMutableArray alloc]initWithArray:[prefs objectForKey:#"list"]];
}
else {
list=[[NSMutableArray alloc]init];
}
}
-(void)saveData
{
NSLog(#"saving data!");
[prefs setObject:list forKey:#"list"];
}
- (void)dealloc {
[self saveData];
[prefs synchronize];
[prefs release];
}
You cannot store UIView instances in the user defaults, but only objects that can be serialized in a property list (see here) Also, as #Justin said, do not retain or release the defaults object.
Thank you. However, I had earlier read that you cannot save an NSMutableArray in NSUserDefaults so I attempted to convert it to NSData and then use it.
Here's my ViewController.m file:
-(id)initWithCoder:(NSCoder *)aDecoder
{
self=[[calViewController alloc]init];
if (self!=nil) {
self.list=[aDecoder decodeObjectForKey:#"list"];
}
return self;
}
-(void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:list forKey:#"list"];
}
And here's my AppDelegate.m file:
-(void) applicationDidFinishLaunching:(UIApplication *)application
{
NSLog(#"Application did finish launching");
defaults=[NSUserDefaults standardUserDefaults];
NSData *dataRepresentingSavedArray=[defaults objectForKey:#"lastArray"];
if (dataRepresentingSavedArray!=nil) {
NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
if (oldSavedArray != nil)
{
listAr = [[NSMutableArray alloc] initWithArray:oldSavedArray];
else
{
listAr = [[NSMutableArray alloc] init];
NSLog(#"listAr: %#",listAr);
}
}
}
-(void) applicationWillTerminate:(UIApplication *)application
{
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:listAr] forKey:#"lastArray"];
}
I've never used UserDefaults before and I absolutely confused. I've read all the docs but I don't seem to be getting it right!
EDIT:
-(void) applicationDidFinishLaunching:(UIApplication *)application
{
NSLog(#"Application did finish launching");
defaults=[NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:#"lastArray"]) {
NSData *dataRepresentingSavedArray=[defaults objectForKey:#"lastArray"];
if (dataRepresentingSavedArray!=nil) {
NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
if (oldSavedArray != nil)
listAr = [[NSMutableArray alloc] initWithArray:oldSavedArray];
}
}
else
{
listAr = [[NSMutableArray alloc] init];
NSLog(#"listAr: %#",listAr);
}
}
Related
I am trying use CoreData, but when I add it to my project I only get two new methods :
- (NSPersistentContainer *)persistentContainer
and
- (void)saveContext
Now I can't get old methods to work with CoreData, and I can't find any tutorials with these new methods and Objective-C. How can I save and get data from CoreData using persistentContainer in Xcode 8 with Objective-c?
You can Get context as -
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
or as in Objective-C
NSManagedObjectContext *context = ((AppDelegate*)[[UIApplication sharedApplication] delegate]).persistentContainer.viewContext;
And fetch data like -
var resultArray = try self.context.fetch(EntityName.fetchRequest())
or as in Objective-C
NSFetchRequest<EntityName *> *fetchRequest = [EntityName fetchRequest];
NSError *error ;
NSArray *resultArray= [context executeFetchRequest:fetchRequest error:&error];
And fetch data with sorting -
var resultArray = [EntityName]()
do {
let request : NSFetchRequest<EntityName> = EntityName.fetchRequest()
let sortDescriptor = NSSortDescriptor(key: "somekey", ascending: true)
let sortDescriptors = [sortDescriptor]
request.sortDescriptors = sortDescriptors
resultArray = try self.context.fetch(request)
} catch {
print("Error")
}
or as in Objective-C
NSFetchRequest<EntityName *> *fetchRequest = [EntityName fetchRequest];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"someKey" ascending:YES];
fetchRequest.sortDescriptors = #[sortDescriptor];
NSError *error ;
NSArray *resultArray= [context executeFetchRequest:fetchRequest error:&error];
And add data like -
let entityNameObj = EntityName(context: context)
entityNameObj.title = "title"
or as in Objective-C
NSManagedObject *entityNameObj = [NSEntityDescription insertNewObjectForEntityForName:#"EntityName" inManagedObjectContext:context];
[entityNameObj setValue:#"someValue" forKey:#"someKey"];
And save context like -
do {
try self.context.save()
} catch _ as NSError {
print("Error")
}
or as in Objective-C
[((AppDelegate*)[[UIApplication sharedApplication] delegate]) saveContext];
-(void)profileDatabase {
NSManagedObjectContext* context=[ADM.persistentContainer viewContext];
NSManagedObject *profile=[NSEntityDescription insertNewObjectForEntityForName:#"Profile" inManagedObjectContext:context];
[profile setValue:[self.serverResponseOfProfileDict objectForKey:#"firstName"] forKey:#"firstName"];
[profile setValue:[self.serverResponseOfProfileDict objectForKey:#"surName"] forKey:#"surName"];
[profile setValue:[self.serverResponseOfProfileDict objectForKey:#"batchID"] forKey:#"batchID"];
[profile setValue:[self.serverResponseOfProfileDict objectForKey:#"profileImagePath"] forKey:#"profileImagePath"];
[profile setValue:[self.serverResponseOfProfileDict objectForKey:#"registeredEmail"] forKey:#"registeredEmail"];
[profile setValue:[self.serverResponseOfProfileDict objectForKey:#"role"] forKey:#"role"];
[profile setValue:[self.serverResponseOfProfileDict objectForKey:#"studentID"] forKey:#"studentID"];
NSLog(#"userObj:%#",profile);
NSError* error;
[context save:&error];
NSFetchRequest *fetchRequest=[[NSFetchRequest alloc]initWithEntityName:#"Profile"];
fetchRequest.returnsObjectsAsFaults=NO;
NSArray* results=[context executeFetchRequest:fetchRequest error:&error];
NSLog(#"Result:%#",results);
NSManagedObject *result=[results objectAtIndex:0];
[ADM.databaseResponseOfProfileDict setObject:[result valueForKey:#"firstName"] forKey:#"firstName"];
[ADM.databaseResponseOfProfileDict setObject:[result valueForKey:#"surName"] forKey:#"surName"];
[ADM.databaseResponseOfProfileDict setObject:[result valueForKey:#"batchID"] forKey:#"batchID"];
[ADM.databaseResponseOfProfileDict setObject:[result valueForKey:#"profileImagePath"] forKey:#"profileImagePath"];
[ADM.databaseResponseOfProfileDict setObject:[result valueForKey:#"registeredEmail"] forKey:#"registeredEmail"];
[ADM.databaseResponseOfProfileDict setObject:[result valueForKey:#"role"] forKey:#"role"];
[ADM.databaseResponseOfProfileDict setObject:[result valueForKey:#"studentID"] forKey:#"studentID"];
NSLog(#"dic:%#",ADM.databaseResponseOfProfileDict);}
I have found a solution using Objective C. It runs, but I'm not sure that it is the correct solution.
- (void)dbManager {
NSManagedObjectContext *context = self.persistentContainer.viewContext;
NSError *error = nil;
if ([context hasChanges] && ![context save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(#"Unresolved error %#, %#", error, error.userInfo);
abort();
}
NSManagedObject *customAnimal = [NSEntityDescription insertNewObjectForEntityForName:#"Animals" inManagedObjectContext:context];
[customAnimal setValue:#"Lion" forKey:#"type"];
[customAnimal setValue:#"Rabit" forKey:#"name"];
[customAnimal setValue:#"Blue" forKey:#"color"];
[customAnimal setValue:#12 forKey:#"age"];
NSLog(#"Get data from DB");
NSMutableArray* animalsArray;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"Animals"];
animalsArray = [[context executeFetchRequest:fetchRequest error:nil] mutableCopy];
NSLog(#"array is %#", animalsArray); // array is (
"<Animals: 0x6000000aee80> (entity: Animals; id: 0x60000022e120 <x-coredata:///Animals/tAAC7332D-6BEF-441C-9041-0ECB57469FA62> ; data: {\n age = 12;\n color = Blue;\n name = Rabit;\n type = Lion;\n})"
}
For all the beginners out there, this will give you the basic idea.
welcome.m
==========
#import "welcomepage.h"
#import "Register.h"
#import "login.h"
#import "AppDelegate.h"
#import "Student+CoreDataProperties.h"
#import "loginbtn.h"
#import "King+CoreDataProperties.h"
#interface welcomepage ()
{
AppDelegate *a;
NSManagedObjectContext *context;
}
#end
#implementation welcomepage
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (IBAction)login:(id)sender
{
loginbtn *lb=[[loginbtn alloc]init];
[self.navigationController pushViewController:lb animated:YES];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)register:(id)sender
{
a=(AppDelegate *)[UIApplication sharedApplication].delegate;
NSManagedObjectContext *context1=((AppDelegate *)[UIApplication sharedApplication].delegate).persistentContainer.viewContext;
Student *ss=[NSEntityDescription insertNewObjectForEntityForName:#"Student" inManagedObjectContext:context1];
ss.name=[NSString stringWithFormat:#"%#",_txtfld1.text];
ss.age=[NSString stringWithFormat:#"%#",_txtfld2.text];
ss.place=[NSString stringWithFormat:#"%#",_txtfld3.text];
[a saveContext];
if (_txtfld1.text.length && _txtfld2.text.length && _txtfld3.text.length != 0)
{
UIAlertView *al=[[UIAlertView alloc]initWithTitle:#"THANK YOU" message:#"DATA SUCESSFULLY SAVER. YOU CAN LOGIN NOW WITH YOUR PASSWORD AND NAME" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[al show];
_txtfld1.text=#"";
_txtfld2.text=#"";
_txtfld3.text=#"";
Register *rg=[[Register alloc]init];
[self.navigationController pushViewController:rg animated:YES];
}
else
{
UIAlertView *al2=[[UIAlertView alloc]initWithTitle:#"WARRNING" message:#"PLEASE FILL THE DATA COMPLETELY" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[al2 show];
}
}
===================================================
Register.m
==========
#import "Register.h"
#import "AppDelegate.h"
#import "Student+CoreDataProperties.h"
#import "welcomepage.h"
#interface Register ()<UITableViewDelegate,UITableViewDataSource>
{
AppDelegate *a;
NSManagedObjectContext *context01;
NSArray *array01;
}
#end
#implementation Register
- (void)viewDidLoad
{
[super viewDidLoad];
a=((AppDelegate *)[UIApplication sharedApplication].delegate);
context01=((AppDelegate *)[UIApplication sharedApplication].delegate).persistentContainer.viewContext;
// specifying nsrequest and nsentity
NSFetchRequest *req=[[NSFetchRequest alloc]init];
NSEntityDescription *entity01=[NSEntityDescription entityForName:#"Student" inManagedObjectContext:context01];
[req setEntity:entity01];
// putting datas from reto array
NSError *err=nil;
array01=[context01 executeFetchRequest:req error:&err];
// Do any additional setup after loading the view from its nib.
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return array01.count;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 3;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *ci=#"hai";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:ci];
if (cell==nil) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ci];
}
if (indexPath.row==0) {
cell.textLabel.text=[[array01 objectAtIndex:indexPath.section]valueForKey:#"name"];
}
if (indexPath.row==1) {
cell.textLabel.text=[[array01 objectAtIndex:indexPath.section]valueForKey:#"age"];
}
if (indexPath.row==2) {
cell.textLabel.text=[[array01 objectAtIndex:indexPath.section]valueForKey:#"place"];
}
return cell;
}
==================================================
Loginbtn.m
============
#import "loginbtn.h"
#import "AppDelegate.h"
#import "Student+CoreDataProperties.h"
#import "login.h"
#interface loginbtn ()
{
AppDelegate *a;
NSArray *arraylb;
}
#end
#implementation loginbtn
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)lgbtn:(id)sender
{
a=(AppDelegate *)[UIApplication sharedApplication].delegate;
//xcode 8.2.1 specification code
NSManagedObjectContext *context=((AppDelegate *)[UIApplication sharedApplication].delegate).persistentContainer.viewContext;
//creating feathch request and entity
NSFetchRequest *req=[[NSFetchRequest alloc]init];
NSEntityDescription *entity=[NSEntityDescription entityForName:#"Student" inManagedObjectContext:context];
[req setEntity:entity];
// setting predicate
NSPredicate *pre=[NSPredicate predicateWithFormat:#"age like %# and place like %#",_txt1.text,_txt2.text];
[req setPredicate:pre];
//creating error and array to store
NSError *err=nil;
arraylb=[[NSArray alloc]init];
arraylb=[context executeFetchRequest:req error:&err];
login *lg=[[login alloc]init];
if (arraylb.count!=0)
{
lg.array001=arraylb;
}
//
// if (arraylb.count!=0)
//// {
////
//// lv *lvi=[[lv alloc]init];
////
//// //passing value
//// lvi.array001=arraylb;
////
////
//// //lv.str1=self.tf1.text;
//// //lv.str2=self.tf2.text;
//// [self.navigationController pushViewController:lvi animated:YES];
////
////
//// }
//// else
//// {
//
// self.lb.text=#"Invalid username & password";
//
// }
//
[self.navigationController pushViewController:lg animated:YES];
}
=====================================================
Lohin.m
=========
#import "login.h"
#import "Student+CoreDataProperties.h"
#import "AppDelegate.h"
#import "loginbtn.h"
#interface login ()
{
AppDelegate *a;
NSArray *array01;
}
#end
#implementation login
- (void)viewDidLoad
{
[super viewDidLoad];
_txt11.text=[[_array001 objectAtIndex:0]valueForKey:#"name"];
_txt22.text=[[_array001 objectAtIndex:0]valueForKey:#"age"];
_txt33.text=[[_array001 objectAtIndex:0]valueForKey:#"place"];
// Do any additional setup after loading the view from its nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
// Dispose of any resources that can be recreated.
}
[array addObject:textdata.text];
NSUserDefaults *save = [NSUserDefaults standardUserDefaults];
[save setObject:array forKey:#"success" ];
[save synchronize];
-(void) viewDidLoad
NSUserDefaults *viewdata1 = [NSUserDefaults standardUserDefaults];
[viewdata1 objectForKey:#"success"];
[viewdata1 synchronize];
[tabledata reloadData];
Once the data is saved in the array, how do I upload it once the app runs again? I want the data to load back in the table once.
The first step is to retrieve it from user defaults. The second step is not to drop it on the floor.
[viewdata1 objectForKey:#"success"];
This does one, but not the other: You retrieve it, but then you drop it on the floor.
You need to store the object as the value of a property (which means you will need to declare a property for that purpose), then, in your table view's data source, return the count of that array as your number of rows and objects in the array (or properties of those objects) as the row values.
Also, you shouldn't need to call synchronize, especially after retrieving the value.
You should make like this:
TSTableViewController.h:
#property(nonatomic, readwrite, retain) NSMutableArray* dataSource;
TSTableViewController.m:
- (id) init
{
if ((self = [super init]))
{
[[NSNotificationCenter defaultCenter] addObserver: self selector: #selector(applicationDidEnterBackground:)
name: UIApplicationDidEnterBackgroundNotification
object: nil];
}
return self;
}
- (void) applicationDidEnterBackground: (NSNotification*) notification
{
[[NSUserDefaults standardUserDefaults] setObject: self.dataSource
forKey: #"success" ];
}
- (void) viewDidLoad
{
[super viewDidLoad];
NSArray* array = [[NSUserDefaults standardUserDefaults] objectForKey: #"success"];
if (array)
{
self.dataSource = [NSMutableArray arrayWithArray: array];
}
else
{
self.dataSource = [[[NSMutableArray alloc] init] autorelease];
}
[tableView reloadData];
}
- (void) addDataToDataSource
{
[self.dataSource addObject: textdata.text];
[tabledata reloadData];
}
- (void) dealloc
{
[dataSource release];
dataSource = nil;
[super dealloc];
}
I've created a Document Application for Mac OSX to work with CoreDataModel.
Now I'm trying to programmatically save a value in the coredata when a button is clicked.
I'm able to save a value when the app start:
- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
[super windowControllerDidLoadNib:aController];
NSManagedObjcetContext *moc = [self managedObjectContext];
NSSet *session = [moc fetchObjectsForEntityName:#"Sessions" withPredicate:nil];
NSLog(#"%d", (int)[session count]);
NSManagedObject *obj = [NSEntityDescription insertNewObjectForEntityForName:#"Sessions"
inManagedObjectContext:moc];
[obj setValue:#"TEST" forKey:#"name"];
[obj setValue:[NSDate dateWithTimeIntervalSinceReferenceDate:112700] forKey:#"start"];
[obj setValue:[NSDate dateWithTimeIntervalSinceReferenceDate:118700] forKey:#"stop"];
}
but I want to save a value of a counter inside a NSObject. So I've tried to create a function in the PersistentDocument like the previous passing a value, but the count of the coredata elements is 0, so I think that is not referencing to the correct Entity.
Can anyone explain me how to do that or how this can works?
Thanks
Ale
EDIT:
I'll try to be more clear.
I've a chrono counter with START and STOP button. I want to save the value of the timer, when is stopped, in the coredata using another button SAVE. The managing of the counter is in an NSObject CounterObject.
How can I do it? Now I'm able to write in the core data only from the PersistentDocument caling a function from windowControllerDidLoadNib. I want to call a function that write in the coredata my counter value, but if I call the function in the PersistentDocument from the CounterObject the log that I've inserted show 0 elements instead of 4. So it's not correctly passed.
Here is the code:
// Document
#import "Document.h"
#import "NSManagedObjectContext.h"
#implementation Document
- (id)init
{
self = [super init];
if (self) {
}
return self;
}
- (NSString *)windowNibName
{
// Override returning the nib file name of the document
// If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
return #"Document";
}
- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
[super windowControllerDidLoadNib:aController];
[self saveTimeMOC:[NSDate dateWithString:#"11:23:34"]];
}
-(IBAction)saveTimeMOC:(NSDate *)time {
NSManagedObjectContext *moc = [self managedObjectContext];
NSSet *session = [moc fetchObjectsForEntityName:#"Sessions" withPredicate:nil];
NSLog(#"%d", (int)[session count]);
NSManagedObject *obj = [NSEntityDescription insertNewObjectForEntityForName:#"Sessions"
inManagedObjectContext:moc];
[obj setValue:#"TEST" forKey:#"name"];
[obj setValue:time forKey:#"start"];
[obj setValue:[NSDate dateWithTimeIntervalSinceReferenceDate:118700] forKey:#"stop"];
}
+ (BOOL)autosavesInPlace
{
return YES;
}
#end
// CounterObject
#import "CounterObject.h"
#import "Document.h"
#implementation CounterObject
#synthesize contText, startButton, stopButton;
-(id)init {
self = [super init];
if (self) {
}
return self;
}
- (IBAction)startContatore:(id)sender {
stopButton.title = #"Stop";
[stopButton setEnabled:YES];
[startButton setEnabled:NO];
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(gestioneTimer) userInfo:nil repeats:YES];
}
- (IBAction)stopContatore:(id)sender {
if (timer != nil) {
[timer invalidate];
timer = nil;
}
if (stopButton.title != #"Reset") {
[startButton setEnabled:YES];
stopButton.title = #"Reset";
startButton.title = #"Continue";
} else if (stopButton.title == #"Reset") {
stopButton.title = #"Stop";
[stopButton setEnabled:NO];
startButton.title = #"Start";
timerCont = 0;
contText.stringValue = [NSString stringWithFormat:#"00:00"];
}
}
- (void)gestioneTimer {
timerCont += 1;
int minutes = floor(timerCont/60);
int seconds = trunc(timerCont - minutes * 60);
contText.stringValue = [NSString stringWithFormat:#"%02i:%02i", minutes, seconds];
}
- (IBAction)saveTime:(id)sender {
Document *moc = [[Document alloc] init];
[moc saveTimeMOC:[NSDate dateWithString:#"13:45:22"]];
}
If you want to add an Object to core data, you can do this :
- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
[super windowControllerDidLoadNib:aController];
NSManagedObjcetContext *moc = [self managedObjectContext];
// But be sure that [self managedObjectContext] is the correct one; you can do this to see if //it's not a null value : NSLog(#"%#",[self managedObjectContext]);
NSManagedObject *obj = [NSEntityDescription insertNewObjectForEntityForName:#"Sessions"
inManagedObjectContext:moc];
[obj setValue:#"TEST" forKey:#"name"];
[obj setValue:[NSDate dateWithTimeIntervalSinceReferenceDate:112700] forKey:#"start"];
[obj setValue:[NSDate dateWithTimeIntervalSinceReferenceDate:118700] forKey:#"stop"];
}
And a request for Core Data is :
-(voi)testRequestCoreData {
NSError *error =nil;
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init]autorelease];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"Sessions" inManagedObjectContext:moc];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
....
}
i need to be able to save the contents of my table view which is given data by an NSMutableArray to a txt file and then need to reopen that file automatically when the window containing the table view. i am making an application for mac
thanks
this is the code for the data source:
#import "tableViewData.h"
#import "Customer.h"
#implementation tableViewData
-(id) init
{
self = [super init];
if (self) {
list = nil;
filepath = #"/Users/Gautambir/Desktop/CustomerNames.txt";
if ([[NSFileManager defaultManager]fileExistsAtPath:filepath]) {
list = [[NSMutableArray alloc] initWithContentsOfFile:filepath];
}
else
list = [[NSMutableArray alloc]initWithObjects:name,memberNumber ,nil];
[list writeToFile:filepath atomically:YES];
}
return self;
}
-(NSInteger)numberOfRowsInTableView:(NSTableView *)tableView{
return [list count];
}
-(id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{
Customer *Customer = [list objectAtIndex:row];
NSString *identifier = [tableColumn identifier];
return [Customer valueForKey:identifier];
}
-(void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{
Customer *Customer = [list objectAtIndex:row];
NSString *identifier = [tableColumn identifier];
[Customer setValue:object forKey:identifier];
}
-(void)save{
[list writeToFile:filepath atomically:YES];
}
-(IBAction)add:(id)sender{
[list addObject:[[Customer alloc]init]];
[tableView reloadData];
NSLog (#"array:%#",list);
}
-(IBAction)remove:(id)sender{
NSInteger row = [tableView selectedRow];
if (row != -1) {
[list removeObjectAtIndex:row];
}
[tableView reloadData];
}
-(void)dealloc
{
[super dealloc];
}
#end
and this is the .m file for the customer object class:
#import "Customer.h"
#implementation Customer
#synthesize name;
#synthesize memberNumber;
-(id) init
{
self = [super init];
if(self) {
name = #"Test";
int i = arc4random()%1000000000000000000;
if (i<0) {
memberNumber = i*-1;
}
else
memberNumber = i;
}
return self;
}
-(void)dealloc
{
[name release];
[super dealloc];
}
-(id)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self)
{
name = [[aDecoder decodeObjectForKey:#"name"]retain];
memberNumber = [aDecoder decodeIntForKey:#"memberNumeber"];
}
return self;
}
-(void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:name forKey:#"name"];
[aCoder encodeInt:memberNumber forKey:#"memberNumber"];
}
#end
strong text
im sorry to post another answer - i misread the tags, and my first answer was relying to iOS.
this is the way to do it in OSX:
saving
NSMutableArray *array = ... //your array
[array addObject:...];
[array addObject:...];
[array addObject:...];
...
// then use an NSData to store the array
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:array];
NSString *path = #"/Users/User/path...";
[data writeToFile:path options:NSDataWritingAtomic error:nil];
retrieving
NSMutableArray *archive = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
sebastian
I cant get the archivedDataWithRootObject method to call encodeWithCoder, it seems pretty simple from what I understand but it doesn't work.
Here's the code:
#import <Foundation/Foundation.h>
#interface Details : NSObject <NSCoding>{
NSMutableArray *myArray;
}
#property(nonatomic,retain) NSMutableArray *myArray;
#end
#import "Details.h"
#implementation Details
#synthesize myArray;
-(id)init{
[super init];
return self;
}
-(id)initWithCoder:(NSCoder *)aDecoder{
NSLog(#"initWithCoder");
if (self = [super init])
{
self.myArray = [[aDecoder decodeObjectForKey:#"details"]retain];
}
return self;
}
- (NSMutableArray*)getDetails{
NSLog(#"getDetials");
// NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *details = [[NSUserDefaults standardUserDefaults] objectForKey:#"details"];
if (details != nil){
NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:details];
if (oldSavedArray != nil)
self.myArray = [[NSMutableArray alloc] initWithArray:oldSavedArray];
else
self.myArray = [[NSMutableArray alloc] initWithCapacity:1];
}
return self.myArray;
}
- (void) addDetails:(NSMutableArray *)details{
NSLog(#"add Details");
[self.myArray addObject:details];
[NSKeyedArchiver archivedDataWithRootObject:self.myArray];
}
- (void) encodeWithCoder:(NSCoder *)coder;
{
NSLog(#"encodeWithCoder");
[coder encodeObject:self.myArray forKey:#"details"];
}
#end
NSLog(#"encodeWithCoder") doesn't run.
I might be missing something, If anyone has any ideas it would be appreciated.
[NSKeyedArchiver archivedDataWithRootObject:self.myArray];
You are telling the NSKeyedArchiver to archive the myArray variable, not the object you have just implemented <NSCoding> with!
Also that method returns NSData * which you then have to write to disk separately if needed.
Try this:
NSData * archivedData = [NSKeyedArchiver archivedDataWithRootObject:self];