8

I'm experiencing a weird behaviour with NSFetchedResultsController. It is new in iOS 10. Straight to the point: fetchedObjects contains duplicate objects.

This is not by any mean "duplicate" in my own criteria. They literally have the same objectIDs and the same reference.

How does it happen in my app:

  1. FRC is setup and fetch performed

  2. 2 objects are fetched (in this example)

  3. Something happens in my sync layer, another object (that fetch items are in relationship with) is updated

  4. FRC calls delegate that the content did change. fetchedObjects contains 4 objects (2 duplicates)

Here's a console output from my debugging in controllerDidChangeContent method.

po frc.fetchedObjects

    - 0 : <ListItem: 0x1700dc3f0> (entity: ListItem; id: 0x1706294a0 <x-coredata://12D0CB00-7BF4-402A-8371-19DD1CFB1537/ListItem/t3384FC2D-3399-41FE-B7DD-C277922F495445> ; data: { ... }

    - 1 : <ListItem: 0x1700dc3f0> (entity: ListItem; id: 0x1706294a0 <x-coredata://12D0CB00-7BF4-402A-8371-19DD1CFB1537/ListItem/t3384FC2D-3399-41FE-B7DD-C277922F495445> ; data: { ... }

    - 2 : <ListItem: 0x1704c49f0> (entity: ListItem; id: 0x170631680 <x-coredata://12D0CB00-7BF4-402A-8371-19DD1CFB1537/ListItem/t3384FC2D-3399-41FE-B7DD-C277922F495446> ; data: { ... }

    - 3 : <ListItem: 0x1704c49f0> (entity: ListItem; id: 0x170631680 <x-coredata://12D0CB00-7BF4-402A-8371-19DD1CFB1537/ListItem/t3384FC2D-3399-41FE-B7DD-C277922F495446> ; data: { ... }


(lldb) po frc.fetchedObjects![0].objectID.isEqual(frc.fetchedObjects![1].objectID)
true

Another note: when I recreate FRC and fetch objects again, there are no duplicates.

I simply have no idea what could be causing this problem. I might be doing something wrong in my app that is causing that bug. It's really weird anyway that FRC allows for duplicates objects in fetchedObjects. Can you please give me any clue of how should I debug it?

msmialko
  • 1,439
  • 2
  • 20
  • 35
  • I'd suspect something is off in your FRC didChange delegate functions since the duplicates show up 1) after in the view only after a change to some objects, and 2) the change isn't reflected in the database. I'd focus on comparing the .insert and .move cases to Apple's suggested code, but if they're OK check the others. It's been a while since I went to the Xcode beta, but I don't remember any changes here other than the switch from AnyObject to Any in some parameters, but they may be sensitive to something that version 7 didn't care about. – Ron Diel Sep 29 '16 at 18:40

1 Answers1

8

I've come across similar problem today also. I noticed in my case the fetched objects on the FRC all had temporary IDs. These can be verified like so:

fetchedResultsController.fetchedObjects[0].objectID.isTemporary

To get around this problem in my App I explicitly request permanent object IDs for all the inserted objects before saving the context on which new data is imported/updated/synced:

NSError *error;
[bgContext obtainPermanentIDsForObjects:bgContext.insertedObjects.allObjects error:&error];
AlexYu
  • 145
  • 2
  • 8
  • This is brilliant. Thank you. – atlex2 Apr 16 '20 at 03:09
  • I've never experienced Duplicates in FRC issue until ios 14 update. – berec Sep 27 '20 at 13:46
  • @berec did you manage a fix for it, such as the `self.persistentContainer.viewContext.obtainPermanentIDs()` function? I try this and sometimes still see duplicates, such as on first app launch being disconnected from the internet. – professormeowingtons Oct 03 '20 at 05:07
  • @professormeowingtons obtaining permanent ids works for me. If you have duplicates on the first launch, then it looks like you deal with the actual duplication in persistent storage. – berec Oct 05 '20 at 15:39
  • AlexYu you saved me. I am experiencing this problem on iOS 14 and I can't believe that this problem is still actual. – Josip B. Jan 20 '21 at 22:34