LoginSignup
4
4

More than 5 years have passed since last update.

CoreDataのリレーションシップをNSValueTransfomerで擬似的に実現する

Posted at

サーバーサイドに問い合わせてテーブルをJSONで取得しているとします。
データの例

Product
 id
 name
 typeId

Type
 id
 name

ProductのtypeIdはTypeのidを参照しています。

このデータをCoreDataに登録してCocoaBindingsでUIに表示するとしましょう。
通常はProductを登録するときにRelationを使用してtypeIdを差し替えると思います。(Typeの方も)

CoreData Entity

Product
 id
 name
 type <--> Type

Type
 id
 name
 products <--> Product

これでわかりますかね。ProductのtypeがRelationになっていて、Typeのインスタンスが登録されます。

ところがこれ登録するのが結構面倒です。

ですので、これをNSValueTransFormer を使って擬似的に実装します。

CoreData Entityは

Product
 id
 name
 typeId

Type
 id
 name

JSONをそのまま登録。

Typeのidをnameに変換するValue Transformerを作成。

@interface TypeTransformer : NSValueTransformer
@end
@implementation TypeTransformer
+ (void)load
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        [NSValueTransformer setValueTransformer:[self new] forName:@"TypeTransformer"];
    });
}
- (id)transformedValue:(id)value
{
    if(![value isKindOfClass:[NSNumber class]]) return nil;

    NSManagedObjectContext *context; // ManagedObjectContextがここに入っているとします

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Type"];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"id = %@", value];
    [request setPredicate:predicate];
    NSArray *array = [context executeFetchRequest:request error:NULL];
    if([array count] == 0) return nil;

    return [array[0] valueForKey:@"name"];
}
@end

これで、CocoaBindingsのkeyPathにtypeIdを指定し、ValueTransformerにTypeTransformerを指定すれば、そのidのTypeのnameが取得(表示)できるようになります。

Typeに複数のカラムがある場合はその数だけNSValueTransformerを作成すればOKです。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4