3lvis / Sync

JSON to Core Data and back. Swift Core Data Sync.
MIT License
2.55k stars 263 forks source link

to-many key not allowed here - Many to Many relationships #202

Closed rswilem closed 8 years ago

rswilem commented 8 years ago

Hey guys!

I have an issue with the 'many-to-many' relationship. I think it's a bug in Sync though I'm not completely sure.

I have the following datamodel: screen shot 2016-04-28 at 15 01 07

Basically, a user has tags (localKey: favouriteTags, remoteKey: user_favorite_tags) and a tag can have many users.

user.favouriteTags is an NSOrderedSet. tag.users is a NSSet.

When I sync a user with the following object:

"first_name": "Fred"; "user_favorite_tags" = ( { hashtag = "#fineline"; id = 6; name = "Fine line"; type = 2; } );

The user.favouriteTags gets filled as expected. Whenever I update the user_favorite_tags with another tag (or more), the tag gets overwritten as expected.

However, whenever I try to "remove" the tag, thus syncing the following object:

"first_name": "Fred"; "user_favorite_tags" = ( );

The app crashes with the log below.

Any clues? Am I doing something wrong perhaps? Can I sync an empty array with many-to-many? It seems like it's a one or more relationship rather than a zero or more. I am using the latest version of Sync. (1.6.4)

* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'to-many key not allowed here' * First throw call stack: ( 0 CoreFoundation 0x000000010c7b9d85 exceptionPreprocess + 165 1 libobjc.A.dylib 0x0000000110356deb objc_exception_throw + 48 2 CoreData 0x000000010c410fff -[NSSQLGenerator newSQLStatementForRequest:ignoreInheritance:countOnly:nestingLevel:nestIsWhereScoped:] + 1583 3 CoreData 0x000000010c3037e3 -[NSSQLGenerator newSQLStatementForFetchRequest:ignoreInheritance:countOnly:nestingLevel:nestIsWhereScoped:] + 35 4 CoreData 0x000000010c3f67b8 -[NSSQLAdapter _statementForFetchRequest:ignoreInheritance:countOnly:nestingLevel:] + 344 5 CoreData 0x000000010c30367c -[NSSQLAdapter _newSelectStatementWithFetchRequest:ignoreInheritance:] + 316 6 CoreData 0x000000010c3032f6 -[NSSQLCore newRowsForFetchPlan:] + 118 7 CoreData 0x000000010c302bac -[NSSQLCore objectsForFetchRequest:inContext:] + 524 8 CoreData 0x000000010c302549 -[NSSQLCore executeRequest:withContext:error:] + 377 9 CoreData 0x000000010c3e7eaf 65-[NSPersistentStoreCoordinator executeRequest:withContext:error:]_block_invoke + 3311 10 CoreData 0x000000010c3f14dd gutsOfBlockToNSPersistentStoreCoordinatorPerform + 189 11 libdispatch.dylib 0x00000001111fe3eb _dispatch_client_callout + 8 12 libdispatch.dylib 0x00000001111e2b74 _dispatch_barrier_sync_f_slow + 1542 13 CoreData 0x000000010c3e25d5 _perform + 197 14 CoreData 0x000000010c3021b4 -[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 500 15 CoreData 0x000000010c300973 -[NSManagedObjectContext executeFetchRequest:error:] + 579 16 DATAObjectIDs 0x000000010d3e72b7 __78+[DATAObjectIDs objectIDsInEntityNamed:withAttributesNamed:context:predicate:]_block_invoke + 599 17 CoreData 0x000000010c348127 developerSubmittedBlockToNSManagedObjectContextPerform + 199 18 CoreData 0x000000010c347fee -[NSManagedObjectContext performBlockAndWait:] + 222 19 DATAObjectIDs 0x000000010d3e6eab +[DATAObjectIDs objectIDsInEntityNamed:withAttributesNamed:context:predicate:] + 491 20 DATAFilter 0x000000010d3dc514 +[DATAFilter changes:inEntityNamed:predicate:operations:localKey:remoteKey:context:inserted:updated:] + 468

3lvis commented 8 years ago

Hi @xTheRamon,

You're right, looks like it's on our side. By making a quick Google search it seems that the problem is related to a wrong predicate.

http://stackoverflow.com/questions/4217849/core-data-nspredicate-for-many-to-many-relationship-to-many-key-not-allowed

In the method [DATAObjectIDs objectIDsInEntityNamed:withAttributesNamed:context:predicate:]

Could you share the complete call stack? Would be nice to see in which Sync method the crash is happening, although with some debugging I could check too.

rswilem commented 8 years ago

@3lvis, thank you for your fast response! Amazing!

Please find the complete callstack below:

* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'to-many key not allowed here' * First throw call stack: ( 0 CoreFoundation 0x000000010e1fdd85 exceptionPreprocess + 165 1 libobjc.A.dylib 0x0000000111d9adeb objc_exception_throw + 48 2 CoreData 0x000000010de54fff -[NSSQLGenerator newSQLStatementForRequest:ignoreInheritance:countOnly:nestingLevel:nestIsWhereScoped:] + 1583 3 CoreData 0x000000010dd477e3 -[NSSQLGenerator newSQLStatementForFetchRequest:ignoreInheritance:countOnly:nestingLevel:nestIsWhereScoped:] + 35 4 CoreData 0x000000010de3a7b8 -[NSSQLAdapter _statementForFetchRequest:ignoreInheritance:countOnly:nestingLevel:] + 344 5 CoreData 0x000000010dd4767c -[NSSQLAdapter _newSelectStatementWithFetchRequest:ignoreInheritance:] + 316 6 CoreData 0x000000010dd472f6 -[NSSQLCore newRowsForFetchPlan:] + 118 7 CoreData 0x000000010dd46bac -[NSSQLCore objectsForFetchRequest:inContext:] + 524 8 CoreData 0x000000010dd46549 -[NSSQLCore executeRequest:withContext:error:] + 377 9 CoreData 0x000000010de2beaf 65-[NSPersistentStoreCoordinator executeRequest:withContext:error:]_block_invoke + 3311 10 CoreData 0x000000010de354dd gutsOfBlockToNSPersistentStoreCoordinatorPerform + 189 11 libdispatch.dylib 0x0000000112c423eb _dispatch_client_callout + 8 12 libdispatch.dylib 0x0000000112c26ef5 _dispatch_barrier_sync_f_invoke + 393 13 CoreData 0x000000010de265d5 _perform + 197 14 CoreData 0x000000010dd461b4 -[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 500 15 CoreData 0x000000010dd44973 -[NSManagedObjectContext executeFetchRequest:error:] + 579 16 DATAObjectIDs 0x000000010ee2b2b7 78+[DATAObjectIDs objectIDsInEntityNamed:withAttributesNamed:context:predicate:]_block_invoke + 599 17 CoreData 0x000000010dd8c127 developerSubmittedBlockToNSManagedObjectContextPerform + 199 18 CoreData 0x000000010dd8bfee -[NSManagedObjectContext performBlockAndWait:] + 222 19 DATAObjectIDs 0x000000010ee2aeab +[DATAObjectIDs objectIDsInEntityNamed:withAttributesNamed:context:predicate:] + 491 20 DATAFilter 0x000000010ee20514 +[DATAFilter changes:inEntityNamed:predicate:operations:localKey:remoteKey:context:inserted:updated:] + 468 21 Sync 0x000000010f29db07 TZFC4Sync4Sync7changesfTGSaGVs10DictionarySSPs9AnyObject13inEntityNamedSS9predicateGSqCSo11NSPredicate_6parentGSqCSo15NSManagedObject_9inContextCSo22NSManagedObjectContext9dataStackC9DATAStack9DATAStack10completionGSqFT5errorGSqCSo7NSError_TT_ + 3959 22 Sync 0x000000010f296581 _TFE4SyncCSo15NSManagedObject23sync_toManyRelationshipfTCSo25NSRelationshipDescription10dictionaryGVs10DictionarySSPs9AnyObject6parentGSqS09dataStackC9DATAStack9DATAStackT + 5281 23 Sync 0x000000010f296f87 _TToFE4SyncCSo15NSManagedObject23sync_toManyRelationshipfTCSo25NSRelationshipDescription10dictionaryGVs10DictionarySSPs9AnyObject6parentGSqS09dataStackC9DATAStack9DATAStackT + 151 24 Sync 0x000000010f299d24 _TFFE4SyncCSo15NSManagedObject23sync_fillWithDictionaryFTGVs10DictionarySSPs9AnyObject6parentGSqS09dataStackC9DATAStack9DATAStack_T_UFCSo25NSRelationshipDescriptionT + 1988 25 Sync 0x000000010f29a773 _TTRXFo_oCSo25NSRelationshipDescription_dT_zoPs9ErrorType__XFo_iS__dTzoPS0 + 35 26 libswiftCore.dylib 0x0000000112586999 _TFEsPs12SequenceType7forEachfzFzWx9Generator7Element_TT + 361 27 Sync 0x000000010f294d8b _TFE4SyncCSo15NSManagedObject23sync_fillWithDictionaryfTGVs10DictionarySSPs9AnyObject6parentGSqS09dataStackC9DATAStack9DATAStackT + 811 28 Sync 0x000000010f2950c2 _TToFE4SyncCSo15NSManagedObject23sync_fillWithDictionaryfTGVs10DictionarySSPs9AnyObject6parentGSqS09dataStackC9DATAStack9DATAStackT + 130 29 Sync 0x000000010f29fdd9 _TFZFC4Sync4Sync7changesFTGSaGVs10DictionarySSPs9AnyObject_13inEntityNamedSS9predicateGSqCSo11NSPredicate_6parentGSqCSo15NSManagedObject_9inContextCSo22NSManagedObjectContext9dataStackC9DATAStack9DATAStack10completionGSqFT5errorGSqCSo7NSError_TT_U0_FTGSQGS1_CSo8NSObjectPS2GSQS4_T_ + 537 30 Sync 0x000000010f29ff17 _TTRXFooGSQGVs10DictionaryCSo8NSObjectPs9AnyObjectoGSQCSo15NSManagedObjectdTXFo_iTGSQGS_S0_PS1GSQS2__iT + 55 31 Sync 0x000000010f29e251 _TPATTRXFooGSQGVs10DictionaryCSo8NSObjectPs9AnyObjectoGSQCSo15NSManagedObjectdTXFo_iTGSQGS_S0_PS1GSQS2iT + 81 32 Sync 0x000000010f29ff54 _TTRXFo_iTGSQGVs10DictionaryCSo8NSObjectPs9AnyObject__GSQCSo15NSManagedObjectiTXFo_oGSQGS_S0PS1____oGSQS2dT + 36 33 Sync 0x000000010f2a002a _TTRXFo_oGSQGVs10DictionaryCSo8NSObjectPs9AnyObject_oGSQCSo15NSManagedObjectdT__XFdCb_dGSQCSo12NSDictionarydGSQS2dT + 202 34 DATAFilter 0x000000010ee20d7c +[DATAFilter changes:inEntityNamed:predicate:operations:localKey:remoteKey:context:inserted:updated:] + 2620 35 Sync 0x000000010f29db07 TZFC4Sync4Sync7changesfTGSaGVs10DictionarySSPs9AnyObject13inEntityNamedSS9predicateGSqCSo11NSPredicate_6parentGSqCSo15NSManagedObject_9inContextCSo22NSManagedObjectContext9dataStackC9DATAStack9DATAStack10completionGSqFT5errorGSqCSo7NSErrorT__T + 3959 36 Sync 0x000000010f29ec86 TFZFC4Sync4Sync7changesFTGSaGVs10DictionarySSPs9AnyObject13inEntityNamedSS9predicateGSqCSo11NSPredicate_9dataStackC9DATAStack9DATAStack10completionGSqFT5errorGSqCSo7NSErrorT_T_UFCSo22NSManagedObjectContextT + 374 37 Sync 0x000000010f29c28f _TPATFZFC4Sync4Sync7changesFTGSaGVs10DictionarySSPs9AnyObject_13inEntityNamedSS9predicateGSqCSo11NSPredicate_9dataStackC9DATAStack9DATAStack10completionGSqFT5errorGSqCSo7NSErrorT___T_UFCSo22NSManagedObjectContextT + 239 38 DATAStack 0x000000010ee3e423 _TFFC9DATAStack9DATAStack29performInNewBackgroundContextFFT17backgroundContextCSo22NSManagedObjectContext_T_T_U_FTT + 67 39 DATAStack 0x000000010ee3e3d7 _TTRXFodTXFdCbdT__ + 39 40 CoreData 0x000000010dd8c127 developerSubmittedBlockToNSManagedObjectContextPerform + 199 41 libdispatch.dylib 0x0000000112c423eb _dispatch_client_callout + 8 42 libdispatch.dylib 0x0000000112c2882c _dispatch_queue_drain + 2215 43 libdispatch.dylib 0x0000000112c27d4d _dispatch_queue_invoke + 601 44 libdispatch.dylib 0x0000000112c2a996 _dispatch_root_queue_drain + 1420 45 libdispatch.dylib 0x0000000112c2a405 _dispatch_worker_thread3 + 111 46 libsystem_pthread.dylib 0x0000000112f7f4de _pthread_wqthread + 1129 47 libsystem_pthread.dylib 0x0000000112f7d341 start_wqthread + 13 ) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)

3lvis commented 8 years ago

BOOM! Thanks!

rswilem commented 8 years ago

@3lvis did you happen to track down this error? Any idea when this fix will be put through? Cheers and thanks in advance!

3lvis commented 8 years ago

@xTheRamon Looking into it, at least I was able to reproduce the crash

3lvis commented 8 years ago

@xTheRamon Could you confirm if this has been fixed on master?

rswilem commented 8 years ago

@3lvis You sir, are an absolute legend! Thanks! Fixed and working as expected. Splendid!

I've noticed one thing though, you might find this interesting. Whenever I pod update, it tries to downgrade Sync to an ancient version. I'm not very familiar with configuring pods, but I've attached the log anyhow. There might be an issue in the config. Anyhow, superb job on the many to many! Great!

Analysing dependencies
Removing DATAFilter
Removing DATAObjectIDs
Removing NSEntityDescription-SYNCPrimaryKey
Downloading dependencies
Using AFNetworking (3.1.0)
Using Crashlytics (3.7.0)
Installing DATAStack 4.3.0 (was 4.2.4)
Using Fabric (1.6.7)
Using NSDictionary-ANDYSafeValue (0.3.1)
Installing NSManagedObject-ANDYMapChanges (0.7)
Installing NSManagedObject-ANDYObjectIDs (0.4)
Using NSManagedObject-HYPPropertyMapper (3.6.0)
Using NSString-HYPNetworking (0.4.0)
**Installing Sync 0.5.1 (was 1.6.4)**
Generating Pods project
Integrating client project
Sending stats
Sending stats
Sending stats
Pod installation complete!
3lvis commented 8 years ago

@xTheRamon 😊

woah, which version of CocoaPods are you using?

rswilem commented 8 years ago

@3lvis I'm on version 0.39.0. Not using any --pre version.

3lvis commented 8 years ago

Weird, I just published a new version of Sync with this change 1.6.5. Could you check if it's working?

rswilem commented 8 years ago

Yep, works perfectly now! Weirdest thing ever. I think we've just found a bug in CocoaPods ;)

Anyhow, thank you @3lvis for your support and time! Great library, best there is!

3lvis commented 8 years ago

I'm glad you find it useful, let me know if I can help in anything else. 💥