11

私はRestKitを使用しており、要素を解析してコア データに保存したいと考えています。2 つの json ファイルがあります。

最初 (カテゴリ):

[
   {
     "cat_id": 3371,
     "cat_name": "myName",
     "image": 762
   },
   {
     "cat_id": 3367,
     "cat_name": "anotherName",
     "image": 617
   }
]

そして2番目(要素):

[
  {
    "art_id": "1",
    "node": {
      "author": "name"
    },
    "small_url": 0
  },
  {
    "art_id": "12",
    "node": {
      "author": "anotherName"
    },
    "small_url": 0
  }
]

したがって、基本的な考え方は、すべてのカテゴリにいくつかの要素が含まれているということです。だから、これは私の CoreData 構造体です: ここに画像の説明を入力

Restkit サンプルをダウンロードし、TwitterCoreData サンプルを使用しました。私のコードは: AppDelegeta.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSURL *baseURL = [NSURL URLWithString:@"http://globalURL.com"];
    RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:baseURL];
    NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
    RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
    objectManager.managedObjectStore = managedObjectStore;

    RKEntityMapping *categoryMapping = [RKEntityMapping mappingForEntityForName:@"Category" inManagedObjectStore:managedObjectStore];
    categoryMapping.identificationAttributes = @[ @"catId" ];
    [categoryMapping addAttributeMappingsFromDictionary:@{
     @"cat_id": @"catId",
     @"node.author": @"author",
     }];

    RKEntityMapping *elementsMapping = [RKEntityMapping mappingForEntityForName:@"Elements" inManagedObjectStore:managedObjectStore];
    elementsMapping.identificationAttributes = @[ @"artId" ];
    [elementsMapping addAttributeMappingsFromDictionary:@{
     @"art_id": @"artId",
     @"node.author": @"author",
    }];
    [elementsMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"category" toKeyPath:@"category" withMapping:categoryMapping]];
    RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:elementsMapping
                                                                                       pathPattern:nil
                                                                                           keyPath:nil
                                                                                       statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
    [objectManager addResponseDescriptor:responseDescriptor];


    [managedObjectStore createPersistentStoreCoordinator];
    NSString *storePath = [RKApplicationDataDirectory() stringByAppendingPathComponent:@"MyCoreData.sqlite"];
    NSString *seedPath = [[NSBundle mainBundle] pathForResource:@"MyCoreData" ofType:@"sqlite"];
    NSError *error;
    NSPersistentStore *persistentStore = [managedObjectStore addSQLitePersistentStoreAtPath:storePath fromSeedDatabaseAtPath:seedPath withConfiguration:nil options:nil error:&error];
    NSAssert(persistentStore, @"Failed to add persistent store with error: %@", error);

    // Create the managed object contexts
    [managedObjectStore createManagedObjectContexts];

    // Configure a managed object cache to ensure we do not create duplicate objects
    managedObjectStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];



    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

およびViewController.m :

NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Elements"];
NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:@"artId" ascending:NO];
fetchRequest.sortDescriptors = @[descriptor];
[[RKObjectManager sharedManager] getObjectsAtPath:@"/detailaddress/:catId" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
    RKLogInfo(@"Load complete: Table should refresh...");
    NSLog(@"%@",mappingResult);
    [[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:@"LastUpdatedAt"];
    [[NSUserDefaults standardUserDefaults] synchronize];
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
    RKLogError(@"Load failed with error: %@", error);
}];

マッピングのログには「nil」が表示されます。restkit を使用して、最初の json (カテゴリ) からコアデータにデータを保存するにはどうすればよいですか? 私はまだ要素リストを持っていないことを思い出してください。

create new file を使用して NEManagedObject サブクラスを作成すると、Elementsクラスがあります。

@interface Elements : NSManagedObject

@property (nonatomic, retain) NSNumber * artId;
@property (nonatomic, retain) NSString * author;
@property (nonatomic, retain) NSString * title;
@property (nonatomic, retain) NSManagedObject *category;

@end
4

2 に答える 2

41

数か月前の .20 リリースまで RESTKit を使用していました。正直なところ、このライブラリには素晴らしい意図がありますが、私の経験では、私を救うために意図されていたよりもはるかに多くの時間を無駄にしています.

.NET/MVC、PHP、python/Django/TastyPie で作成された API で使用し、Twitter でいくつかのことを行うためにハッキングしました。これはすべて非常に興味深い学問的な演習になりましたが、最終的にはそれ以上のものではありませんでした. RESTKit の古いバージョンと新しいバージョンの両方が、API がリクエストに応答する方法について ALOT を想定しています。

