NSCoding:保存自定义对象并加载到表视图iOS

时间:2014-04-01 07:53:19

标签: ios iphone objective-c cocoa-touch

我尝试了解保存数据的应用程序。我有一个自定义对象。

@interface CellObject : NSObject <NSCoding>

@property (nonatomic, strong) NSString *links;
@property (nonatomic, strong) NSString *title;
@property (assign) BOOL isFavorite;

@end



#import "CellObject.h"

@implementation CellObject
@synthesize title, links;
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:title forKey:@"title"];
    [aCoder encodeObject:links forKey:@"links"];
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super init];
    if (self){
        [self setTitle:[aDecoder decodeObjectForKey:@"title"]];
        [self setLinks:[aDecoder decodeObjectForKey:@"links"]];
    }
    return self;
}

并且控制器在单元格中必须是我的对象。

#import "SettingsViewController.h"
#import "SettingsCell.h"
#import "CellObject.h"

#define kFileName @"archive"
#define kDataKey  @"Data"

@implementation SettingsViewController


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self)
    {
        self.title = @"Settings";

        [[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIFont fontWithName:@"Helvetica" size:20.0f], NSFontAttributeName, nil] forState:UIControlStateNormal];

    }
    return self;
}


-(NSString *)dataFilePath {
    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    return [documentsDirectory stringByAppendingPathComponent:kFileName];

}



- (void)viewDidLoad
{
    [super viewDidLoad];



    UIApplication *app = [UIApplication sharedApplication];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:app];

    [_rssObjectArray removeAllObjects];
    _rssObjectArray = nil;

    if(!_rssObjectArray)
    {
    _rssObjectArray = [[NSMutableArray alloc]init];
    }

        _resourceTV = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) style:UITableViewStylePlain];
        [_resourceTV setAutoresizesSubviews:YES];

        [_resourceTV setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
       [_resourceTV setDataSource:self];
       [_resourceTV setDelegate:self];

    [self.view addSubview:_resourceTV];

    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(showAlert)];

    NSString *filePath = [self dataFilePath];
    if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
        NSMutableData* data = [[NSMutableData alloc] initWithContentsOfFile:[self dataFilePath]];

        NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];

        CellObject *cellObj = [unarchiver decodeObjectForKey:kDataKey];
        [unarchiver finishDecoding];
    }
}

-(void)applicationWillResignActive:(NSNotification *)notification
 {
    CellObject *cellObj = [[CellObject alloc] init];

      NSMutableData *data = [[NSMutableData alloc] init];
      NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:cellObj forKey:kDataKey];
    [archiver finishEncoding];
    [data writeToFile:[self dataFilePath] atomically:YES];

}

- (void)showAlert
{
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Enter name" message:@"And internet adress" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Ok", nil];

    alertView.alertViewStyle = UIAlertViewStyleLoginAndPasswordInput;

    UITextField *bottomField = [alertView textFieldAtIndex:0];
    [bottomField setPlaceholder:@"Name"];

    UITextField *footerField = [alertView textFieldAtIndex:1];
    [footerField setPlaceholder:@"Internet adress"];
    footerField.secureTextEntry = NO;

    alertView.tag = -1;


    [alertView show];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return _rssObjectArray.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellIdentifier = [SettingsCell cellIdentifier];

    SettingsCell *sCell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (!sCell)
    {
        sCell = [[SettingsCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
    }

    CellObject *object = [_rssObjectArray objectAtIndex:indexPath.row];

    sCell.linkLabel.text = object.links;
    sCell.nameLabel.text = object.title;

    sCell.favorite.selected = object.isFavorite;

    return sCell;
}

//change rows in table

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
     return YES;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        [_rssObjectArray removeObjectAtIndex:indexPath.row];
        [_resourceTV deleteRowsAtIndexPaths:@[indexPath] withRowAnimation: UITableViewRowAnimationTop];
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 50;
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex && (alertView.alertViewStyle == UIAlertViewStyleLoginAndPasswordInput))
    {

        CellObject *object = nil;

        if (alertView.tag == -1) {
            object = [[CellObject alloc]init];


            [_rssObjectArray addObject:object];

        } else {



        object = [_rssObjectArray objectAtIndex:alertView.tag];
        }

        object.links = [[alertView textFieldAtIndex:0] text];
        object.title = [[alertView textFieldAtIndex:1] text];

        [_resourceTV reloadData];
    }
}


-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Enter name" message:@"And internet adress" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Ok", nil];

    alertView.alertViewStyle = UIAlertViewStyleLoginAndPasswordInput;

    UITextField *bottomField = [alertView textFieldAtIndex:0];
    [bottomField setPlaceholder:@"Name"];

    UITextField *footerField = [alertView textFieldAtIndex:1];
    [footerField setPlaceholder:@"Internet adress"];
    footerField.secureTextEntry = NO;

    CellObject *cellObj = [_rssObjectArray objectAtIndex:indexPath.row];
    bottomField.text = cellObj.links;
    footerField.text = cellObj.title;

    alertView.tag = indexPath.row;

    [alertView show];

}

@end

在互联网上找到教程,但是它们不是很有帮助,告诉我怎么做,重启应用程序后对象会持续存在,它们还留在单元格中吗?

1 个答案:

答案 0 :(得分:1)

在viewDidLoad中:

- (void)viewDidLoad
{
    // ...

    if ([[NSFileManager defaultManager] fileExistsAtPath:[self dataFilePath]]) { // Check if the file exist.
        NSMutableData* data = [[NSMutableData alloc] initWithContentsOfFile:[self dataFilePath]]; // Retrieve the data from the file

        self.rssObjectArray = [[NSKeyedUnarchiver unarchiveObjectWithData:data] mutableCopy];
    }
}

和你的

- (NSString *)dataFilePath
{
    NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"CustomFeed.plist"];
    /*BOOL result = [NSKeyedArchiver archiveRootObject:self.rssObjectArray toFile:path];
    // This line above erase the file when it's called, remove all the code i commented.
    if(result == YES)
    {
        NSLog(@"Array saved");
    }*/
    return path;
}

通过这些修改,我测试了你的应用程序并且它正常工作。