2012-11-10 55 views
5

我正在編寫一本Cookbook應用程序,並且我無法找到任何有關如何保存我創建的類(食譜類)的數據的任何信息。我見過的唯一辦法是能拯救這個類作爲一個整體的內容,無需通過使這個方法對我的食譜類單獨的類爲每個對象的每個元素節省:如何保存一個不屬於屬性列表對象的Objective-C對象,或者是否存在比屬性列表更好的方法?

-(void) writeToFile:(NSString *)file atomically:(BOOL)atomic{ 

} 

但是我有絕對不知道如何去實現這個將此對象保存到使用此方法的文件。有些屬性是:

NSString* name; 
UIImage* recipePicture; 
NSDate* dateAdded; 
NSMutableArray* ingredients; //The contents are all NSStrings. 

有誰知道如何去保存配方類的對象? 這讓我瘋狂得不知所措。任何幫助將不勝感激。我已經有一個名爲「RecipeData.plist」的.plist。 我只需要將每個屬性寫入plist,並在運行時用這些屬性初始化配方的新對象?

回答

5

採用:

@interface Recipe : NSObject<NSCoding> 

實現:

- (void)encodeWithCoder:(NSCoder *)coder 
{ 
    [coder encodeObject:name_ forKey:@"name"]; 
    [coder encodeObject:recipePicture_ forKey:@"recipePicture"]; 
    [coder encodeObject:dateAdded_ forKey:@"dateAdded"]; 
    [coder encodeObject:ingredients_ forKey:@"ingredients"]; 

}

// Decode an object from an archive 
- (id)initWithCoder:(NSCoder *)coder 
{ 
    self = [super init]; 
    if (self!=NULL) 
    { 
     name_ = [coder decodeObjectForKey:@"name"]; 
     recipePicture_ = [coder decodeObjectForKey:@"recipePicture"]; 
     dateAdded_ = [coder decodeObjectForKey:@"dateAdded"]; 
     ingredients_ = [coder decodeObjectForKey:@"ingredients"]; 
    } 
    return self; 
} 

現在,在您保存:

- (void) save:(NSString*)path recipe:(Recipe*)recipe 
{ 
    NSMutableData* data=[[NSMutableData alloc] init]; 
    if (data) 
    { 
     NSKeyedArchiver* archiver=[[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; 
     if (archiver) 
     { 
      [archiver encodeInt:1 forKey:@"Version"]; 
      [archiver encodeObject:recipe forKey:@"Recipe"]; 
      [archiver finishEncoding]; 

      [data writeToFile:path atomically:YES]; 

     } 
    } 
} 

而在負荷:

- (Recipe*) load:(NSString*)path 
{ 
    Recipe* ret=NULL; 
    NSData* data=[NSData dataWithContentsOfFile:path]; 
    if (data) 
    { 
     NSKeyedUnarchiver* unarchiver=[[NSKeyedUnarchiver alloc] initForReadingWithData:data]; 
     if (unarchiver) 
     { 
      int version=[unarchiver decodeIntForKey:@"Version"]; 
      if (version==1) 
      { 
       ret=(Recipe*)[unarchiver decodeObjectForKey:@"Recipe"]; 
      } 
      [unarchiver finishDecoding]; 
     } 
    } 
    return ret; 
} 
+0

您應該用其他三分之二的答案更新 - 如何將它編碼爲一個NSData對象以存儲在屬性列表中,以及如何解碼屬性列表中的數據。 – rmaddy

+0

正如我在下面的評論中所說的,非常感謝您花時間向我展示如何做到這一點。這真的是一個很大的幫助。 – crarho

+0

你應該調用'self = [super initWithCoder:coder];'而不是'self = [super init];'。否則,你的超類將沒有它的編碼數據。 –

2

一個選項(除了編碼/解碼)是你的類的每個屬性存儲在字典中。然後,您將字典寫入文件。訣竅是確保放入字典中的每個對象都可以放入plist中。在您展示的四個屬性中,除UIImage之外的所有內容都可以原樣存儲。

-(BOOL)writeToFile:(NSString *)file atomically:(BOOL)atomic{ 
    NSMutableDictionary *data = [NSMutableDictionary dictionary]; 

    [data setObject:name forKey:@"name"]; 
    [data setObject:dateAdded [email protected]"dataAdded"]; 

    NSDate *imageData = UIImagePNGRepresentation(recipePicture); 
    [data setObject:imageData forKey:@"recipePicture"]; 

    // add the rest 

    return [data writeToFile:file atomically:YES]; 
} 

我更新了這個返回BOOL。如果失敗,就意味着兩種情況之一:

  1. 的文件是不恰當的
  2. 你試圖挽救一個非plist中友好的對象在dictonary

您需要添加代碼以避免試圖添加nil對象,如果你有任何。重要的是確保所有的鍵都是字符串,並且只存儲plist友好的對象(NSString,NSNumber,NSDate,NSValue,NSData,NSArray和NSDictionary)。

+0

非常感謝您的幫助。非常感謝 - 這個問題一直在困擾我一段時間。 – crarho