thoughtbot/Argo

How to decode optional array to other type optional array.

iOSCoderJane opened this issue · 2 comments

Sample JSON

{
	"images": [
			"www.whatever.com/samp1.jpg",
			"www.whatever.com/samp2.jpg",
			"www.whatever.com/samp3.jpg"
		]
}

Models

All models involved, including their Decodable implementations.

struct NewsModel {
    let id: [URL]?
}

extension NewsModel: Decodable {
  // ... now, I dont know how to decode an optional array of String to optional array of URL.  I only knowed how to decode an optional String to URL. But optional array, I can't. Could you help me to resolve this question. Thank you.

}

Argo Version

example: Argo 3.0.0

Dependency Manager

examples: Carthage, Cocoapods, git submodules, copied code, etc.

Hi @MrCoderMSH, sorry I'm just now getting to this.

First thing you'll want to do is to conform URL to Decodable. The implementation of this that we use in our test suite looks like:

extension URL: Argo.Decodable {
  public static func decode(_ json: JSON) -> Decoded<URL> {
    switch json {
    case .string(let urlString):
      return URL(string: urlString).map(pure) ?? .typeMismatch(expected: "URL", actual: json)
    default: return .typeMismatch(expected: "URL", actual: json)
    }
  }
}
extension NewsModel: Argo.Decodable {
  static func decode(_ json: JSON) -> Decoded<NewsModel> {
    return curry(NewsModel.init)
      <^> json <||? "images"
  }
}

The <|| operator acts like the <| operator does, but returns an array. We also supply an optional version of this operator (<||?), which will give you the optional array that you're looking for.

I'm going to go ahead and close this due to inactivity but please feel free to reopen if this is still an issue.