magicalpanda / MagicalRecord

Super Awesome Easy Fetching for Core Data!
Other
10.8k stars 1.79k forks source link

Fix crash when related attribute is a string / MR 3.0 #1158

Closed pronebird closed 6 years ago

pronebird commented 8 years ago

I import a payload presented as array of dictionaries.

[
  {
    "relatedCategoryIdentifier": "Software",
    "string": "Something"
  }
]

Category relationship has userInfo set as following:

screenshot 2015-12-25 16 53 26

While debugging I see it finds the related category using the configured mappedKeyName and relatedAttributed, I also have distinctAttribute set on models.

Looking at the implementation of MR_lookupObjectForRelationship I see that it supports relationship lookup by having a string provided:

// if its a primitive class, than handle singleRelatedObjectData as the key for relationship
if ([singleRelatedObjectData isKindOfClass:[NSString class]] ||
    [singleRelatedObjectData isKindOfClass:[NSNumber class]])
{
    relatedValue = singleRelatedObjectData;
}

So in my case singleRelatedObjectData is a string from relatedCategoryIdentifier. But then MR_importValuesForKeysWithObject is always called and that causes it to crash because it expects enumerable object and NSString is not.

//Look up any existing objects
NSManagedObject *relatedObject = [strongSelf MR_lookupObjectForRelationship:relationshipInfo fromData:localObjectData];

if (relatedObject == nil)
{
    //create if none exist
    NSEntityDescription *entityDescription = [relationshipInfo destinationEntity];
    relatedObject = [entityDescription MR_createInstanceInContext:[strongSelf managedObjectContext]];
}

//import or update
[relatedObject MR_importValuesForKeysWithObject:localObjectData];

The crash used to happen in MR_setRelationship:relatedData::

id relatedObjectData = [relationshipData valueForKeyPath:lookupKey];

Where relationshipData is an instance of NSString.

My fix is to simply avoid calling import for relationship established using string identifier. I don't check for NSDictionary because technically seed data can be an object that implements the same methods of NSDictionary or NSFastEnumeration. This is probably useful for generated seed data for test purposes or whatsoever.

Merry christmas!

pronebird commented 6 years ago

Closing due to absence of interest in proceeding with this PR.

hardikdevios commented 6 years ago

@pronebird No body is here working for MR.

pronebird commented 6 years ago

@hardikdevios not sure what you mean. I needed to clean up the stale PRs to free up the reviewable board.