6

I'm on macOS Monterey (12.0.1), not iOS, objective-c, XCode 13

I'm receiving this log message after building my app for arm64:

[general] *** -[NSKeyedUnarchiver validateAllowedClass:forKey:] allowed unarchiving safe plist type ''NSString' (0x1dcb1c848) [/System/Library/Frameworks/Foundation.framework]' for key 'NS.objects', even though it was not explicitly included in the client allowed classes set: '{(
    "'NSDictionary' (0x1dcaee5d0) [/System/Library/Frameworks/CoreFoundation.framework]"
)}'. This will be disallowed in the future.

Any idea what's causing this and how to get rid of it?

Edit: it seems to happen with every app compiled on arm64 starting with macOS Monterey. So it might be a generic apple bug

Pat_Morita
  • 3,355
  • 3
  • 25
  • 36
  • 2
    thats not a bug, it is a notice. It even tells exactly whats up. NSString was allowed in NSDictionary without being explicit allowed. Meaning you may want to read what changed on decoding objects (NSKeyedUnarchiver). – Ol Sen Nov 21 '21 at 13:09

2 Answers2

8

Thanks to @OI Sen it've had a closer look to the NSUnarchiver. First of all NSKeyedUnarchiver should be allocated and initialized like this:

NSError* err;

NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:someData error:&err];

In my specific case I use NSSecure coding. Therefore you have to specify classes on decoding objects. In my case it looked like this

NSDictionary* someDict = [unarchiver decodeObjectOfClass:[NSDictionary class] forKey:NSKeyedArchiveRootObjectKey];

But the NSDictionary contained additional strings. That was the cause of the log message. By adding NSString to the decoded class list the error is gone.

NSDictionary* someDict = [unarchiver decodeObjectOfClasses:[[NSSet alloc] initWithArray:@[[NSDictionary class],[NSString class]]] forKey:NSKeyedArchiveRootObjectKey];
Pat_Morita
  • 3,355
  • 3
  • 25
  • 36
  • I've added same code still i am getting same error ? – Anita Nagori Sep 20 '22 at 15:53
  • You might have other objects inside nested or sub nested dictionaries, arrays... – Pat_Morita Sep 20 '22 at 16:33
  • NSError *error = nil; NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:encodedObject error:&error]; NSSet *sets = [NSSet setWithArray: @[ [NSMutableArray class], [NSDictionary class], [NSMutableDictionary class], [NSArray class], [NSDate class], [NSString class], [NSNumber class], [NSIndexSet class]]]; id object = [unarchiver decodeObjectOfClasses:sets forKey:NSKeyedArchiveRootObjectKey]; – Anita Nagori Sep 20 '22 at 17:12
  • I am using common function for encode and decode data , where result class will not fixed , it might array , dictionary , string , number so i have added set , what is wrong i am doing here ? – Anita Nagori Sep 20 '22 at 17:13
  • Do you have any custom object stored inside? E.g. inherited from NSObject that itself contains an encoding/decoding? – Pat_Morita Sep 21 '22 at 17:53
  • Yes i have custom classes too – Anita Nagori Sep 22 '22 at 13:04
  • Then you have custom encoders/decoders in these classes. You have to implement this all the way down in every class and subclass that's getting encoded/decoded. – Pat_Morita Sep 22 '22 at 14:01
  • But the project is 10year earlier and doing changes in all classes takes a lot of time , i need quick solution on this – Anita Nagori Sep 23 '22 at 11:02
  • Don't use secure coding then. Please open another thread for your issue. This is not the right place – Pat_Morita Sep 23 '22 at 20:10
2

Another related situation is if you're using NSCoder.

This code generated the warning:

self.expression = [aDecoder decodeObjectForKey: kExpression];

Warning eliminated with:

self.expression = [aDecoder decodeObjectOfClass:[NSString class] forKey:kExpression];

Note use of decodeObjectOfClass:[NSString class] instead of decodeObjectForKey.

Phantom59
  • 947
  • 1
  • 8
  • 19