diff --git a/Source/AFMMRecordResponseSerializer/AFMMRecordResponseSerializer.m b/Source/AFMMRecordResponseSerializer/AFMMRecordResponseSerializer.m index a454881..03f5c2a 100644 --- a/Source/AFMMRecordResponseSerializer/AFMMRecordResponseSerializer.m +++ b/Source/AFMMRecordResponseSerializer/AFMMRecordResponseSerializer.m @@ -107,11 +107,23 @@ - (NSManagedObjectContext *)backgroundContext { } - (NSArray *)recordsFromMMRecordResponse:(MMRecordResponse *)recordResponse - backgroundContext:(NSManagedObjectContext *)backgroundContext { - __block NSMutableArray *objectIDs = [NSMutableArray array]; + backgroundContext:(NSManagedObjectContext *)backgroundContext + options:(MMRecordOptions *)options { + NSMutableArray *objectIDs = [NSMutableArray array]; [backgroundContext performBlockAndWait:^{ + NSError *error; NSArray *records = [recordResponse records]; + if (![backgroundContext save:&error]) { + NSDictionary *parameters = nil; + if (error.localizedDescription != nil) { + parameters = [options.debugger parametersWithKeys:@[MMRecordDebuggerParameterErrorDescription] + values:@[error.localizedDescription]]; + } + [options.debugger handleErrorCode:MMRecordErrorCodeCoreDataSaveError + withParameters:parameters]; + return; + } for (MMRecord *record in records) { [objectIDs addObject:[record objectID]]; @@ -120,9 +132,11 @@ - (NSArray *)recordsFromMMRecordResponse:(MMRecordResponse *)recordResponse NSMutableArray *records = [NSMutableArray array]; - for (NSManagedObjectID *objectID in objectIDs) { - [records addObject:[self.context objectWithID:objectID]]; - } + [self.context performBlockAndWait:^{ + for (NSManagedObjectID *objectID in objectIDs) { + [records addObject:[self.context objectWithID:objectID]]; + } + }]; return records; } @@ -186,11 +200,12 @@ - (id)responseObjectForResponse:(NSURLResponse *)response MMRecordResponse *recordResponse = [MMRecordResponse responseFromResponseObjectArray:responseArray initialEntity:initialEntity - context:self.context + context:backgroundContext options:options]; NSArray *records = [self recordsFromMMRecordResponse:recordResponse - backgroundContext:backgroundContext]; + backgroundContext:backgroundContext + options:options]; *error = [debugger primaryError]; diff --git a/Source/MMRecord/MMRecordProtoRecord.h b/Source/MMRecord/MMRecordProtoRecord.h index 7428869..b31e1a7 100644 --- a/Source/MMRecord/MMRecordProtoRecord.h +++ b/Source/MMRecord/MMRecordProtoRecord.h @@ -132,7 +132,8 @@ */ + (MMRecordProtoRecord *)protoRecordWithDictionary:(NSDictionary *)dictionary entity:(NSEntityDescription *)entity - representation:(MMRecordRepresentation *)representation; + representation:(MMRecordRepresentation *)representation + primaryKeyValue:(id)primaryKeyValue; ///--------------------------- diff --git a/Source/MMRecord/MMRecordProtoRecord.m b/Source/MMRecord/MMRecordProtoRecord.m index e6c5927..b1fa2fb 100644 --- a/Source/MMRecord/MMRecordProtoRecord.m +++ b/Source/MMRecord/MMRecordProtoRecord.m @@ -39,12 +39,13 @@ @implementation MMRecordProtoRecord + (MMRecordProtoRecord *)protoRecordWithDictionary:(NSDictionary *)dictionary entity:(NSEntityDescription *)entity - representation:(MMRecordRepresentation *)representation { + representation:(MMRecordRepresentation *)representation + primaryKeyValue:(id)primaryKeyValue { NSParameterAssert([NSClassFromString([entity managedObjectClassName]) isSubclassOfClass:[MMRecord class]]); MMRecordProtoRecord *protoRecord = [[MMRecordProtoRecord alloc] init]; protoRecord.dictionary = dictionary; protoRecord.entity = entity; - protoRecord.primaryKeyValue = [representation primaryKeyValueFromDictionary:dictionary]; + protoRecord.primaryKeyValue = primaryKeyValue; protoRecord.relationshipProtosDictionary = [NSMutableDictionary dictionary]; protoRecord.relationshipDescriptionsDictionary = [NSMutableDictionary dictionary]; protoRecord.hasRelationshipPrimarykey = [representation hasRelationshipPrimaryKey]; diff --git a/Source/MMRecord/MMRecordResponse.m b/Source/MMRecord/MMRecordResponse.m index 367928f..064155d 100644 --- a/Source/MMRecord/MMRecordResponse.m +++ b/Source/MMRecord/MMRecordResponse.m @@ -223,35 +223,32 @@ - (MMRecordProtoRecord *)protoRecordWithRecordResponseObject:(id)recordResponseO } id primaryValue = [representation primaryKeyValueFromDictionary:recordResponseObject]; - MMRecordProtoRecord *proto = [recordResponseGroup protoRecordForPrimaryKeyValue:primaryValue]; - - if (proto == nil) { - proto = [MMRecordProtoRecord protoRecordWithDictionary:recordResponseObject - entity:entity - representation:representation]; - - - if (proto.hasRelationshipPrimarykey == NO) { - if (proto.primaryKeyValue == nil) { - if (self.options.entityPrimaryKeyInjectionBlock != nil) { - proto.primaryKeyValue = self.options.entityPrimaryKeyInjectionBlock(proto.entity, - proto.dictionary, - parentProtoRecord); - } - } - - if (proto.primaryKeyValue == nil) { + if (primaryValue == nil) { + if (self.options.entityPrimaryKeyInjectionBlock != nil) { + primaryValue = self.options.entityPrimaryKeyInjectionBlock(entity, + recordResponseObject, + parentProtoRecord); + if (primaryValue == nil) { MMRecordDebugger *debugger = self.options.debugger; - NSString *errorDescription = [NSString stringWithFormat:@"Creating proto record with no primary key value. \"%@\"", proto]; + NSString *errorDescription = [NSString stringWithFormat:@"No primary key value for response object. \"%@\"", recordResponseObject]; NSDictionary *parameters = [debugger parametersWithKeys:@[MMRecordDebuggerParameterRecordClassName, MMRecordDebuggerParameterErrorDescription, MMRecordDebuggerParameterEntityDescription] - values:@[proto.entity.managedObjectClassName, + values:@[entity.managedObjectClassName, errorDescription, - proto.entity]]; + entity]]; [debugger handleErrorCode:MMRecordErrorCodeMissingRecordPrimaryKey withParameters:parameters]; } } + } + MMRecordProtoRecord *proto = [recordResponseGroup protoRecordForPrimaryKeyValue:primaryValue]; + + if (proto == nil) { + proto = [MMRecordProtoRecord protoRecordWithDictionary:recordResponseObject + entity:entity + representation:representation + primaryKeyValue:primaryValue]; + } else { [representation.marshalerClass mergeDuplicateRecordResponseObjectDictionary:recordResponseObject withExistingProtoRecord:proto];