web-dev-qa-db-ja.com

JSONSerializationオプションは何を行い、jsonResultをどのように変更しますか?

私は私のプロジェクトでJSONSerializationをかなり頻繁に使用しています。これは私のJSONSerializationコードの例です:

let json = try JSONSerialization.jsonObject(with: data!, options: []) as? [String: Any] 

:目的のためにオプションがありません。通常、プロジェクトにオプションがあります。

私の問題は、これらのoptions: [] 行う?

オプションについて私が見つけたもの:

NSJSONReadingMutableContainers:

配列と辞書が可変オブジェクトとして作成されることを指定します。

NSJSONReadingMutableLeaves:

JSONオブジェクトグラフのリーフ文字列がNSMutableStringのインスタンスとして作成されることを指定します。

NSJSONReadingAllowFragments:

パーサーがNSArrayまたはNSDictionaryのインスタンスではない最上位オブジェクトを許可することを指定します。

注2:これらの定義は次の場所で見つかりました: https://developer.Apple.com/reference/foundation/nsjsonreadingoptions

私の質問はです:誰かがそれらのオプションの違い、私はそれらを何のために使うべきか、それらのオプションのコード例を見せてもらえればそれは完璧でしょう:)。

任意の助けに感謝します。

ありがとう。

22
0ndre_

最初の2つのオプションの短い答え:

Swiftでは無視してください!

Swiftでは、varキーワードでオブジェクトを可変にすることができます。

一方、Objective-Cでは必要です

  • ネストされたコレクション型を可変にするNSJSONReadingMutableContainersNSArrayNSMutableArrayおよびNSDictionaryNSMutableDictionary
  • NSJSONReadingMutableLeavesで値文字列を変更可能にします→NSMutableString

Objective-CとSwiftの場合のみreading使用するJSON可変性はまったく必要ありません。

3番目のオプションNSJSONReadingAllowFragmentsは、受信したJSONのルートオブジェクトがnot配列およびnot辞書である場合に重要です。
それがis配列または辞書の場合、そのオプションも省略できます。

空のブラケットのペア[]No optionsを表します(Swift 3+)ではoptionsパラメーターを省略できます)。

32
vadian

JSONの値がiOSの世界にどのようにインポートされるかをよく知っている必要があります。

 JSON array ->  NSArray
 JSON object -> NSDictionary
 JSON number -> NSNumber
 JSON string -> NSString
 JSON true   -> NSNumber
 JSON false  -> NSNumber
 JSON null   -> NSNull

(JSONのRFCも確認することをお勧めします。 RFC-4627RFC-7159

次に、すべてのオプションを再度確認します。

mutableContainersNSJSONReadingMutableContainers

結果に含まれるNSArraysまたはNSDictionarysがNSMutableArraysまたはNSMutableDictionarysでなければならないことを保証します。古いiOSでは誰かがJSONSerializationNSJSONSerialization)がmutableContainersを指定せずに可変オブジェクトを返したと言いますが、それに依存することはお勧めできません。 iOS 10で動作します。

Swiftでは、可変性はvarおよびletで表されるため、Swiftyコードでこのオプションを使用する必要はありません。逆シリアル化された結果の一部をNSMutableArrayまたはNSMutableDictionaryにキャストする場合にのみ必要です。このようなコードをより迅速に書き直すことを強くお勧めします。

mutableLeavesNSJSONReadingMutableLeaves

結果に含まれるNSStringsがNSMutableStringsでなければならないことを保証します。古いObjective-Cコードでもほとんど使用されないため、無視してください。

allowFragmentsNSJSONReadingAllowFragments

古いRFC(RFC-4627)では、配列とオブジェクトのみがJSONの最も外側のコンポーネントとして有効でした。サーバーから配列またはオブジェクト(NSDictionary)を期待する場合、このオプションを指定しないと、サーバーから無効な戻り値を少し早く見つけるのに役立ちます。

コードの違いを見る:

data1は、次のJSONの有効なUTF-8表現です。

[{"name": "aaa", "value": 123}, {"name": "bbb", "value": 456}]

そしてコード:

do {
    let result = try JSONSerialization.jsonObject(with: data1)
    let resultArray = result as! NSMutableArray //->This may cause your app crash
    //->Could not cast value of type '__NSArrayI' (0x105e79c08) to 'NSMutableArray' (0x105e79cd0).
    print(resultArray)
} catch {
    print(error)
}

do {
    let result = try JSONSerialization.jsonObject(with: data1, options: [.mutableContainers])
    let resultArray = result as! NSMutableArray //->This should always work
    print(resultArray) //->shows output...
} catch {
    print(error)
}

そしてdata2

-1

そして、その比較:

do {
    let result = try JSONSerialization.jsonObject(with: data2)
    print(result)
} catch {
    print(error) //->Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}
}

do {
    let result = try JSONSerialization.jsonObject(with: data2, options: [.allowFragments])
    print(result) //-> -1
} catch {
    print(error)
}
18
OOPer

Options: []は空の配列で、何も返しません。

一方、Options: []は次のように修正することもできます。

  • NSJSONWritingOptions: JSONデータの書き込み用。

    • NSJSONWritingOptions.NSJSONWritingPrettyPrinted:出力を読みやすくするために設計された空白を使用してJSONデータを生成する必要があることを指定します。このオプションが設定されていない場合、最もコンパクトなJSON表現が生成されます。
  • NSJSONReadingOptions: JSONデータからFoundationオブジェクトを作成するときに使用されます。

    • NSJSONReadingOptions.MutableContainers:配列と辞書が可変オブジェクトとして作成されることを指定します。
    • .mutableLeaves: JSONオブジェクトグラフのリーフ文字列がNSMutableStringのインスタンスとして作成されることを指定します。
    • .allowFragments:パーサーがNSArrayまたはNSDictionaryのインスタンスではない最上位オブジェクトを許可することを指定します。
4
vaibhav