(前回)Cocoaの日々: Cocoaの日々: BlogAssistant(12) - Queueの導入: plistの保存
Safariプラグインで保存した plist を読み出し、CoreDataへ保存する実装を管理アプリで行う。
まず QueueManager を作った。ここで plist の読み込みから CoreDataへの保存までのコントロールを行う。
QueueManager.m
- (void)loadFiles { NSFileManager* fm = [NSFileManager defaultManager]; NSString* path = [[PathManager sharedManager] queuePath]; NSError* error = nil; NSArray* files = [fm contentsOfDirectoryAtPath:path error:&error]; if (error) { NSLog(@"ERROR(loadFiles): %@", error); return; } ModelManager* mm = [ModelManager sharedManager]; for (NSString* filename in files) { if ([[filename pathExtension] isEqualToString:@"plist"]) { ResourceTransfer* resTran = [ResourceTransfer resourceTransferWithContentsOfFile:filename]; if (resTran) { [mm insertResourceWithTransfer:resTran]; } } } }
まず所定のフォルダ(Queue)内の plist ファイルの一覧を作る。次に plist 毎に ResourceTransfer を作成する。そしてそれを ModelManager に渡して CoreData へ保存する。
plist から ResourceTransfer を作るメソッドはこんな感じ。
ResourceTransfer.m
+ (ResourceTransfer*)resourceTransferWithContentsOfFile:(NSString*)filename { return [[[ResourceTransfer alloc] initWithContentsOfFile:filename] autorelease]; } - (id)initWithContentsOfFile:(NSString*)filename { self = [super init]; if (self) { NSString* path = [[[PathManager sharedManager] queuePath] stringByAppendingPathComponent:filename]; NSDictionary* inputDict = [NSDictionary dictionaryWithContentsOfFile:path]; if (inputDict) { for (NSString* key in [inputDict allKeys]) { [self setValue:[inputDict valueForKey:key] forKey:key]; } } } return self; }
CoreDataへの保存は -[ModelManager insertResourceWithTransfer:] で行う。
ModelManager.m
-(BOOL)insertResourceWithTransfer:(ResourceTransfer*)resTran { NSManagedObjectContext* moc = [[CoreDataManager sharedManager] managedObjectContext]; Resource* resource = (Resource*)[NSEntityDescription insertNewObjectForEntityForName:@"Resource" inManagedObjectContext:moc]; NSArray* keys = [Utility getPropertyNamesOf:resTran]; for (NSString* key in keys) { [resource setValue:[resTran valueForKey:key] forKey:key]; } NSError* error = nil; [moc save:&error]; if (error) { NSLog(@"ERROR(insertResourceWithTransfer:): %@", error); return NO; } return YES; }
+[Utility getPropertyNamesOf:] は以前紹介した class_copyPropertyList( ) を使ってプロパティ一覧を取得するユーティリティ。前回も ResourceTransfer 内で使っていたがリファクタリングして Utilityクラスへ移した。
Utility.m
+ (NSArray*)getPropertyNamesOf:(id)object { NSMutableArray* propertyNames = [NSMutableArray array]; unsigned int outCount, i; objc_property_t *properties = class_copyPropertyList([object class], &outCount); for(i = 0; i < outCount; i++) { objc_property_t property = properties[i]; NSString *propertyName = [NSString stringWithUTF8String:property_getName(property)]; [propertyNames addObject:propertyName]; } free(properties); return propertyNames; }
クラスの依存関係はこんな感じ。
ResourceTransfer と Resource の間の依存関係は無い。この間の依存関係を知っているのは ModelManager だけ。
実行してみよう。Safariでクリップしておき、管理アプリ側で -[QueueManager loadFiles] を呼び出す。
表示された。動いているようだ。
ソースコード(GitHub)
xcatsan's BlogAssistant at 2010-02-04 - GitHub