LoginSignup
18
17

More than 5 years have passed since last update.

NSDictionaryから直接CoreDataへ保存したい

Last updated at Posted at 2013-04-02

WebAPIで取得してきたデータは一旦NSDictionary型で取り扱うかと思います。
こいつをそのままCoreDataに保存できたら便利ですよね。

例として以下の様なフォーマットでAPIのレスポンスが返ってくる場合

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
    <dict>
        <key>notification</key>
        <dict>
            <key>created_at</key>
            <date>2013-03-19T09:22:07Z</date>
            <key>id</key>
            <integer>389</integer>
            <key>notifications_type</key>
            <string>typeA</string>
            <key>notifier_id</key>
            <integer>1</integer>
            <key>notifier_type</key>
            <string>User</string>
            <key>source_id</key>
            <integer>99</integer>
            <key>source_type</key>
            <string>Relationship</string>
            <key>text</key>
            <string>test message1</string>
            <key>updated_at</key>
            <date>2013-03-19T09:22:07Z</date>
            <key>user_id</key>
            <integer>11</integer>
        </dict>
    </dict>
    <dict>
        <key>notification</key>
        <dict>
            <key>created_at</key>
            <date>2013-03-14T07:27:13Z</date>
            <key>id</key>
            <integer>316</integer>
            <key>notifications_type</key>
            <string>typeB</string>
            <key>notifier_id</key>
            <integer>4</integer>
            <key>notifier_type</key>
            <string>User</string>
            <key>source_id</key>
            <integer>241</integer>
            <key>source_type</key>
            <string>Schedule</string>
            <key>text</key>
            <string>message 2</string>
            <key>updated_at</key>
            <date>2013-03-17T06:57:11Z</date>
            <key>user_id</key>
            <integer>11</integer>
        </dict>
    </dict>
</array>
</plist>

対応するモデルは以下のように設定します。
plistの型とプロパティ名を一致させるように登録します

@interface Notification : NSManagedObject

@property (nonatomic, retain) NSDate * created_at;
@property (nonatomic, retain) NSNumber * id;
@property (nonatomic, retain) NSString * text;
@property (nonatomic, retain) NSDate * updated_at;
@property (nonatomic, retain) NSNumber * user_id;
@property (nonatomic, retain) NSString * notifications_type;
@property (nonatomic, retain) NSNumber * notifier_id;
@property (nonatomic, retain) NSString * notifier_type;

@end

また、カテゴリ機能を使ってNSManagedObjectを機能拡張し
プロパティ名一覧を取得できるようにします

#pragma mark - NSManagedObject 拡張
@interface NSManagedObject (propertyNames)
+(NSArray*)propertyNames;
@end

@implementation NSManagedObject(propertyNames)

//プロパテイ名一覧の取得
+(NSArray*)propertyNames
{
    unsigned int cnt;
    objc_property_t *properties =  class_copyPropertyList([self class], &cnt);
    NSMutableArray* propNames = [NSMutableArray arrayWithCapacity:cnt];
    for (int i =0; i< cnt; i++) {
        objc_property_t property = properties[i];
        const char* propName = property_getName(property);
        NSString* propertyName = [NSString stringWithUTF8String:propName];
        [propNames addObject:propertyName];
    }

    free(properties);
    return propNames;
}


@end

ここまでお膳立てしますと以下のコードで代入処理ができるようになります。


//dictの中にAPIの取得した情報が格納されている

Notification* notification = [NSEntityDescription
                        insertNewObjectForEntityForName:@"Notification"
                        inManagedObjectContext:self.managedObjectContext];

[notification setValuesForKeysWithDictionary:[dict dictionaryWithValuesForKeys:[Notification propertyNames]]];


jsonがインターフェースとなる場合、plistと違って型情報が値と文字列しか無いため
さらなる工夫が必要になるかもしれません。

18
17
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
18
17