0

First, let me show you the piece of code:

NSURL *url = [NSURL URLWithString:@"http://www....../struct1.js"];
//create a NSData file from url.
NSData *myData = [NSData dataWithContentsOfURL:url];
NSError *theError = nil;
//some framework
NSDictionary *dict = [[CJSONDeserializer deserializer] deserializeAsDictionary:myData error:&theError];  

NSString * products;
for(id key in dict){
    NSLog(@"key: %@, value: %@",key,[dict objectForKey:key]);
    if([key isEqualToString:@"product_reviews"]){
        products = (NSString *)[dict valueForKey:key];
        break;
    }
}

//gives an error at the execution, why?
NSLog(@"products : %@",[NSString stringWithString:products]);

I get an error at the execution, like products was not NSString, is it not? why can't i cast it?

Here is the error :

0x00e0eb2c __84-[UIApplication _handleApplicationActivationWithScene:transitionContext:completion:]_block_invoke3246 + 68
    19  UIKit                               0x00de5b8a -[UIApplication workspaceDidEndTransaction:] + 163
    2123
    31  UIKit                               0x00de52da -[UIApplication _run] + 540

........ .....

32  UIKit                               0x00deaeb9 UIApplicationMain + 160
33  App1                                0x000416ca main + 138
34  libdyld.dylib                       0x03156a25 start + 1

) libc++abi.dylib: terminating with uncaught exception of type NSException

  • Can you add a sample of the data? Are you sure that products is not nil on the NSLog line? – Dominic Jun 15 '16 at 13:05
  • 1
    what is the error exactly? compilation or runtime? show the stack trace and the log output you're generating – Wain Jun 15 '16 at 13:07
  • After your `if` test: `NSLog(@"Value class: %@" [dict[key] class])` shows what? – Larme Jun 15 '16 at 13:11
  • We may need the text before ` 0x00e0eb2c __84-[UIApplication`. – Larme Jun 15 '16 at 13:15
  • @Dominic yes, the data is not null and shows my data, just tested it again. –  Jun 15 '16 at 13:16
  • 3
    Don't use valueForKey:. Use objectForKey: unless you have a clearly understood need to use key-value coding. – rmaddy Jun 15 '16 at 13:17
  • @Larme interesting, it shows __NSCFArray, maddy I was using objectForKey until now, and didnt work. but u'r right i should read more about it –  Jun 15 '16 at 13:18
  • I don't know `CJSONDeserializer`, but you may have misunderstood the structure of your JSON. Could you show the `product_reviews` part? – Larme Jun 15 '16 at 13:20
  • @Larme it's a test, I've created the json manually, when I NSLog it, it shows 3 objects. –  Jun 15 '16 at 13:21
  • Then it makes perfect sense that if the value of `product_reviews` can hold various value it's a `NSArray` object. Your issue is what to do with a NSArray to "convert" it into a NSString. You have to decide what you want to do now. Show only first value? Show all separated with " ," ? `products = [dict[key] firstObject];` `products = [dict[key] componentsJoinedByString:@" ,"];`... – Larme Jun 15 '16 at 13:24
  • 1
    Yes, that what you were doing with `(NSString *)anNSArrayObject`, where `anNSArrayObject` is `dict[key]` in your case. So `stringWithString:anNSArrayObject` would cause the crash, I guess that there was in console a `Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ZzZ selectorName:]: unrecognized selector sent to instance"` somewhere that you didn't give. – Larme Jun 15 '16 at 13:30
  • @Larme thank you, this was my problem, I tried to use isKindOfClass, I didnt know there's a simple class method. You can add this comment as an answer if you want, so i can accept it ;) thanks again. –  Jun 15 '16 at 13:50

2 Answers2

1

You should use -objectForKey: instead od -valueForKey:.

See: Difference between objectForKey and valueForKey?

Community
  • 1
  • 1
arturdev
  • 10,884
  • 2
  • 39
  • 67
0

Casting something doesn't make it so. It just tries to convince the compiler that you know what you're talking about, so you can pretend an untyped (or id) value is of a specific class, then get more useful compile time checks when you're coding.

If you get casting wrong, then you get a crash at runtime.

You're getting an array, you can't just cast that to a string and expect it to work. You need to convert it. Since you don't say what it is you want to do with the array, it's difficult to offer help on that specifically.

Since at the moment you're just logging the value, you could change the relevant line of code to:

NSLog(@"products : %@", products);

And all would be clear.

jrturton
  • 118,105
  • 32
  • 252
  • 268