Search code examples
iosswiftobjective-cjsonmodel

NSArray element failed to match the Swift Array Element type Expected JSONPaymentCard but found __NSDictionaryI


I am using JSONModel to cast values from server:

@interface PaymentCardsResponse: JSONModel
@property (strong, nonatomic) NSArray<JSONPaymentCard *> *userCards;
@end

But when later I try to access this

response.userCards.forEach { card in } //here is an error

I have an error:

Precondition failed: NSArray element failed to match the Swift Array Element type Expected JSONPaymentCard but found __NSDictionaryI

Why do I have it there? What am I missing?


Solution

  • In the README file of JSONModel, there is a note saying:

    @interface OrderModel : JSONModel
    @property (nonatomic) NSInteger orderId;
    @property (nonatomic) float totalPrice;
    @property (nonatomic) NSArray <ProductModel> *products;
    @end
    

    Note: the angle brackets after NSArray contain a protocol. This is not the same as the Objective-C generics system. They are not mutually exclusive, but for JSONModel to work, the protocol must be in place.

    JSONModel uses the type in the <> to determine the specific type of array to deserialise, and it is specifically noted that you can't replace this with Objective-C generics system ("not the same"!), so if you did:

    @property (strong, nonatomic) NSArray<JSONPaymentCard *> *userCards;
    

    You are not telling JSONModel what model type the array should contain, so it just dumbly deserialises NSDictionarys. You can do both Objective-C generics, and tell JSONModel the type of the array, as demonstrated by the next code snippet in the README.

    @property (strong, nonatomic) NSArray<JSONPaymentCard *> <JSONPaymentCard> *userCards;