开发者

JSON fetching data gives exception

开发者 https://www.devze.com 2023-03-30 08:35 出处:网络
I am fetching data from JSON using following it gives exception: Terminating app due to uncaught exception \'NSInvalidArgumentException\', reason: \'*** -[NSCFDictionary objectAtIndex:]: unrecognized

I am fetching data from JSON using following it gives exception:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -  [NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0x9b1ac50'

SBJsonParser *parser = [[SBJsonParser alloc] init];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.krsconnect.no/community/api.html?method=event&appid=620&eventid=15946&affecteddate=1310515200000"]];

NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSDictionary *object = [parser objectWithString:json_string error:nil];
appDelegate.books1 = [[NSMutableArray alloc] init];
appDelegate.dates =[[NSMutableArray alloc]init];
appDelegate.descriptionArray=[[NSMutableArray alloc]init];
NSArray *results = [parser objectWithString:json_string error:nil];

for (int i=0; i<[results count]; i++) {
    NSDic开发者_运维百科tionary*dictOne=[results objectAtIndex:i];
    Detail  *aDetail = [[Detail alloc] initWithDictionary:[results objectAtIndex:i]];       
    [appDelegate.descriptionArray addObject:aDetail];
}


Replace following line...

    NSDictionary *object = [parser objectWithString:json_string error:nil];

    NSDictionary*dictOne=[results objectAtIndex:i];

With following one...

    NSDictionary *object = (NSDictionary*) [parser objectWithString:json_string error:nil];

    NSDictionary *dictOne = (NSDictionary*) [results objectAtIndex:i];

SBJSONParser doesn't support objectWithString: error: and raising pre-compiler warning warning: 'SBJsonParser' may not respond to '-objectWithString:error:' and that's why its crashing.

I have modified your code accordingly and it's working fine. Try it...

Modified Code...

    SBJsonParser *parser = [[SBJsonParser alloc] init];
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.krsconnect.no/community/api.html? method = event&appid = 620&eventid = 15946&affecteddate=1310515200000"]];

    NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];

    SBJSON *objParser = [[SBJSON alloc] init];
    NSDictionary *object = (NSDictionary *)[objParser objectWithString:json_string error:nil];
    appDelegate.books1 = [[NSMutableArray alloc] init];
    appDelegate.dates =[[NSMutableArray alloc]init];
    appDelegate.descriptionArray=[[NSMutableArray alloc]init];
    NSArray *results = (NSArray *)[objParser objectWithString:json_string error:nil];

    for (int i=0; i<[results count]; i++) {
        NSDictionary*dictOne = (NSDictionary *)[results objectAtIndex:i];
        Detail  *aDetail = [[Detail alloc] initWithDictionary:[results objectAtIndex:i]];       
        [appDelegate.descriptionArray addObject:aDetail];
    }


    #import <Foundation/Foundation.h>
    #import "SBJsonParser.h"
    #import "SBJsonWriter.h"


    @interface SBJSON : SBJsonBase <SBJsonParser, SBJsonWriter> {

    @private    
        SBJsonParser *jsonParser;
        SBJsonWriter *jsonWriter;
    }


    /// Return the fragment represented by the given string
    - (id)fragmentWithString:(NSString*)jsonrep error:(NSError**)error;

    /// Return the object represented by the given string
    - (id)objectWithString:(NSString*)jsonrep error:(NSError**)error;

    /// Parse the string and return the represented object (or scalar)
    - (id)objectWithString:(id)value allowScalar:(BOOL)x error:(NSError**)error;

    /// Return JSON representation of an array  or dictionary
    - (NSString*)stringWithObject:(id)value error:(NSError**)error;

    /// Return JSON representation of any legal JSON value
    - (NSString*)stringWithFragment:(id)value error:(NSError**)error;

    /// Return JSON representation (or fragment) for the given object
    - (NSString*)stringWithObject:(id)value allowScalar:(BOOL)x error:(NSError**)error;


    @end


    #import "SBJSON.h"

    @implementation SBJSON

    - (id)init {
        self = [super init];
        if (self) {
            jsonWriter = [SBJsonWriter new];
            jsonParser = [SBJsonParser new];
            [self setMaxDepth:512];

        }
        return self;
    }

    - (void)dealloc {
        [jsonWriter release];
        [jsonParser release];
        [super dealloc];
    }

    - (NSString *)stringWithObject:(id)obj {
        NSString *repr = [jsonWriter stringWithObject:obj];
        if (repr)
            return repr;    
        [errorTrace release];
        errorTrace = [[jsonWriter errorTrace] mutableCopy];
        return nil;
    }

    - (NSString*)stringWithObject:(id)value allowScalar:(BOOL)allowScalar error:(NSError**)error {
        NSString *json = allowScalar ? [jsonWriter stringWithFragment:value] : [jsonWriter stringWithObject:value];
        if (json)
            return json;
        [errorTrace release];
        errorTrace = [[jsonWriter errorTrace] mutableCopy];        
        if (error)
            *error = [errorTrace lastObject];
        return nil;
    }

    - (NSString*)stringWithFragment:(id)value error:(NSError**)error {
        return [self stringWithObject:value allowScalar:YES error:error];
    }

    - (NSString*)stringWithObject:(id)value error:(NSError**)error {
        return [self stringWithObject:value
                  allowScalar:NO
                        error:error];
    }

    - (id)objectWithString:(NSString *)repr {
        id obj = [jsonParser objectWithString:repr];
        if (obj)
            return obj;

        [errorTrace release];
        errorTrace = [[jsonParser errorTrace] mutableCopy];

        return nil;
    }


    - (id)objectWithString:(id)value allowScalar:(BOOL)allowScalar error:(NSError**)error {
        id obj = allowScalar ? [jsonParser fragmentWithString:value] : [jsonParser objectWithString:value];
        if (obj)
            return obj;

        [errorTrace release];
        errorTrace = [[jsonParser errorTrace] mutableCopy];
        if (error)
            *error = [errorTrace lastObject];
        return nil;
    }

    - (id)fragmentWithString:(NSString*)repr error:(NSError**)error {
        return [self objectWithString:repr
                  allowScalar:YES
                        error:error];
    }

    - (id)objectWithString:(NSString*)repr error:(NSError**)error {
        return [self objectWithString:repr
                  allowScalar:NO
                        error:error];
    }


    - (NSUInteger)maxDepth {
        return jsonParser.maxDepth;
    }

    - (void)setMaxDepth:(NSUInteger)d {
         jsonWriter.maxDepth = jsonParser.maxDepth = d;
    }

    - (BOOL)humanReadable {
           return jsonWriter.humanReadable;
    }

    - (void)setHumanReadable:(BOOL)x {
        jsonWriter.humanReadable = x;
    }

    - (BOOL)sortKeys {
        return jsonWriter.sortKeys;
    }

    - (void)setSortKeys:(BOOL)x {
        jsonWriter.sortKeys = x;
    }

    @end


The answer is actually pretty simple and it's right there in the error message. You are trying to treat a NSDictionary as if it were an NSArray. The reason you are doin this is because your HTTP request returns an JSON object, not a JSON array. This is it:

{
    "affectedDate": 1310515200000,
    "category": "Sport",
    "content": "Kl 2100 hver tredje lørdag i måneden arrangerer <<<SNIP>>>",
    "eventId": 15946,
    "image": "http://shelf-media.s3.amazonaws.com/39be3cbc5584eb0e9f61c9926a62d478_gmedium.jpg",
    "latitude": "58.1441382",
    "longitude": "7.9933589",
    "title": "HARVEY'S SATURDAY NIGHT FOOTBALL QUIZ"
}

See, not an array. I suspect the fact that you are parsing the same JSON string twice means you wanted to do another HTTP request to get another string, but you have left it out of your code by accident.

Note that, this is basic input validation. You need to check that a) your JSON strings are parsed correctly and b) you get the structure out that you expected. Just because an external service gave you a JSON array yesterday does not mean it will do so today, if the owners of the service change it.

0

精彩评论

暂无评论...
验证码 换一张
取 消