将自定义对象附加到txt文件并将其读回

时间:2015-06-29 06:37:02

标签: ios xcode ios-app-group

我正在为iOS开发todo list app。我有一个名为ToDoItem的自定义类。我的设计是将用户内容写入文本文件,并在用户再次打开应用程序时从文件中读回。我已经为我的ToDoItem类实现了确认NSCoding协议的方法。

下面给出了写入数据的方法

- (void)loadData{
if ([[NSFileManager defaultManager] fileExistsAtPath:_appFile]) {

    NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:_appFile];

    if (handle) {
        NSData *data = [handle readDataToEndOfFile];
        if (data) {
            ToDoItem *item;
            NSMutableArray *arr = [NSKeyedUnarchiver unarchiveObjectWithData:data];

            for (item in arr) {
                [_toDoItems addObject:item];
            }
        }
        [handle closeFile];
    } 
}}

下面给出了读取数据的方法

- (void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:_itemName forKey:ITEMNAME];
[aCoder encodeObject:_date forKey:DATE];
[aCoder encodeBool:_isDone forKey:DONE];
[aCoder encodeInteger:_row forKey:ROW];
}

- (id)initWithCoder:(NSCoder *)aDecoder{
self = [super init];
if (self) {
    _itemName = [aDecoder decodeObjectForKey:ITEMNAME];
    _date = [aDecoder decodeObjectForKey:DATE];
    _isDone = [aDecoder decodeBoolForKey:DONE];
    _row = [aDecoder decodeIntegerForKey:ROW];
}
return self;
}

现在我只能将单个ToDoItem写入文件并能够读取它。如果我写了多个ToDoItem的对象,在阅读它的时候我会得到" [NSKeyedUnarchiver initForReadingWithData:]:难以理解的存档"例外。 我担心的是,当用户重新启动应用程序时,我只想在用户保存数据并再次检索所有信息时附加我的ToDoItem对象。

NSCoding方法

test.sh

提前致谢

2 个答案:

答案 0 :(得分:1)

添加新项目时,无法将新数据附加到文件末尾 - 您需要每次都完全替换该文件。

您需要将新项目添加到现有项目数组中,然后保存完整数组的存档。如果您的新待办事项视图控制器只返回新项目或nil并在“外部”VC中完成保存,则可能更清晰

<ImageView
        android:id="@+id/icon"
        android:layout_width="@dimen/slidingtab_item_icon_size"
        android:layout_height="@dimen/slidingtab_item_icon_size"
        android:layout_centerInParent="true"
        android:src="@drawable/ic_event_black_18dp"/>

答案 1 :(得分:1)

我建议使用属性列表文件而不是文本文件。 这是一个在plist文件中加载和保存todoItems的解决方案。

<强>假设:

_appFile:一个NSString变量,包含plist文件的路径

__toDoItems:一个初始化的NSMutableArray变量来保存待办事项

两种方法都使用NSPropertyListSerialization,它提供了更多的读写选项

- (void)loadData
{
    NSDictionary *prefs = nil;
    NSData *plistData = [NSData dataWithContentsOfFile:_appFile];
    if (plistData) {
        prefs = (NSDictionary *)[NSPropertyListSerialization
                                        propertyListWithData:plistData
                                        options:NSPropertyListImmutable
                                        format:NULL
                                        error:nil];
    }
    if (prefs) {
        NSArray *itemDataArray = prefs[@"todoItems"];
        if (itemDataArray) {
            [_toDoItems removeAllObjects]; // might be not needed
            for (itemData in itemDataArray) {
                 [_toDoItems addObject:(ToDoItem *)[NSKeyedUnarchiver unarchiveObjectWithData:itemData]];
            }
        }
    }
}


- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    // if cancel button is pressed
    if (sender != self.saveBtn) {
        return;
    }
    // if save button is pressed
    else {
        NSMutableArray *itemDataArray = [[NSMutableArray alloc] init];
        for (ToDoItem *item in _toDoItems) {
            [itemDataArray addObject:[NSKeyedArchiver archivedDataWithRootObject:item]];
        }
        NSError *error = nil;
        NSDictionary *prefs = @{@"todoItems" : itemDataArray};
        NSData *plistData = [NSPropertyListSerialization dataWithPropertyList: prefs
                                                         format:NSPropertyListBinaryFormat_v1_0
                                                        options:0 
                                                          error:&error];

        if (plistData) {
         [plistData writeToFile:_appFile atomically:YES];
     }
        else {
        // do error handling
     }
}