Invalid relationship type for one relationship: property = "user"; desired type = user; this type = User;

I have a problem with the master data. With Swift3 in iOS 10, I get a managed object context every time I retrieve or save data using

func getContext () -> NSManagedObjectContext { let appDelegate = UIApplication.shared.delegate as! AppDelegate return appDelegate.persistentContainer.viewContext } 

In my application, I have two users, "User" and "Book." I want to assign a book to a user, but a user can have multiple registers. So I have a UserTableView where I can display users and the UserViewController class where I create the user. The same goes for the book. When creating a journal, I also get a list of all users from which I choose one, and which should be assigned to the register and vice versa.

When saving as above, I get an error

 Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unacceptable type of value for to-one relationship: property = "user"; desired type = User; given type = User; 

My data model is as follows: Data Model

Any help is appreciated :)

+8
source share
2 answers

I had the same problem. In my case, this happened when I was doing unit tests. In this case, there were two main data stacks in memory, one for the wiring harness, and the other for my unit tests being tested.

The first key to solving this issue was to put a statement right before setting the relation property to make sure that the entity type of the object that I set was the same as the expected relation entity type. They should be the same, and in my case they were not.

In my case, I had a MatchRequest that had a one-to-one relationship with a Player called an "initiator". So, my statement was as follows:

  let player = try Player.findLocal(for: matchRequest.initiator, in: moc, createIfMissing: true) let expectedEntity = self.entity.relationshipsByName["initiator"]!.destinationEntity! assert(player!.entity === expectedEntity, "Player returned doesn't have the same entity type") self.initiator = player 

The above statement failed, which I suspect is similar to the statement used by Core Data, which throws an argument exception.

When checking Player.entity (), it returns the same instance of the object that causes the crash.

I think the root of the problem is that Core Data sets some kind of static property for entities that will not be correctly distributed between the main data stacks. The call to MyManagedObject.entity () will work correctly when called from one stack, but not in another.

So, to get around the problem, when I create a Player object for input into relationships, I get the object using the older API NSEntityDescription.insertNewObject(...) , and not the newer constructor MyManagedObject(context:) . This ensures that the correct object is used for the given context of the managed object.

So, to repeat:

 // SOMETIMES FAILS if you have more than one core data stack: result = Player(context: managedObjectContext) // ALWAYS WORKS: result = NSEntityDescription.insertNewObject(forEntityName: "Player", into: managedObjectContext) as? Player 
+5
source

I had the same problem, but I was sure that I did not have two main data stacks, as in the previous answer.

In the end, I realized that I had initialized the link to the NSStoreCoordinator and the view context and background context using the lazy keyword. I also had a bunch of code doing the heavy work in the background thread and saving using the specified stack.

Apple docs state: "If a property marked with the lazy modifier is available to multiple threads at the same time, and the property has not yet been initialized, there is no guarantee that the property will be initialized only once."

So this unsuccessful scenario is another way to get to this error. Solution: make sure that nothing is lazy in your underlying data stack, especially when you are doing a lot of background / priority threads.

I hope this helps someone in the future. You, the future developer, if you are here: Good luck.

0
source

Source: https://habr.com/ru/post/1012319/


All Articles