i spent all afternoon banging my head against the wall trying to figure out why decoding of this class was failing. the class has a property that is an NSArray of Foo objects. Foo conforms to NSSecureCoding, and i have successfully encoded and decoded that class by itself. i was getting an error in initWithCoder: that said failed to decode class Foo. through some experimentation, i discovered that i needed to add [Foo class] to initWithCoder: in order for it to work. maybe this will help someone else who's having the same problem. my question is, why is this necessary? i found no suggestion that this is necessary in apple's documentation.
#import "Foo.h"
@interface MyClass : NSObject <NSSecureCoding>
@property (nonatomic) NSArray *bunchOfFoos;
@end
@implementation MyClass
static NSString *kKeyFoo = @"kKeyFoo";
+ (BOOL) supportsSecureCoding
{
return YES;
}
- (void) encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:self.bunchOfFoos forKey:kKeyFoo];
}
- (id) initWithCoder:(NSCoder *)decoder
{
if (self = [super init])
{
[Foo class]; // Without this, decoding fails
_bunchOfFoos = [decoder decodeObjectOfClass:[NSArray class] forKey:kKeyFoo];
}
return self;
}
@end
For those who are still struggling with this: @Ben H's solution didn't solve my problem. And I keep having the following error message:
And finally, I realized that for custom classes. You have to use the following function instead
decodeObjectOfClasses
:And you to pass a
NSSet
of all possible classes in theNSArray
to the function above! I am not sure why @Ben H could solve the issue by simply adding a[Foo class]
outside of the function. Maybe it is a compiler issue. But anyway, if his solution doesn't work, try this one as well.I've just encountered similar issue and that was weird and extremely time consuming. I wanted to test my class to be NSSecureCoded correctly with Specta/Expecta. So I've implemented everything as needed specifying class when decoded. At the end of my trials I got weirdest exception:
Test looked something like that:
While plain NSCoding (requiresSecureCoding = NO) test succeeded, NSSecureCoding tests kept failing. After vast range of trials I found solution for that, just a single line:
After that all my tests succeeded, objects were created as expected.
I'm not sure why did that happened, my guess would be that class is not visible as
Ben H
suggested and it uses something likeNSClassFromString(@"MyClass")
. The above code worked fine in AppDelegate. MyClass was from development pods I'm developing.i think i may have figured this out. without the line [Foo class], there is no reference to the class Foo in this file. because of this, i believe the compiler is optimizing the Foo class out, and then the Foo objects within the array cannot be decoded. having [Foo class] in there prevents this.