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

Hi,

Overview:

  • I get the following error when trying to save / read from SwiftData
  • It happens when I try to save color to SwiftData (code below)

Error

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

Questions

  1. How can I resolve the error?
  2. I am not directly using data, I am using just Float values, swift types. Why am I getting this error?
  3. Is there a way to add a breakpoint to stop at the exact type causing the error? (Symbolic breakpoint doesn't seem to help)
  4. Or is the below code ok and not responsible for the error?

Code

import SwiftUI

nonisolated struct ColorRepresentation: Codable {

    let red: Float
    let green: Float
    let blue: Float
    let opacity: Float

    init(colorResolved: Color.Resolved) {
        red = colorResolved.red
        green = colorResolved.green
        blue = colorResolved.blue
        opacity = colorResolved.opacity
    }

    func color() throws -> Color {
        Color(
            red: Double(red),
            green: Double(green),
            blue: Double(blue),
            opacity: Double(opacity)
        )
    }
}

extension ColorRepresentation: Equatable {}

This SwiftData is synced to CloudKit.

Is there any requirement that custom property (struct) needs to implement / conform to any protocol?

Seems find when it is just SwiftData without CloudKit sync, I feel the issue happens only with CloudKit

Doing a search for your error message leads me to believe that the cause of the problem is that Color doesn't conform to Codable. You have to write a transformer for Color that inherits from NSSecureUnarchiveFromDataTransformer. Inheriting from NSSecureUnarchiveFromDataTransformer will make the error/warning go away.

Take a look at the following Stack Overflow questions:

The second question has an answer that shows how to create a transformer.

Assuming that you use ColorRepresentation, which is Codable, with an attribute in a SwiftData model, the issue seems to be quite similar to this one, which I had a hard time to reproduce. Will the issue still occur if you remove the SwiftData + CloudKit integration? Do you have a minimal project that reproduces the issue?

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

@DTS Engineer could you please add CloudKit tag to this post, I am unable to add it, thanks!

My Solution

  • I have managed to get it working on the app target with ValueTransformer and NSSecureCoding but kind of seems odd to store just a normal struct using so much boilerplate code.

Way to reproduce this

  • The issue is not reproducible on SwiftData only.
  • Only when you have SwiftData + CloudKit this occurs.
  • CloudKit minimum reproducible code often requires turning on project setup with capabilities etc.

Problem

  • On the app target things work ok but for test cases there is a crash as it can't convert from Data to ColorRepresentation.
  • I have the same file added to 2 different targets, not sure if it has anything with the names and module names because the error seems to suggest it.
Error Domain=NSCocoaErrorDomain Code=4864 "value for key 'root' was of unexpected class 'ColorRepresentation' (0x10326c828) [/Users/homefolder/Library/Developer/CoreSimulator/Devices/E365C6A9-B19A-4A53-8885-05E9DE4D8B84/data/Containers/Bundle/Application/BE80DEBA-5FAF-496A-99CC-E60A8C72A096/WidgetStylesDemo.app].
Allowed classes are:
 {(
    "'ColorRepresentation' (0x103d98520) [/Users/homefolder/Library/Developer/CoreSimulator/Devices/E365C6A9-B19A-4A53-8885-05E9DE4D8B84/data/Containers/Bundle/Application/BE80DEBA-5FAF-496A-99CC-E60A8C72A096/WidgetStylesDemo.app/PlugIns/WidgetStylesDemoTests.xctest]"
)}" UserInfo={NSDebugDescription=value for key 'root' was of unexpected class 'ColorRepresentation' (0x10326c828) [/Users/homefolder/Library/Developer/CoreSimulator/Devices/E365C6A9-B19A-4A53-8885-05E9DE4D8B84/data/Containers/Bundle/Application/BE80DEBA-5FAF-496A-99CC-E60A8C72A096/WidgetStylesDemo.app].
Allowed classes are:
 {(
    "'ColorRepresentation' (0x103d98520) [/Users/homefolder/Library/Developer/CoreSimulator/Devices/E365C6A9-B19A-4A53-8885-05E9DE4D8B84/data/Containers/Bundle/Application/BE80DEBA-5FAF-496A-99CC-E60A8C72A096/WidgetStylesDemo.app/PlugIns/WidgetStylesDemoTests.xctest]"
)}}

Documentation / Videos:

  • I wish there are some documentation around SwiftData + CloudKit custom types.

could you please add CloudKit tag to this post, I am unable to add it, thanks!

Sure, added the CloudKit tag.

I have managed to get it working on the app target with ValueTransformer and NSSecureCoding but kind of seems odd to store just a normal struct using so much boilerplate code. ... but for test cases there is a crash as it can't convert from Data to ColorRepresentation.

Nice to know you've had your app work, but it doesn't seem that ValueTransformer + NSSecureCoding is needed, as I described here.

CloudKit minimum reproducible code often requires turning on project setup with capabilities etc.

Yeah, I know that. If you can provide a minimal project that reproduces the issue, I can set it up with my team and CloudKit container to hopefully see the issue and get to the bottom.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

@DTS Engineer

  • I tried on a clean sample project and I am able to reproduce the fault log

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

I have filed a feedback FB22634797 with the following:

  1. Sample project (minimum code)
  2. Screen recording
  3. Steps to reproduce

Note: I have turned on strict concurrency and swift language to 6. I have mentioned everything in the feedback.

Questions

  • Is this a bug?
  • If this is a bug, can this fault be ignored (in production app) or what is the recommended approach till the bug gets fixed?

Any help on this would be much appreciated!

@DTS Engineer

Questions

  1. Can you confirm if it is ok to use ColorComponents as Coddle and ignore the fault log?
'NSKeyedUnarchiveFromData' should not be used to for un-archiving and will be removed in a future release
  1. Or what is the best approach?

I could store it as Data, however having to decode every time seems to be expensive especially when displaying In a list.

I am kind of stuck with this, could you please help, thanks!

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