我正在为 iPad 和 iPod 制作一个 Cookbook 应用程序,并且我的 Cookbook 类中有一系列我的 Recipe 类。
@interface Cookbook : NSObject<NSCoding>{
NSMutableArray* recipes;
}
那是在我的食谱课上,在我的食谱课上我有这个:
@interface Recipe : NSObject<NSCoding>{
NSString* name;
NSMutableArray* ingredients; //List of ingredients for the recipe
UIImage* recipePicture;
NSMutableArray* instructions;
unsigned int prepTime;//in seconds
NSDate* dateAdded;
}
(实际上我这里有更多变量,但我不想过多地淹没它)
我的问题基本上在于保存/加载功能。我之前在这里问过一个类似的问题: 如何保存不是属性列表对象的 Objective-C 对象,或者有比属性列表更好的方法吗?
这让我决定最好使用 NSCoding,而且我也已经按照 NSCoding 建议的方式为它实现了一个方法。
我的主要问题是我无法存储和成功检索食谱。
我也很难将目录添加到我的 RecipeList.plist 文件中以存储食谱。
任何帮助将不胜感激,因为这是我无法继续制作此应用程序的原因。
在我的 Cookbook.m 中,我有:
-(id) initWithCoder:(NSCoder *)aDecoder{
NSLog(@"Init With Coder - Cookbook");
if(self = [super init]){
recipes = [aDecoder decodeObjectForKey:@"recipes"];
}
return self;
}
在我的食谱中:
-(id) initWithCoder:(NSCoder *)aDecoder{
if(self = [super init]){
name = [aDecoder decodeObjectForKey:@"name"];
ingredients = [aDecoder decodeObjectForKey:@"ingreds"];
recipePicture = [aDecoder decodeObjectForKey:@"recipePict"];
}
return self;
}
再一次,我有更多的变量,这只是为了简单。此外,这是我尝试获取 RecipeList.plist 的文件路径:
+(NSString*) filePath{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
path = [path stringByAppendingPathComponent:@"RecipeList.plist"];
NSLog(@"%@",path);
return path;
}
我在 AppDelegate.m 中尝试保存方法:
-(void) save:(NSString *)path cookbook:(Cookbook *)cookbook{
BOOL b = [[NSFileManager defaultManager] fileExistsAtPath:path];
NSLog(@"File exists: %i",b); //1 = exists, 0 = doesn't
NSMutableData* data = [[NSMutableData alloc] init];
if(data){ //If the data object was successfully initialized
NSKeyedArchiver* archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
if(archiver){
//Encode the recipe using the coder method defined in recipe.
[archiver encodeInt:1 forKey:@"Version"];
[archiver encodeObject:cookbook forKey:@"Cookbook"];
[archiver finishEncoding];
[data writeToFile:path atomically:YES];
}
}
}
和我的加载方法:
-(Cookbook *) loadCookbook:(NSString *)path{
BOOL b = [[NSFileManager defaultManager] fileExistsAtPath:path];
NSLog(@"File exists: %i",b);
Cookbook* ret = nil;
NSData* data = [NSData dataWithContentsOfFile:path];
if(data){
NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
int version = [unarchiver decodeIntForKey:@"Version"];
if(version == 1){
ret = (Cookbook*) [unarchiver decodeObjectForKey:@"Cookbook"];
}
[unarchiver finishDecoding];
}
return ret;
}
我的 Recipe 类也有一个与此非常相似的保存和加载方法。
再一次,我们将不胜感激任何帮助,并感谢您花时间阅读本文。
编辑:这是 Recipe.m 中的 encodeWithCoder 方法,为简洁起见省略了一些变量:
-(void) encodeWithCoder:(NSCoder *)aCoder{
NSLog(@"Encoding Recipe.");
[aCoder encodeObject:name forKey:@"name"];
[aCoder encodeObject:ingredients forKey:@"ingreds"];
[aCoder encodeObject:recipePicture forKey:@"recipePict"];
[aCoder encodeObject:instructions forKey:@"instructs"];
[aCoder encodeObject:category forKey:@"categ"];
[aCoder encodeObject:dateAdded forKey:@"dateAdd"];
[aCoder encodeInt:prepTime forKey:@"prepTime"];
}
在 Cookbook.m 中:
-(void) encodeWithCoder:(NSCoder *)aCoder{
NSLog(@"Encoding cookbook.");
[aCoder encodeObject:recipes forKey:@"recipes"];
}