使用NSUserDefaults保存我的数组

时间:2014-12-08 04:56:48

标签: objective-c arrays singleton persistence nsuserdefaults

我遇到NSUserDefaults时遇到问题。请耐心等待,因为这是我第一次实施它。

我尝试存储到手机的数据是我的e-commerce应用购物车的一系列对象,相同的数组会加载我的购物车table view以显示添加到我的购物车的所有商品大车。

阵列中有两种不同类型的对象具有不同的属性(NSStringsNSNumbers:产品名称,大小,价格等)。有人向我建议,我的阵列中可能有太多属性要放入plist中,这就是没有任何东西可以保存的原因。

这是我的代码。我使用的是singleton方法,并已将此代码插入我的singleton类。

- (void)save
{  
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];  
    [userDefaults setObject:self.cartArray forKey:@"tableViewCartData"];
    [userDefaults synchronize];
    NSURL *plistURL = [[self documentsDirectory]URLByAppendingPathComponent:@"cartItems.plist"];
    [self.cartArray writeToURL:plistURL atomically:YES];
}

-(void)load
{
    NSURL *plistURL = [[self documentsDirectory]URLByAppendingPathComponent:@"cartItems.plist"];

    self.cartArray = [NSMutableArray arrayWithContentsOfURL:plistURL];
    if (self.cartArray == nil)
    {
        self.cartArray = [NSMutableArray new];
    }
}

-(NSURL *)documentsDirectory
{   
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSURL *url = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask].firstObject;
    return url;
}

我可以在我的文档目录中看到plist被创建了。但那里什么都没有。

修改

我刚才在日志中注意到了这一点:

  

CityBicycleCompany [4239:249463]属性列表对格式无效:200   (属性列表不能包含'CFType'类型的对象)2014-12-07   20:52:10.037 CityBicycleCompany [4239:249463]尝试设置一个   非属性列表对象(       “”)作为键tableViewCartData的NSUserDefaults / CFPreferences值

我不确定这意味着什么。什么是CFType?

修改2

此刻是self.cartArray的po(将一个对象添加到“cart”)。 ChosenAccessory是我添加到购物车中的自定义object

<__NSArrayM 0x79788380>( <ChosenAccessory: 0x796d1f80> )

1 个答案:

答案 0 :(得分:0)

您无法直接在NSUserDefaults中保存包含自定义对象的数组,Apple doc:首选项值必须是标准属性列表对象类型之一:NSData,NSString,NSNumber,NSDate,NSArray或NSDictionary。 a link

解决方法是为自定义对象提供编码器/解码器。 在你的Item类中添加:

- (void)encodeWithCoder:(NSCoder *)coder{

//for each attribute of your class that you need to store, (NSString, Date, NSNumber...)

    [coder encodeObject:self.recordID forKey:@"recordID"];//NSNumber
    [coder encodeObject:self.phone forKey:@"phone"];//NSString
    [coder encodeObject:self.date forKey:@"date"];//nsdate

}

- (Item*)initWithCoder:(NSCoder *)decoder {
    if (self == [super init]) {
        self.recordID = [decoder decodeObjectForKey:@"recordID"];
        self.phone = [decoder decodeObjectForKey:@"phone"];
        self.date =[decoder decodeObjectForKey:@"date"];
    }
    return self;
}
在你的viewController中

是如何初始化并保存你的项目数组

-(void)initItems{

    self.itemsArray = [[NSMutableArray alloc]init];
    NSUserDefaults* preferences = [NSUserDefaults standardUserDefaults];

    NSString* savedItems = @"savedItems";

    if([preferences objectForKey: savedItems] == nil)
    {
//handle

    }
    else
    {
        NSMutableArray *archiveArray = [preferences objectForKey: savedItems];
        for (NSData* itemObj in archiveArray) {
            Item *item = [NSKeyedUnarchiver unarchiveObjectWithData: itemObj];
            [self.itemsArray addObject:item];
        }

    }

}


-(void)saveItemsArray{

    NSUserDefaults* preferences = [NSUserDefaults standardUserDefaults];

    NSString* savedItems = @"savedItems";

    NSMutableArray *archiveArray = [NSMutableArray arrayWithCapacity:[self.itemsArray count]];

    for (Item* item in self.itemsArray) {
        NSData* itemObj = [NSKeyedArchiver archivedDataWithRootObject:item];
        [archiveArray addObject:itemObj];

    }

    [preferences setObject:archiveArray forKey: savedItems];
    [preferences synchronize];

}