Swift 疑問 — JSONSerialization 的 Options?
究竟 JSONSerialization 的方法中的 Options 參數到底幫我們做了什麼事情呢?
前言:
最近打算整理一些無論是個人或是工作室的大家、學員在開發間所碰到的問題,針對碰到的問題內容來深入的研究,會盡量把提出的疑惑給正確解決,但也有可能遇上無法解釋的狀況,例如:Bug 無法重現之類的…。
因為有些問題可能我也不了解內部發生了什麼原因,所以想藉由這個過程了解到這個問題過程發生了什麼,並且一一去解釋原因,藉由這樣也能使自己多了解一些問題、或是 Bug,同時也能解決他們的疑惑。
●
發生情況:
前陣子在工作室在進行小型 Side Project 活動時,當時候有人在進行透過 API 將參數發送給後端這邊碰到了問題,每次發送的 request
後得到的 response
都是沒有帶上參數,而她是使用 try?
配合 JSONSerialization
在進行將 Dictionary ( JSON )
類型轉換成 Data?
作為請求的 httpBody
發送。
而我們實際將他的 httpBody
再次解析成 JSON
,也是得到相同的內容。
- 意外的解決?我不這麼認為 🤨
而這時候有人使用 do-catch
的方式來執行 JSONSerialization
的 data(withJSONObject:options:)
的方法,並且在其 options
參數中加上了一個 JSONSerialization.WritingOptions()
的實例化,接著發送請求並且得到後端正確的返回值。
這時讓我一頭霧水,因為我覺得會有以下幾點問題
httpBody
的參數可以讓你賦與一個Data?
類型的值,畢竟原本經由我們透過try?
以及JSONSerialization
轉換成Data
的返回值就是為Data?
類型,所以我不認為還需要使用do-catch
方式來處理會有差異( 除非想要看到JSONSerialization
的錯誤描述 )。JSONSerialization.WritingOptions()
這個實例化到底實例化了什麼?因為就我的了解,這個options
參數所能帶入的類型應該為一個JSONSerialization.WritingOptions
類型的值(原本以為它是一個Enumeration
類型的值,後來發現是struct
),但也只有.sortedKeys
與.prettyPrinted
兩種值可以採用,而透過rawValue
所初始化出來的又是什麼?- 但是它對於後端的其他請求沒有加上
options
參數卻還是能透過,所以我覺得只有這個請求要加上options
並不合理,照理說也不需要。
後來採用原本的不加上 options 方式,莫名其妙地得到後端正確的回傳…
一個無法重現的 Bug 啊~ 😭😭😭
● JSONSerialization 的 Options
在我們使用 JSONSerialization
對於 data
以及 jsonObject
兩種方法也有不同的 options
可以採用,分別為 WritingOptions
以及 ReadingOptions
,讓我們來分別認識這兩者:
WritingOptions,用來編寫 JSON 數據的選項。
- prettyPrinted
此選項藉由使用空格及縮排讓輸出結果更具可讀性。- sortedKeys
此選項會讓結果按字典中的key值進行排序。
ReadingOptions,從 JSON 數據創建 Foundation Objects 時使用的選項。
- mutableContainers
指定將數組和字典創建為可變對象。- mutableLeaves
指定將 JSON 對象圖中的字串創建為 NSMutableString 的實例。- allowFragments
指定解析器(Parser)允許不是 NSArray 或 NSDictionary 為頂層對象的實例。
並且這兩者都有一個 init(rawValue: UInt)
方法,但是透過它初始化出來的值不知道是什麼用途。
而我在 stack overflow 上的這篇文章找尋到類似的問題,只是它想要找 ReadingOptions
的功用,而下面回覆提到了:
⚠️ 在 Swift 中請忽略它們在 Swift 中你可以透過使用 var 使對象變為可變;而在 Objective-C 則需要透過這種方式,使一個 Array 或是 Dictionary 變為可變的。在 Objective-C 和 Swift 中,如果您只是閱讀JSON,則不需要可變性。
而 WritingOptions
在我測試的時候,好像就算帶上 options
也沒有效果,好像沒有看到官方文檔內的效果(又或許它已經自動幫我們實現了):
後記:
這可能是我第一篇文章寫到不知道如何下手的,尤其許多地方都好像無從解釋,像是 Bug 無法重現和 options
的 rawValue
到底初始化了什麼,以及最後在 options
帶參數和不帶參數的差異在哪?雖然官方文檔有提供說明該值的作用是什麼,但也沒有實際的範例或是說明這種方法是否可行,又或是說明 Objective-C 需要,Swift 不需要之類的訊息。
如果有寫錯的部分或是有人可以幫忙解答的部分,歡迎各位在下方留言指教,希望能將正確的資訊帶給大家。