iOS MVC - Passing data back and forth to view cont

2019-03-01 02:30发布

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

1条回答
▲ chillily
2楼-- · 2019-03-01 02:47

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.

查看更多
登录 后发表回答