2016-12-01 47 views
0

我尝试使用下面的一个NSDictionary对象转换为JSON字符串的重新排序:转换的NSDictionary以JSON字符串引起元素

let data = try JSONSerialization.data(withJSONObject: data, options :[]) 
var string = String(data: data, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue)) 

然而,它重新排序各个元素字母,这是什么斯威夫特的回报:

{"client-nonce":"4q7581q6CbkAlJAAajHuWFiLJTPKJLpk","timestamp":"1480560235","token":"5aeba5cb66644e8e739765632a23f2f98a4035f99306f46777c67cea652dad79","url":"http://api.uselinkthrow.local/api/me/stream/friend/links"} 

我想保持在字典中作出的命令,从而返回此:

{"token":"5aeba5cb66644e8e739765632a23f2f98a4035f99306f46777c67cea652dad79","timestamp":"1480560235","client-nonce":"4q7581q6CbkAlJAAajHuWFiLJTPKJLpk","url":"http://api.uselinkthrow.local/api/me/stream/friend/links"} 

有谁知道我该怎么做?

+0

那怎么世界的作品。此外,如果字典键不正确,会有什么影响? –

+0

HMAC哈希值会有所不同 –

+0

“有谁知道我能做到这一点?”为什么你想这样做?如果你能解释为什么,那么人们可能会提供明智的解决方案。如果你真的想这样做,那么字典(单独)就是错误的数据结构。你需要一个数组,或者一个数组和一个字典的组合。字典本质上是无序的。阵列是有序的。这适用于JSON以及Swift。然而,取决于你对“为什么?”的回答的问题,你可能会更好继续使用字典,然后在需要时操纵键进入一些秩序。 –

回答

3

您不能也不应该依赖JSON对象中元素的排序。

JSON对象是一个键值对,没有订单了,你不能命令它和持续的顺序并不重要

欲了解更多详情检查json.org

+0

星爷我想通这一点,但不知道如果我能超越这一点,我将不得不处理这个服务器端。谢谢 –

+1

我们解决问题的方法是在将字典转换为JSON之前计算已排序键和它们的值的散列值。这不是一个理想的解决方案,但只要在服务器和客户端的算法匹配的哈希值会。 – EricS

+1

@JohnDoe我认为唯一的方法是自己构建JSON字符串,而不是依赖JSONSerialization。因为最终你要发送到服务器端的数据将是字符串格式。 –

0

你不能做到这一点只有一个字典和公正的(单层)JSON。

字典是由JSON和Swift(以及任何其他语言)自然排序的。如果你需要维护一个订单,你应该使用一个数组。

对于你的问题很难给出具体的答案,因为你没有提供任何你想维护这个顺序的理由,也没有提供关于数据产生本质的细节(例如,字典总是有相同的密钥,并且它们应该始终以相同的顺序?)。

但是,如果真的有必要维持秩序,如果你在使用不同的JSON格式的位置,您可以通过以下两种方法做到这一点,根据您的要求:

  1. 如果密钥始终是相同的并且顺序相同...

从数组中填充JSON而不是从原始字典中填充。既然你知道元素的顺序,你就知道哪个元素不需要任何键。

  • 如果键不总是将是相同的,或者不总是会以相同的顺序...
  • 维护的有序阵列密钥以及字典,然后使用该数组以访问字典值的顺序与密钥存储在数组中的顺序相同。

    根据您的要求,您可能需要将数组存储在JSON中(例如,将您的字典与父字典结合使用)。

    这可能有点贵,但为了得到更好的答案,您可能需要提供更多关于您的要求的信息。

    0

    正如其他人所说,这是一本字典,它不是为了提供有序的密钥而设计的。它被设计为具有快速哈希查找功能,所以请继续使用它来按正确的顺序进行。

    我不知道的为什么你想要某种有序串的,所以这只是一个例子,你到过的顺序工作,以打印字符串你想要的:

    if let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any] { 
        ["token", "timestamp", "client-nonce", "url"].forEach({ print(String(describing: json?[$0])) }) 
    }