使用转换为NSData时保留NSDictionary键的顺序

我有以下情况:

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

这个字典包含一个web服务请求传递一个JSONstring的web服务URL的参数。 我使用NSJSONSerialization类获取JSONstring,如下所示:

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

问题是:jsonString“keys”按照与原始params字典键顺序不同的顺序sorting,如下所示:

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

}

也就是说,“PaymentState”和“Offer”键首先在jsonString中,我需要保持原来的顺序。 这非常重要,像这样:

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

}

所以,伙计们,我该怎么做?

每当我需要保持我的字典键的顺序时,我使用CocoaWithLove中的OrderedDictionary 。

基本上, OrderedDictionary包含一个NSMutableDictionary和一个NSMutableArray用于内部的键,以跟踪键的顺序。 它实现了NSDictionary / NSMutableDictionary子类化所需的方法,只是将方法调用“传递”给内部的NSMutableDictionary

根据JSON规范 ,JSON对象具体是无序的。 每个JSON库都将考虑到这一点。 所以即使你现在解决这个问题,你几乎肯定会遇到问题, 因为你正在做一个假设不成立(钥匙是有序的)。

尽pipeNSDictionaryDictionary没有为它们的键维护任何特定的顺序,但是从iOS 11和macOS 10.13开始, JSONSerialization支持通过指定sortedKeys选项按字母顺序对键进行sorting( 请参阅Apple文档 )。

例:

 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" // }