Ошибка синтаксического анализа NSJSONSerialization: ни словарь, ни массив

я успешно получаю данные с моего сервера. и после его получения я отправляю данные в функцию для разбора;

- (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;
        }

person meth    schedule 17.08.2012    source источник


Ответы (4)


Попробуйте явно указать 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
  }
person glenn sayers    schedule 17.08.2012
comment
результат такой же. Ничего не изменилось - person meth; 17.08.2012
comment
Может быть, попробовать не использовать jsonData в качестве промежуточного шага? id jsonObjects = [NSJSONSerialization JSONObjectWithData:s.... - person glenn sayers; 17.08.2012

Причина сбоя заключается в том, что исходные данные, вероятно, содержат некоторые символы '\', заключающие в кавычки символы '"'. Если бы вы искали «Ошибка какао 3840», вы бы получили подсказку об этом. Что я предлагаю вам сделать, так это распечатайте исходные данные, по одному символу за раз (это ascii, поэтому нет необходимости в UTF) и проверьте это.

char *ptr = [s байт]; for(int i=0; i‹[s length]; ++i) NSLog(@"%c ", *ptr++);

person David H    schedule 17.08.2012
comment
То, что было возвращено, было nil, а не каким-либо объектом, поэтому ошибка была действительной. - person David H; 17.08.2012
comment
да, он получает пробел в начале и «\ 0» в конце данных. - person meth; 17.08.2012
comment
NSString имеет удобные методы для обрезки пробелов на обоих концах строки — очевидно, вы можете их использовать. Вы также можете очистить строку от нулей. Однако ваша проблема, вероятно, глубже, и вам нужно в первую очередь изучить, как именно вы получаете этот JSON. Удачи! - person David H; 17.08.2012

проблема в том, что строка 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. спасибо за людей, которые заинтересованы в моем вопросе.

person meth    schedule 22.08.2012

JSON не принимает любые управляющие символы, кроме табуляции, перевода страницы, возврата каретки и перевода строки в документе JSON, поэтому ваш код работает отлично и делает именно то, что он должен делать, не чтение чего-либо.

Так откуда же взялся этот нулевой символ? Либо ваш код, читающий данные, неправильный, либо сервер неправильный. Мне кажется проблема в сервере. Ваше «исправление» путем отбрасывания последнего символа плохое — если сервер когда-либо будет исправлен, вы выбросите закрывающую фигурную скобку. Я бы связался с тем, кто отвечает за сервер, и решил бы проблему там.

person gnasher729    schedule 10.03.2014