.10 リリースでは、Obj-C ブロックを使用することでかなりの量のカスタマイズが可能になりました。RKRequest の要求/応答をインターセプトして、RESTKit が実行しようとしていたことをほとんどオーバーライドすることができました。これはかなりすごかったようです。.20 リリースでは、すべてが非常に...巧妙になりました(通常、巧妙なコードは良くありません)。

汎用的で順応性を維持しようとする代わりに、RK はあらゆる種類の "便利な" ことを行います。これにより、API が取った (非理想的で現実的な) 形状にそれを詰め込む能力が効果的に奪われます。この時点で、AFNetworkingを使用してすべてのコードを記述することに戻りました。時間をかけて独自の構文解析コードを作成し、単体テストに合格したときに作業が完了したことを確認したいと考えています。意味のあるエラー メッセージを RK からログアウトさせるために何時間も費やす必要はありません。

RK のもう 1 つの問題は、オフラインであることを考慮していないことです。これは、アプリケーションが常にオンラインであり、空の永続ストアを単純にミラーリングするという前提で設計されました。私のアプリケーションはすべて、コンテンツ作成時にオンラインである場合とそうでない場合がある iOS デバイスでコンテンツ作成を処理します。これが私が RK .10 を「カスタマイズ」した主な理由です。.20 での変更を確認したとき、これで十分だと判断し、古い方法に戻りました。

たぶん、私は自分の CRUD/RESTful フレームワークを書くだけかもしれません。なぜなら、アプリケーション開発者にできるだけ責任を負わせずにすべてを行おうとする、非常に特殊なライブラリを使用することに時間を費やすのに飽き始めているからです。このようなフレームワークは、スイス アーミー ナイフである傾向があります。彼らは紙の上では本当に素晴らしく見えます, 彼らはでもすることができます. 優れたソフトウェアがうまく機能することはほとんどありません。

于 2013-02-25T20:32:13.857 に答える
3

これで、各 NSManagedObject のマッピングが作成されました (そしてそれらは機能します) が、今度は "Category" と "Elements" の間の関係を確立する必要があります。

問題は、各要素が属するカテゴリの要素のマッピングに関する情報がないことです (一意のキーがありません)。cat_idしたがって、このキーパスが使用可能であることを確認するには、Elements JSON にを追加する必要があります。

// Elements JSON
[
  {
    "cat_id": "1313",
    "art_id": "1",
    "node": {
      "author": "name"
    },
    "small_url": 0
  },
  ...
]
// Edit keypath in relationship mapping
[elementsMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"cat_id" toKeyPath:@"category" withMapping:categoryMapping]];

さらに、次のメソッドを使用して、マッピングが機能するかどうかを追跡できます。

1) -com.apple.CoreData.SQLDebug 1 // Add in "Arguments" Tab > "Arguments Passed On Launch" 
2) RKLogConfigureByName("RestKit/*", RKLogLevelTrace); // Add to AppDelegate`

編集

マッピング

Elements指定された値でデータ モデルと NSManagedObjectのエンティティを更新しましたか? していないようです。

@interface Elements : NSManagedObject

@property (nonatomic, retain) NSNumber * catId;
@property (nonatomic, retain) NSNumber * artId;
@property (nonatomic, retain) NSString * author;
@property (nonatomic, retain) NSString * title;
@property (nonatomic, retain) NSManagedObject *category;

@end

ルーティング

get リクエストに使用して@"/detailaddress/:catId"いるパスは、有効なパスではないため機能しません。一方では、一般的なオブジェクト マネージャのルーティングを設定したり、応答の説明を定義したりできます。

 // Route for get operation
 [[RKObjectManager sharedManager].router.routeSet addRoute:[RKRoute 
      routeWithClass:[Category class] 
      pathPattern:@"/detailaddress/:catId" 
      method:RKRequestMethodGET]];

 // Response descriptor taken from the Core Data same application 
 RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:categoryMapping pathPattern:@"/detailaddress/:catId" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];     
 [objectManager addResponseDescriptor:responseDescriptor];

 // Use general path for get request
 [[RKObjectManager sharedManager] getObjectsAtPath:@"/detailaddress" ...

ただし、最初にマッピングとデータ モデルが期待どおりに設定されているかどうかを確認してください。

于 2013-02-19T11:15:13.003 に答える