Сохранение порядка ключей 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":[]
}
Итак, ребята, как я могу это сделать?
Ответы
Ответ 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"
// }