2016-12-01 45 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])) }) 
    }