[解決済み] JSONEncoderでnil値をnullとしてエンコードする
質問
私はSwift 4の
JSONEncoder
. を持っているのですが
Codable
構造体にオプションのプロパティがあり、このプロパティを
null
の値として表示させたい。
nil
. しかし
JSONEncoder
はプロパティを破棄し、JSON出力に追加されません。を設定する方法はありますか?
JSONEncoder
を構成して、キーを保持し、それを
null
に設定するのでしょうか?
例
以下のコード・スニペットは
{"number":1}
を生成しますが、私はむしろこのコードで
{"string":null,"number":1}
:
struct Foo: Codable {
var string: String? = nil
var number: Int = 1
}
let encoder = JSONEncoder()
let data = try! encoder.encode(Foo())
print(String(data: data, encoding: .utf8)!)
どのように解決するのですか?
はい、しかし、あなたは独自の
encode(to:)
の実装を書く必要があり、自動生成されたものを使うことはできません。
struct Foo: Codable {
var string: String? = nil
var number: Int = 1
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(number, forKey: .number)
try container.encode(string, forKey: .string)
}
}
オプショナルを直接エンコードすると、探しているようなNULLがエンコードされます。
もしこれがあなたにとって重要なユースケースであるなら、以下のサイトで欠陥を開くことを検討してください。
bugs.swift.org
にて、新しい
OptionalEncodingStrategy
フラグを JSONEncoder に追加し、既存の
DateEncodingStrategy
などです(なぜこれが今日のSwiftで実際に実装することが不可能である可能性が高いかを以下でご覧ください。しかし、追跡システムに入ることはSwiftが進化する際にまだ役に立ちます)。
編集: 下のPauloの質問に対して、これは一般的な
encode<T: Encodable>
バージョンにディスパッチします。
Optional
に準拠しています。
Encodable
. この実装は
Codable.swift
をこのようにします.
extension Optional : Encodable /* where Wrapped : Encodable */ {
@_inlineable // FIXME(sil-serialize-all)
public func encode(to encoder: Encoder) throws {
assertTypeIsEncodable(Wrapped.self, in: type(of: self))
var container = encoder.singleValueContainer()
switch self {
case .none: try container.encodeNil()
case .some(let wrapped): try (wrapped as! Encodable).__encode(to: &container)
}
}
}
の呼び出しをラップしています。
encodeNil
そして、stdlib に Optionals をただの Encodable として扱わせる方が、独自のエンコーダで特別なケースとして扱って
encodeNil
を呼び出すよりも良いと思います。
もうひとつの明白な疑問は、そもそもなぜこのように動作するのかということです。Optional は Encodable であり、生成された Encodable 適合性はすべてのプロパティをエンコードするので、なぜ "encode all the properties by hand" は異なる動作をするのでしょうか。その答えは、適合性生成器が がOptionalsのための特別なケースを含んでいるからである。 :
// Now need to generate `try container.encode(x, forKey: .x)` for all
// existing properties. Optional properties get `encodeIfPresent`.
...
if (varType->getAnyNominal() == C.getOptionalDecl() ||
varType->getAnyNominal() == C.getImplicitlyUnwrappedOptionalDecl()) {
methodName = C.Id_encodeIfPresent;
}
つまり、この動作を変更するには、自動生成されたコンフォーマンスを変更する必要があり、そのためには
JSONEncoder
(を変更する必要があるということです(これはまた、今日のSwiftで設定可能にするのが本当に難しいということでしょう......)。
関連
-
iOS classic error Undefined symbols for architecture XXX:
-
dyld: ライブラリがロードされていません。エラーの解決
-
[解決済み] cURLでJSONデータをPOSTするにはどうすればよいですか?
-
[解決済み] jQueryでフォームデータをJavaScriptオブジェクトに変換する
-
[解決済み] UITableViewの選択を無効にするにはどうすればよいですか?
-
[解決済み] iOSのステータスバーの文字色を変更する方法
-
[解決済み] App Storeのアプリと連動させる方法
-
[解決済み] Xcode 12、iOS Simulator用にビルドしても、iOS用にビルドされたオブジェクトファイルでは、アーキテクチャ「arm64」用にリンクされます。
-
[解決済み] Swiftで配列に要素を追加する
-
[解決済み] Swift 4 の JSONDecoder で、見つからないキーは、オプションのプロパティである必要はなく、デフォルト値を使うことができますか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
libc++abi.dylib が NSException 型の捕捉できない例外で終了する理由 エラー
-
[解決済み] カスタムオブジェクトを含むNSMutableArrayをソートするにはどうすればよいですか?
-
[解決済み] Objective-Cでデリゲートを作成するにはどうしたらいいですか?
-
[解決済み] 奇妙な不要なXcodeログを隠す
-
[解決済み] iOS 13 のフルスクリーンでモーダルを表示する
-
[解決済み] UITextViewのマージン/パディングをなくす方法
-
[解決済み] UITextFieldのテキストインセット?
-
[解決済み] Swift で HTTP リクエストを行うにはどうしたらいいですか?
-
[解決済み] UIImageのサイズを変更する最も簡単な方法?
-
[解決済み] iPhoneでナビゲーションバーを1ページ目だけ非表示にする