-1

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?

Sweeper
  • 213,210
  • 22
  • 193
  • 313
Bartłomiej Semańczyk
  • 59,234
  • 49
  • 233
  • 358
  • `NSDictionary` objects seem to have been put inside the `userCards` array, rather than `JSONPaymentCard`. Can you show the code that puts things into `userCards`? Are you using `JSONSerialization`? That tends to creates `NSDictionary`s. – Sweeper May 10 '21 at 07:00
  • `[[PaymentCardsResponse alloc] initWithDictionary:(NSDictionary *) responseBody error:error];` This is how I parse response body. – Bartłomiej Semańczyk May 10 '21 at 07:40
  • And... what does that do exactly? Please show a [mcve]. – Sweeper May 10 '21 at 07:42
  • This is the custom init from library. That is all I do with this. You want example response? – Bartłomiej Semańczyk May 10 '21 at 07:57
  • Oh I see, "JSONModel" is the name of a library! I added the tag for you :) They seem to have explained this clearly in the README: "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." – Sweeper May 10 '21 at 08:02
  • So perhaps try `NSArray *userCards;`. That's what they did in the README file. – Sweeper May 10 '21 at 08:03

1 Answers1

1

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;
Sweeper
  • 213,210
  • 22
  • 193
  • 313