1

我成功地从我的服务器获取数据。得到它后,我将数据发送到函数进行解析;

- (void)readIn:(NSMutableData *)s {
    NSLog(@"Reading in the following:");
    NSString * prints = [[NSString alloc] initWithData:s  encoding:NSUTF8StringEncoding];
    NSLog(@"%@", prints);

    NSError *error = nil;
    NSData *jsonData = [[NSData alloc] initWithData:s];

    if (jsonData) {

        id jsonObjects = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];

        if ([jsonObjects isKindOfClass: [NSArray class]])
            NSLog(@"yes we got an Array");
        else if ([jsonObjects isKindOfClass: [NSDictionary class]])
             NSLog(@"yes we got an dictionary");
        else
              NSLog(@"neither array nor dictionary!");



        if (error) {
            NSLog(@"error is %@", [error localizedDescription]);
            return;
        }

        NSArray *keys = [jsonObjects allKeys];
        for (NSString *key in keys) {
            NSLog(@"%@ is %@",key, [jsonObjects objectForKey:key]);
        }

    } else {

        // Handle Error
    } 
    }

现在我在控制台上的打印是:

    2012-08-17 13:59:57.667 TaraftarlikOyunu[1157:c07] Reading in the following:
2012-08-17 13:59:57.667 TaraftarlikOyunu[1157:c07] {"uID":"5878341","tm":"fb","hh":122,"pt":75,"coin":500,"ll":1,"qlevel":1,"coect":true,"potWeekly":{"pts":75,"intval":604800000},"acent":{"chamunt":0},"mes":[]}
2012-08-17 13:59:57.668 TaraftarlikOyunu[1157:c07] neither array nor dictionary!
2012-08-17 13:59:57.670 TaraftarlikOyunu[1157:c07] error is The operation couldn’t be completed. (Cocoa error 3840.)

对我来说,这似乎是合法的 json 对象。我在哪里做错了?

我正在使用 nsstream 从服务器获取数据;这是我获取数据的代码:

case NSStreamEventHasBytesAvailable: {
            if(stream == inputStream) {
                NSLog(@"inputStream is ready.");

                uint8_t buf[1024];
                unsigned int len = 0;

                len = [inputStream read:buf maxLength:1024];
            NSLog(@"length %i", len);
                if(len > 0) {

                    NSMutableData* data=[[NSMutableData alloc] initWithLength:0];
                    [data appendBytes: (const void *)buf length:len];
                    [self readIn:data];

                }
            }
            break;
        }
4

4 回答 4

0

尝试将 jsonObjects 显式设置为数组:

NSError *myError = nil;

NSArray *jsonObjects= [NSJSONSerialization JSONObjectWithData:responseData   ptions:NSJSONReadingMutableLeaves error:&myError];


for (NSDictionary * dict in jsonObjects) {
    NSLog(@"Some data %@", [dict objectForKey:@"field"]);
    //replace this to access a valid field
  }
于 2012-08-17T11:13:10.720 回答
0

失败的原因是原始数据中可能有一些 '\' 字符引用 '"' 字符。如果你搜索过“Cocoa error 3840”,你会得到一个提示。我建议你做的是打印出原始数据,一次一个字符(它的 ascii 所以不需要 UTF)并验证这一点。

char *ptr = [s 字节]; for(int i=0; i<[s 长度]; ++i) NSLog(@"%c", *ptr++);

于 2012-08-17T11:54:45.070 回答
0

问题是,我得到的 json 字符串最后带有空终止,当我尝试反序列化它时,它无法转换为 NSDictionary 或 NSArray。对代码稍作改动会使一切变得完美。真正的代码应该是这样的

case NSStreamEventHasBytesAvailable: {
        if(stream == inputStream) {

            NSLog(@"inputStream is ready.");

            uint8_t buf[1024];
            unsigned int len = 0;

            len = [inputStream read:buf maxLength:1024];
            NSLog(@"length %i", len);
            if(len > 0) {

                datum =[[NSMutableData alloc] initWithLength:0];

                [datum appendBytes: (const void *)buf length:len-1];




                NSDictionary * jsondict = [NSJSONSerialization JSONObjectWithData:datum options:NSUTF8StringEncoding error:nil];

                NSLog(@"is valid json object %d",[NSJSONSerialization isValidJSONObject:jsondict]);


                [self readIn:datum];
                }
            }
             else {
                NSLog(@"no buffer!");
            }
            break;
            }


    default: {
        NSLog(@"Stream is sending an Event: %i", event);

        break;
    }
}

与另一个的唯一区别是我扔了最后一个字节,它变成了有效的 json 字典。感谢对我的问题感兴趣的人。

于 2012-08-22T15:27:35.220 回答
0

JSON 不接受JSON 文档中除制表符、换页符、回车符和换行符之外的任何控制字符,因此您的代码工作得非常好,并且完全按照它应该做的事情不读取任何内容。

那么那个 nul 字符是从哪里来的呢?您读取数据的代码是错误的,或者服务器是错误的。在我看来,问题出在服务器上。通过丢弃最后一个字符来“修复”是不好的 - 如果服务器曾经修复过,您将丢弃右括号。我会联系负责服务器的人并在那里解决问题。

于 2014-03-10T16:01:53.230 回答