Сохранение порядка ключей NSDictionary при преобразовании в NSData с помощью [NSJSONSerialization dataWithJSONObject:] - программирование
Подтвердить что ты не робот

Сохранение порядка ключей NSDictionary при преобразовании в NSData с помощью [NSJSONSerialization dataWithJSONObject:]

У меня следующая ситуация:

NSDictionary *params = @{
    @"Checkout" : @{
        @"conditions" : @{@"Checkout.user_id" : @1},
        @"order" : @{@"Checkout.id" : @"DESC"}
    },
    @"PaymentState" : @[],
    @"Offer" : @[]
};

Этот словарь содержит параметры для запроса веб-службы, передающего строку JSON с URL-адресом webservice. Я получаю строку JSON, используя класс NSJSONSerialization, например:

NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:nil];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

Проблема в том, что "ключи" jsonString упорядочены по-другому, чем порядковый номер исходного словаря params, например:

{
"Offer":[],
"PaymentState":[],
"Checkout":{
    "conditions":{"Checkout.user_id":6},
    "order":{"Checkout.id":"DESC"}
}

}

То есть, ключи "PaymentState" и "Предложение" входят в первую очередь в jsonString, и мне нужно поддерживать первоначальный заказ. Это очень важно, например:

{
"Checkout":{
    "conditions":{"Checkout.user_id":6},
    "order":{"Checkout.id":"DESC"}
},
"Offer":[],
"PaymentState":[]

}

Итак, ребята, как я могу это сделать?

4b9b3361

Ответ 1

Я использую OrderedDictionary из CocoaWithLove всякий раз, когда мне нужно сохранить порядок ключей словаря.

В принципе, OrderedDictionary содержит NSMutableDictionary и NSMutableArray для ключей внутри него, чтобы отслеживать порядок ключей. Он реализует необходимые методы для подкласса NSDictionary/NSMutableDictionary и просто "передает" вызов метода во внутреннюю NSMutableDictionary.

Ответ 2

В соответствии с спецификацией JSON объект JSON специально неупорядочен. Каждая библиотека JSON будет учитывать это. Поэтому, даже когда вы обойдете эту проблему на данный момент, вы почти наверняка столкнетесь с проблемами позже; потому что вы делаете предположение, что это не верно (что клавиши упорядочены).

Ответ 3

Пока NSDictionary и Dictionary не поддерживают какой-либо определенный порядок для своих ключей, начиная с iOS 11 и macOS 10.13, JSONSerialization поддерживает сортировку клавиш по алфавиту (см. документацию Apple), указав параметр sortedKeys.

Пример:

let data: [String: Any] = [
    "hello": "world",
    "a": 1,
    "b": 2
]

let output = try JSONSerialization.data(withJSONObject: data, options: [.prettyPrinted, .sortedKeys])
let string = String(data: output, encoding: .utf8)

// {
//  "a" : 1,
//  "b" : 2,
//  "hello" : "world"
// }