次のように、サービス呼び出しごとにシングルトンで RestKit マッピングを作成します。
- (void)setupMapping
{
RKObjectManager *objectManager = [RKObjectManager sharedManager];
RKEntityMapping *challengesMapping = [RKEntityMapping mappingForEntityForName:@"Challenge" inManagedObjectStore:[objectManager managedObjectStore]];
[challengesMapping addAttributeMappingsFromDictionary:@{
@"uuid": @"uuid",
@"title": @"title",
@"description": @"challengeDescription",
@"icon": @"icon",
@"active_from": @"activeFrom",
@"active_to": @"activeTo",
@"trigger": @"trigger",
@"show_in_feed": @"showInFeed",
@"points": @"points",
@"trigger": @"trigger",
@"type": @"type",
@"min_level": @"minLevel"
}];
challengesMapping.identificationAttributes = @[ @"uuid" ];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:challengesMapping
pathPattern:CHALLENGE_PATH
keyPath:@"challenges"
statusCodes:[NSIndexSet indexSetWithIndex:SUCCESS]];
[objectManager addResponseDescriptor:responseDescriptor];
RKObjectMapping *sessionMapping = [RKObjectMapping mappingForClass:[TimeStamp class]];
[sessionMapping addAttributeMappingsFromArray:@[@"ts"]];
[objectManager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:sessionMapping
pathPattern:CHALLENGE_PATH
keyPath:nil
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]];
}
と
- (void)setupMapping
{
RKObjectManager *objectManager = [RKObjectManager sharedManager];
RKEntityMapping *festivalsMapping = [RKEntityMapping mappingForEntityForName:@"Festival" inManagedObjectStore:[objectManager managedObjectStore]];
[festivalsMapping addAttributeMappingsFromDictionary:@{
@"uuid": @"uuid",
@"festival": @"festivalDescription",
@"start_ts": @"start_ts",
@"end_ts": @"end_ts",
@"title": @"title"
}];
festivalsMapping.identificationAttributes = @[ @"uuid" ];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:festivalsMapping
pathPattern:GET_FESTIVALS_PATH
keyPath:@"festivals"
statusCodes:[NSIndexSet indexSetWithIndex:SUCCESS]];
[objectManager addResponseDescriptor:responseDescriptor];
RKObjectMapping* sessionMapping = [RKObjectMapping mappingForClass:[TimeStamp class]];
[sessionMapping addAttributeMappingsFromArray:@[@"ts"]];
[objectManager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:sessionMapping
pathPattern:GET_FESTIVALS_PATH
keyPath:nil
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]];
}
最初のマッピング (チャレンジ) の最初のサーバー呼び出しは正常に機能しますが、2 つ目の呼び出し (祭りのマッピング) を行うと、「この NSManagedObjectContext のコーディネーターからオブジェクトの永続ストアに到達できません」というエラーが表示されます。これが Core Data のスレッドの問題である可能性があることは理解していますが、コードで原因を見つけることができません。
コンソールに次の情報が表示されます。
(lldb) po $r0 エラー: 構造体をマテリアライズできませんでした: r0 を読み取ることができませんでした (マテリアライズ) 実行中にエラーが発生しましたmain + 1 at main.m:14
r6 = 0x00000000
r7 = 0x2fd9ccf8
r8 = 0x2fd9cd10
r10 = 0x00000000
r11 = 0x00000000
r12 = 0x00000148
sp = 0x2fd9ccd4
lr = 0x00066f09 MyApp
。 main.m:16 で pc = 0x00066f09 MyApp`main + 117 main.m:16 で cpsr = 0x00000010 5 つのレジスタが使用できませんでした。
編集
サービス/マッピング クラスの 1 つの完全な例を次に示します。以前に使用された同様のパターンを見たことがあります。つまり、GCD シングルトンを使用しています。また、pathPatterns が異なるため、以下のコメントごとに TimeStamp が重複しているとは思いません。正しい?それらを削除しようとしましたが、同じ問題です。Core Data によってサポートされていないため、これは予想されることです
#import "ChallengeService.h"
static ChallengeService __strong *defaultService = nil;
#define CHALLENGE_PATH @"/api/challenges"
@implementation ChallengeService
+ (ChallengeService *)defaultService
{
static dispatch_once_t pred;
dispatch_once(&pred, ^{
defaultService = [[self alloc] initWithPath:CHALLENGE_PATH];
[defaultService setupMapping];
});
return defaultService;
}
- (void)setupMapping
{
RKObjectManager *objectManager = [RKObjectManager sharedManager];
RKEntityMapping *challengesMapping = [RKEntityMapping mappingForEntityForName:@"Challenge" inManagedObjectStore:[objectManager managedObjectStore]];
[challengesMapping addAttributeMappingsFromDictionary:@{
@"uuid": @"uuid",
@"title": @"title",
@"description": @"challengeDescription",
@"icon": @"icon",
@"active_from": @"activeFrom",
@"active_to": @"activeTo",
@"trigger": @"trigger",
@"show_in_feed": @"showInFeed",
@"points": @"points",
@"trigger": @"trigger",
@"type": @"type",
@"min_level": @"minLevel"
}];
challengesMapping.identificationAttributes = @[ @"uuid" ];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:challengesMapping
pathPattern:CHALLENGE_PATH
keyPath:@"challenges"
statusCodes:[NSIndexSet indexSetWithIndex:SUCCESS]];
[objectManager addResponseDescriptor:responseDescriptor];
RKObjectMapping *sessionMapping = [RKObjectMapping mappingForClass:[TimeStamp class]];
[sessionMapping addAttributeMappingsFromArray:@[@"ts"]];
[objectManager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:sessionMapping
pathPattern:CHALLENGE_PATH
keyPath:nil
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]]; }
- (void)getChallengesFromDate:(NSDate *)date
onSuccess:(DidSucceedBlock)successBlock
onError:(DidFailWithErrorBlock)failBlock
{
[defaultService getWithData:nil
fromDate:date
onLoad:^(id object) {
successBlock(object);
} onError:^(NSError *error) {
failBlock(error);
}];
}