0

I am doing an app as a starter to get some experience, I am making a simple app that stores assignments in a table view. So I have a table view as a main view and a plus button that pulls up a modal view controller that allows the user to enter information about the - class name, assignment title, assignment description, due date, and a switch to turn on/off notifications. These values are stored in a AssignmentInfo model. I need to be able to archive (NSCoding) these values, and add to them when new data is entered. Here is some sample code that might help give a better idea:

AssignmentInfo.h -

@property (nonatomic,strong)NSString *className;
@property (nonatomic,strong)NSString *assignmentDescription;
@property (nonatomic,strong)NSString *assignmentTitle;
@property (nonatomic,strong)NSString *dateTimeString;
@property (nonatomic)bool notifcationStatus;

AddEditViewController.m -

{
    IBOutlet UIDatePicker *dateTimePicker;
}

@property (nonatomic, strong) IBOutlet UITextField *className;
@property (nonatomic, strong) IBOutlet UITextField *assignmentTitle;
@property (nonatomic, strong) IBOutlet UITextField *assignmentDescription;
@property (nonatomic, strong) IBOutlet UISwitch *procrastinationNotificationSwitch;
@property (nonatomic,strong)AssignmentInfo *assignmentInfo;

AddEditViewController.m -

- (IBAction)addTheInfo:(id)sender {

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
    dateFormatter.timeZone = [NSTimeZone defaultTimeZone];
    dateFormatter.timeStyle = NSDateFormatterShortStyle;
    dateFormatter.dateStyle = NSDateFormatterShortStyle;
    NSString *dateTimeString = [dateFormatter stringFromDate: dateTimePicker.date];
    self.assignmentInfo.className = self.className.text;
    self.assignmentInfo.assignmentTitle = self.assignmentTitle.text;
    self.assignmentInfo.assignmentDescription = self.assignmentDescription.text;
    self.assignmentInfo.dateTimeString = dateTimeString;
    NSLog(@"%@",self.assignmentInfo.className);    

    [self dismissViewControllerAnimated:YES completion:nil];

}
AbdelElrafa
  • 881
  • 8
  • 16
  • What do you mean you need to archive them, like, between app launches? – powerj1984 Oct 13 '13 at 02:21
  • @powerj1984 yes exactly. – AbdelElrafa Oct 13 '13 at 02:22
  • It looks like your modal view controller is calling dismissViewControllerAnimated? Likely you want to access its presenting view controller and dismiss the modal view. Also this is probably a good place to send your assignmentInfo object to that presenting view controller. – powerj1984 Oct 13 '13 at 02:42

1 Answers1

1

I'll link a post from the inimitable NSHipster on the subject. http://nshipster.com/nscoding/

NSCoding is a simple protocol, with two methods: -initWithCoder: and encodeWithCoder:. Classes that conform to NSCoding can be serialized and deserialized into data that can be either be archived to disk or distributed across a network.

@interface Book : NSObject <NSCoding>
@property NSString *title;
@property NSString *author;
@property NSUInteger pageCount;
@property NSSet *categories;
@property (getter = isAvailable) BOOL available;
@end

@implementation Book

#pragma mark - NSCoding

- (id)initWithCoder:(NSCoder *)decoder {
    self = [super init];
    if (!self) {
        return nil;
    }

    self.title = [decoder decodeObjectForKey:@"title"];
    self.author = [decoder decodeObjectForKey:@"author"];
    self.pageCount = [decoder decodeIntegerForKey:@"pageCount"];
    self.categories = [decoder decodeObjectForKey:@"categories"];
    self.available = [decoder decodeBoolForKey:@"available"];

    return self;
}

- (void)encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:self.title forKey:@"title"];
    [encoder encodeObject:self.author forKey:@"author"];
    [encoder encodeInteger:self.pageCount forKey:@"pageCount"];
    [encoder encodeObject:self.categories forKey:@"categories"];
    [encoder encodeBool:[self isAvailable] forKey:@"available"];
}

@end

Once your class is setup you can save/restore from disk easily:

// Archive
[NSKeyedArchiver archiveRootObject:books toFile:@"/path/to/archive"];

// Unarchive
[NSKeyedUnarchiver unarchiveObjectWithFile:@"/path/to/archive"];

So in your case you have a class like this:

@property (nonatomic, strong) NSString *className;
@property (nonatomic, strong) NSString *assignmentDescription;
@property (nonatomic, strong) NSString *assignmentTitle;
@property (nonatomic, strong) NSString *dateTimeString;
@property (nonatomic, assign) BOOL notifcationStatus;

So you'd end up with an initWithCoder method like:

#pragma mark - NSCoding

- (id)initWithCoder:(NSCoder *)decoder {
    self = [super init];
    if (!self) {
        return nil;
    }

    self.className = [decoder decodeObjectForKey:@"className"];
    self.assignmentDescription = [decoder decodeObjectForKey:@"assignmentDescription"];
    self.assignmentTitle = [decoder decodeIntegerForKey:@"assignmentTitle"];
    self.dateTimeString = [decoder decodeObjectForKey:@"dateTimeString"];
    self.notifcationStatus = [decoder decodeBoolForKey:@"notifcationStatus"];

    return self;
}

and an encodeWithCoder like:

- (void)encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:self.className forKey:@"className"];
    [encoder encodeObject:self.assignmentDescription forKey:@"assignmentDescription"];
    [encoder encodeInteger:self.assignmentTitle forKey:@"assignmentTitle"];
    [encoder encodeObject:self.dateTimeString forKey:@"dateTimeString"];
    [encoder encodeBool:self.notifcationStatus forKey:@"notifcationStatus"];
}

Now you should be able to just add your newly created objects to an NSMutableArray, and when necessary save that array to disk/load it from disk.

powerj1984
  • 2,216
  • 1
  • 22
  • 34
  • How do I do it so that it is an array of the items that the user enters. – AbdelElrafa Oct 13 '13 at 02:37
  • The modal view controller you are displaying should have a property 'presentingViewController', you should be able to call a method on it to add the new assignment to a NSMutableArray within that class. It might be better to create a protocol and use the delegate pattern here though. – powerj1984 Oct 13 '13 at 02:40
  • So do I need to archive the array too? – AbdelElrafa Oct 13 '13 at 02:42
  • If you want to save the array of assignments between app launches you need to archive the array, yes. If you only want to archive one assignment you could do that. – powerj1984 Oct 13 '13 at 02:44
  • So I wouldn't need to archive all the objects just the array? and how do I create an array to keep adding to it a list of things that display in a table view, and also can delete from it? – AbdelElrafa Oct 13 '13 at 02:47