2017-09-23 10 views
2

オプションのURLを使用するとSwift 4を使用してJSONのデコードが失敗する理由を突き止めようとしています。WWDCの「Whats new in Foundation」ビデオ、 Apples Playgroundの例、およびインターネット上の場所の束が解決策を見つけていない。スウィフト4でJSONのデコードを失敗させるオプションのURL

これは問題を示すために作成したテストです。これは私のJSONデータであると言う:

let json = """ 
{ 
    "kind" : "", 
    "total" : 2, 
    "image_url" : "https://www.myawesomeimageURL.com/awesomeImage.jpg" 
} 
""".data(using: .utf8)! 

そして、これは私の構造体である:私はそれをシリアライズどこ

struct BusinessService: Decodable { 
    let kind: String? 
    let total: Int 
    let image_url : URL? 
} 

そして、ここです:私はJSONを受け取った場合

let myBusiness = try? JSONDecoder().decode(BusinessService.self, from: json) 
print(myBusiness) 

さて、問題がありますデータがimage_urlが見つからない場合、jsonのデコードは失敗し、ゼロになります。

"kind"はオプションの文字列にすることができ、値がないときにjsonデコードが失敗することはありませんが、image_urlはオプションのURLにすることはできません。

私は今、運がない2日間これを理解しようとしています。なぜ誰がこれが失敗するのかについての洞察はありますか?

私はパズルのもう一つの部分を気付きました。それは実際にはjsonのimage_urlが有効な画像URLである必要はありません。私は任意の文字列で入力することができますし、私の構造体がシリアル化されるので、おそらく私はこの動作方法を誤解していると思います。私はURLが有効なURLに変換でき、それが起こっていない場合にのみ、URLが自動的に入力されると考えました。

これに対する洞察は非常に高く評価されます。

答えて

2

これは期待通りに機能します。私はそのように空の文字列として無効なURL値を供給する場合にのみ、トラブルが立ち上がっ

struct Example: Decodable { 
    let url: URL? 
} 

// URL is present. This works, obviously. 
try JSONDecoder().decode(Example.self, from: """ 
    { "url": "foo" } 
    """.data(using: .utf8)!) 

// URL is missing, indicated by null. Also works. 
try JSONDecoder().decode(Example.self, from: """ 
    { "url": null } 
    """.data(using: .utf8)!) 

// URL is missing, not even the key is present. Also works. 
try JSONDecoder().decode(Example.self, from: """ 
    {} 
    """.data(using: .utf8)!) // works, too 

nullimage_urlを設定するか、それを残して完全にimage_urlフィールドのnil値をデコードして得る有効なBusinessServiceにつながりますフィールド。だから私はあなたの問題だと思いますか?

// This throws: "Invalid URL string." 
try JSONDecoder().decode(Example.self, from: """ 
    { "url": "" } 
    """.data(using: .utf8)!) 

あなたはnullを送信するか、アウト全体のラインを残すことにより、URLフィールドに「なし」値を送信する必要があり、空の文字列を送信しません。

私は「種類」は、オプションの文字列で、それは値がないときJSONデコードが失敗する原因ではない、まだIMAGE_URLはJSONが失敗することなく、オプションのURLすることはできませんができ理由として混乱しています。

違いは、JSONで""が有効String値ではなく、有効なURLであることです。

+0

ありがとうございます。これは週末のうちにナッツを動かしていた。私はJSONをあまり使わないので、nullが有効な値であることを認識していませんでした。 私が使用しているAPI(Yelp)がnullの代わりに ""を渡すのは残念です。私はその問題を解決するためにjsonのコンテナ(私は思う)を調べなければならないでしょう。 助けてくれてありがとう! – SN81

+0

お手伝いします!空の文字列と不足している文字列を混同するのは簡単なので、 "空の"場合は常にちょっと難しいです。 Swiftの 'Optional'型は、文字列が欠落しているときに' .none'を、文字列が存在するときに '.some(" ")'を得るので、これを少し良くします。欠落しているURLのために '' ''を渡すことは、本当に悪い選択です。 – zoul

関連する問題