I'm new to iOS programming and having written a simple reminders style app, I'm now rewriting it to implement the MVC model correctly as previously all my code was inside View Controllers.
I have a custom class called Event with properties name, time, repeat etc and then the following structure:
Model class
Retrieves, processes and and saves data to and from NSUserDefaults
RootViewController
Creates an instance of the Model object and asks the model to return all the Events objects from NSUserDefaults
then displays them in a UITableView
EditEventViewController
[editEventVC initWithEvent:theEvent];
Passes the specific event object that was selected in the table cell via init method and displays all the properties available for editing
EditEventPropertyViewController
[editEventPropertyVC initWithValue:propertyValue];
Passes value of property to edit (e.g. event name) via init method and returns the user updated value via a delegate method
Is this the correct way to implement this app?
What's the best way to save the updated Event object in NSUserDefaults
via the Model after finishing with the EditEventViewController? Via a delegate? Currently I am reloading the uitableview data on viewWillAppear in the rootViewController so it will have to save the updated data before retrieving it again.
Thanks
You can store the collection of Event
in NSUserDefaults
. Since its a custom class, you need to implement NSCoding
protocol for serialization to NSUserDefaults
.
//Event.h
@interface Event : NSObject<NSCoding>
@property (nonatomic, copy) NSString *name;
@property (nonatomic, strong) NSDate *time;
@property (nonatomic) NSInteger repeat;
- (void)save;
+ (NSArray *)allEvents;
//Event.m
#define kSavedEvents @"SavedEvents"
#pragma mark - Encoding
- (void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:self.name forKey:@"EventName"];
[encoder encodeObject:self.time forKey:@"EventTime"];
[encoder encodeObject:@(self.repeat) forKey:@"EventRepeat"];
}
#pragma mark - Decoding
- (id)initWithCoder:(NSCoder *)decoder
{
self = [super init];
if (self)
{
_name = [decoder decodeObjectForKey:@"EventName"];
_time = [decoder decodeObjectForKey:@"EventTime"];
_repeat = [[decoder decodeObjectForKey:@"EventRepeat"]integerValue];
}
return self;
}
You need to archive the data while storing to NSUserDefaults and unarchive when fetching
(void)save
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *savedData = [defaults objectForKey:kSavedEvents];
NSMutableArray *savedEvents = [@[] mutableCopy];
//Some events are already there in there
if (savedData) {
savedEvents = [[NSKeyedUnarchiver unarchiveObjectWithData:savedData]mutableCopy];
}
[savedEvents addObject:self];
//Archiving the savedEvents to data
NSData *newEventData = [NSKeyedArchiver archivedDataWithRootObject:savedEvents];
[defaults setObject:newEventData forKey:kSavedEvents];
[defaults synchronize];
}
+ (NSArray *)allEvents
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data = [defaults objectForKey:kSavedEvents];
if (data)
{
return [NSKeyedUnarchiver unarchiveObjectWithData:data];
}
return nil;
}
Hope this will get you started.