読者です 読者をやめる 読者になる 読者になる

CoreDataのレコードをJSONに変換する

一つ前のエントリーとは逆に、Objective-CのオブジェクトをJSONへ、のパターン。
素直なNSArrayとかNSDictionaryを処理する場合には特に注意する点はなし*1
SQLiteがストアのCoreDataで,FetchしたResultのNSArrayをJSONとして渡したい場合等は注意が必要。

- (void)sampleMethod
{
  NSError *error=nil;
  NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"ModelName"];
  NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
                                      initWithKey:@"createdAt" ascending:YES];
  [request setSortDescriptors:@[sortDescriptor]];
  NSArray *fetchResult = [[self managedObjectContext] executeFetchRequest:request
                                                                error:&error];
  NSData *data=nil;
  @try {
    data = [NSJSONSerialization dataWithJSONObject:fetchResult options:NSJSONReadingAllowFragments error:NULL];
  }
  @catch (NSException *ex) {
    NSLog(@"%@",[ex name]);
    // NSInvalidArgumentException
    NSLog(@"%@",[ex reason]);
    //Invalid type in JSON write (ModelName)
  }
}

(fault)フォールティングになっているからじゃないかなーと。
それ以前にNSArrayの要素も、NSString, NSNumber, NSArray, NSDictionary以外だと駄目かもしれません。

試してみました

適当なクラスを作成して空の場合と、@propertyを定義したパターンと試してみたらInvalid type in JSON write (ClassName)だったので、単純にNSString, NSNumber, NSArray, NSDictionary以外のタイプは駄目、これらにする必要があるようです。失礼しました。リファレンスにも書いてありましたね・・。


なので、各NSManagedObjectをNSDictionaryにした配列を作成し、処理するといいかと。

- (void)sampleMethod
{
  NSError *error=nil;
  NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"ModelName"];
  NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
                                      initWithKey:@"createdAt" ascending:YES];
  [request setSortDescriptors:@[sortDescriptor]];
  NSArray *fetchResult = [[self managedObjectContext] executeFetchRequest:request
                                                                error:&error];
  NSMutableArray *mArray = [NSMutableArray array];
  for (ModelName *m in fetchResult) {
    [mArray addObject:@{@"title" : m.title,@"content" : m.content}];
  }
  NSData *d = [NSJSONSerialization dataWithJSONObject:mArray options:NSJSONReadingAllowFragments error:NULL];
  NSString *s = [[NSString alloc] initWithData:d encoding:NSUTF8StringEncoding];
  NSLog(@"json:%@",s);
  //json:[{"title":"title1","content":"<span id=\"fugafuga\">hogehgoe<\/span>"},{"title":"title2","content":"second content"}]
}

こんな感じ。

*1:要素がNSString, NSNumber, NSArray, NSDictionary