私は iPad と iPod 用のクックブック アプリケーションを作成しており、クックブック クラスにレシピ クラスの配列があります。
@interface Cookbook : NSObject<NSCoding>{
NSMutableArray* recipes;
}
それは私のCookbookクラスにあり、私のレシピクラスにはこれがあります:
@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;
}
私の Recipe.m では:
-(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 での save メソッドの試み:
-(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"];
}