1

I am using this code to unarchive an array of a custom object from UserDefaults:

guard let data = UserDefaults.standard.data(forKey: "key") else {
    return 
}

let customClassArray = try NSKeyedUnarchiver.unarchivedObject(ofClasses: 
   [NSMutableArray.self, 
    NSNull.self, 
    NSMutableDictionary.self, 
    NSNumber.self, 
    NSString.self, 
    NSArray.self, 
    CustomClass.self], from: data) as? [CustomClass]

But I get this error spammed several times:

 [NSKeyedUnarchiver validateAllowedClass:forKey:] allowed unarchiving safe plist type ''NSString' (0x1e5fae918) [/System/Library/Frameworks/Foundation.framework]' for key 'NS.keys', even though it was not explicitly included in the client allowed classes set: '{(
        "'NSMutableArray' (0x1e5fa7050) [/System/Library/Frameworks/CoreFoundation.framework]",
        "'NSNull' (0x1e5fa68a8) [/System/Library/Frameworks/CoreFoundation.framework]",
        "'NSMutableDictionary' (0x1e5fa6fb0) [/System/Library/Frameworks/CoreFoundation.framework]"
    )}'. This will be disallowed in the future.

along with this error:

[NSKeyedUnarchiver validateAllowedClass:forKey:] allowed unarchiving safe plist type ''NSNumber' (0x1e5fae8c8) [/System/Library/Frameworks/Foundation.framework]' for key 'NS.objects', even though it was not explicitly included in the client allowed classes set: '{(
    "'NSMutableArray' (0x1e5fa7050) [/System/Library/Frameworks/CoreFoundation.framework]",
    "'NSNull' (0x1e5fa68a8) [/System/Library/Frameworks/CoreFoundation.framework]",
    "'NSMutableDictionary' (0x1e5fa6fb0) [/System/Library/Frameworks/CoreFoundation.framework]"

As you can see in my code, I have listed out the classes such as NSMutableArray, NSNull, NSMutableDictionary and NSString. Why am I still getting this error?

Micro
  • 10,303
  • 14
  • 82
  • 120
  • That's strange. Could you check with the last part of an old answer https://stackoverflow.com/a/75821291/1801544 With writing `data` to a temp path and use the `NSDictionary(contentsOf:error:)` or `PropertyListSerialization.PropertyListFormat.binary` code part to list all the classes, but your code should indeed work. – Larme Jun 01 '23 at 09:27
  • The error seems to imply you only listed three classes but clearly you've listed more. As a test, what happens if you move `NSString.self` to the top of the list? – HangarRash Jun 01 '23 at 15:09
  • @HangarRash - I tried that and it didn't change anything. – Micro Jun 02 '23 at 03:50
  • @Larme I tried `PropertyListSerialization.PropertyListFormat.binary` but got this error: `Could not cast value of type '__NSDictionaryI' (0x1e5fbfdf0) to 'NSData' (0x1e5fc1dc8)` – Micro Jun 02 '23 at 03:51
  • I updated the question with more info from the console log. – Micro Jun 02 '23 at 03:51
  • That's a strange error you got if you tested my code. Which lined causes the issue? Did you saved the `data` into a temp file first? If there is no sensitive data, could you share `data` (usually, as hex with https://stackoverflow.com/questions/39075043/how-to-convert-data-to-hex-string-in-swift) ? – Larme Jun 02 '23 at 07:29
  • I think the problem is coming from `CustomClass`’s implementation of unarchiving, not the top level root object. Each class in the object hierarchy needs to specify which classes it can safely decode. – Geoff Hackworth Jun 02 '23 at 08:37
  • @GeoffHackworth I think you are correct. CustomClass is from a library so I can't modify it. Is there a way for me to specify classes it can decode with something like an extension? – Micro Jun 02 '23 at 22:28
  • @Micro I think the custom type contains arrays or dictionaries of other types, or is using older versions of the unarchive methods that don’t allow the list of classes to be specified. I don’t think you can change the behaviour of the internal classes in the library. Is there a newer version of the library? This issue started in iOS 15, I think, when using secure coding so they’ve had a while to fix it. – Geoff Hackworth Jun 03 '23 at 07:55

0 Answers0