2

I have a core data model with some transformable attributes. When I try to fetch an entity from the store, I get a warning

'NSKeyedUnarchiveFromData' should not be used to for un-archiving and will be removed in a future release

I understand what this means - we are supposed to be using a value transformer that uses NSSecureCoding to encode and decode the attribute. The problem is that as far as I can tell, I am using a secure coding value transformer. I have four transformable attributes in this entity. Two of them use a transformer named NSSecureUnarchiveFromData. The other two use custom transformers that are registered with ValueTransformer.setValueTransformer(_:forName:).

I set a breakpoint on +[NSKeyedUnarchiver unarchiveObjectWithData:] and sure enough, I hit the breakpoint when I try to fetch the entity. The stack trace is

  * frame #0: 0x00007fff207e4abf Foundation`+[NSKeyedUnarchiver unarchiveObjectWithData:]
    frame #1: 0x00007fff2516b4ef CoreData`+[_PFRoutines retainedDecodeValue:forTransformableAttribute:] + 58
    frame #2: 0x00007fff250fdf78 CoreData`_prepareResultsFromResultSet + 2535
    frame #3: 0x00007fff250fbddf CoreData`newFetchedRowsForFetchPlan_MT + 2095
    frame #4: 0x00007fff253486f1 CoreData`_executeFetchRequest + 55
    frame #5: 0x00007fff2529b56a CoreData`-[NSSQLFetchRequestContext executeRequestCore:] + 41
    frame #6: 0x00007fff25310b4e CoreData`-[NSSQLStoreRequestContext executeRequestUsingConnection:] + 405
    frame #7: 0x00007fff252e28cb CoreData`__52-[NSSQLDefaultConnectionManager handleStoreRequest:]_block_invoke + 56
    frame #8: 0x00007fff2524b3c1 CoreData`__37-[NSSQLiteConnection performAndWait:]_block_invoke + 28
    frame #9: 0x0000000108ee6a88 libdispatch.dylib`_dispatch_client_callout + 8
    frame #10: 0x0000000108ef5cac libdispatch.dylib`_dispatch_lane_barrier_sync_invoke_and_complete + 132
    frame #11: 0x00007fff2524b2a7 CoreData`-[NSSQLiteConnection performAndWait:] + 134
    frame #12: 0x00007fff252e27e0 CoreData`-[NSSQLDefaultConnectionManager handleStoreRequest:] + 273
    frame #13: 0x00007fff252e9214 CoreData`-[NSSQLCoreDispatchManager routeStoreRequest:] + 283
    frame #14: 0x00007fff2521a994 CoreData`-[NSSQLCore dispatchRequest:withRetries:] + 161
    frame #15: 0x00007fff25215f2e CoreData`-[NSSQLCore processFetchRequest:inContext:] + 88
    frame #16: 0x00007fff250eaf31 CoreData`-[NSSQLCore executeRequest:withContext:error:] + 1072
    frame #17: 0x00007fff251f50a2 CoreData`__65-[NSPersistentStoreCoordinator executeRequest:withContext:error:]_block_invoke.797 + 3219
    frame #18: 0x00007fff251ed772 CoreData`-[NSPersistentStoreCoordinator _routeHeavyweightBlock:] + 222
    frame #19: 0x00007fff250ea40e CoreData`-[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 1684
    frame #20: 0x00007fff250e89c2 CoreData`-[NSManagedObjectContext executeFetchRequest:error:] + 885
    frame #21: 0x00007fff539b2903 libswiftCoreData.dylib`(extension in CoreData):__C.NSManagedObjectContext.fetch<A where A: __C.NSFetchRequestResult>(__C.NSFetchRequest<A>) throws -> Swift.Array<A> + 51
    frame #22: 0x0000000106bbd7c8 TouchpointLibrary`static TPLibrary.fetchLibrary(moc=0x00006000007dc750, self=TouchpointLibrary.TPLibrary) at TPLibrary+CoreDataClass.swift:26:29

My questions:

  1. Under what circumstances would Core Data fall back to the insecure decoder even though all of the transformable attributes in this entity have specifically set the transformer name?
  2. How can I debug this further?

Note: I've also double-checked all other entities in this model to ensure that their transformable attributes have specifically set a secure transformer, just in case this is due to a relation being faulted in.

Rudedog
  • 4,323
  • 1
  • 23
  • 34
  • On your second point, you could try setting `propertiesToFetch` to limit the fetch to each of the transformable attributes in turn, to see which triggers the breakpoint. – pbasdf Oct 29 '20 at 09:07

1 Answers1

2

Per the suggestion in the comments I set propertiesToFetch to isolate the issue. I was using the technique I described in this comment https://stackoverflow.com/a/58528937/212649, which has worked fine for me up until now. However, when the object to be transformed is declared in a different module, the auto-generated transformer name includes the module name, which doesn't match the name I was using in the core data model.

Unfortunately, iOS doesn't give any warnings about not finding a transformer for the name you specify, but instead just silently falls back to insecure decoding. Had it logged this, I would have spent way less time zeroing in on the issue.

Rudedog
  • 4,323
  • 1
  • 23
  • 34