iOS 12 specific problem: Core Data External Storage Binary Data corruption

  • A+
Category:Languages

I've spent the better part of a workday trying to solve this.

Background

I have a simple core data model, with essentially books and reading sessions. The books have covers (images) that are stored as binary data with "Allows External Storage".

On iOS 11.4 and below, everything works fine all the time. When I save a new session everything gets updated properly.

Problem

Since iOS 12, when I create a new reading session and link it to the book, about every second time, core data generates a SQL statement that also updates the book cover field, sometimes resulting in a bad reference (to file on disk) which often results in cover being nil when restarting app, and almost always creates another copy of the cover on disk (as can be seen in Simulator's _EXTERNAL_DATA folder).

In memory context and objects remain correct though (and everything in the UI is therefore OK), until app is restarted, then the cover is often nil.

iOS 12 specific

On iOS 12, I can deterministically reproduce the error in the simulator, on physical phones, and users have reported the error as well. I cannot reproduce the error on iOS 11.4, and no users reported the error previous to iOS 12.

Steps taken

  • I've enabled "-com.apple.CoreData.ConcurrencyDebug 1", so it shouldn't be that I'm accessing anything from the wrong queue. I've also enabled "-com.apple.CoreData.SQLDebug 3" so that I can see exactly what gets written.

  • I've made sure the Book instance (and therefore the cover) is not modified by my code before the association with the new Session by checking hasChanges, just before I do newSession.book = book and context.save().

  • To be 100% sure I'm not touching the cover property on any thread I've short-circuited my getters and setters for that property. No improvement.

  • I've tried using objectID to request an instance of the book just before the association and save. No improvement.

  • I've even tried the option where the context keeps strong references to all objects, just to make sure it was not some kind of memory management issue. No improvement.

Question

Any ideas for next steps?

Anyone else had any similar problems since iOS 12?

I would be very grateful for any help!

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: