tristanhimmelman / ObjectMapper

Simple JSON Object mapping written in Swift
MIT License
9.13k stars 1.03k forks source link

check the value for parse #1119

Open ShenYj opened 3 years ago

ShenYj commented 3 years ago

Your JSON dictionary:

[
{
  "name": null,
  "url": "https://github.com/Hearst-DD/ObjectMapper"
}
]

Your model:

struct Repo: Mappable {
  var name: String!
  var url: URL!

  init(_ map: Map) {
    name <- map["name"]
    url <- map["url"]
  }
}

What you did:

let repo = Mapper< Repo >().mapArray(JSONObject: myJSONDictionary)?

What you expected:

I exepected something like:

repo = []

but now, it's parse object success, when somewhere user this required property, the app crashed!

I wanna let the property required not optional, how I can achieve that effect ?

like init?(map: Map) { }to check the key is exist for check the value ?

b1ack0u7 commented 3 years ago

Hi, I may have a solution for this, as I understood you want that if there's a null in the name it should return nothing.

[IF]: user and url are Any types then if you make an optional downcast to both of them you can determine that url could be a String because it has quotes but on the other side name can´t be a string so it assigns to nil.

[?? Array]: Assign an empty array

struct Repo: Mappable {
    var name: String?
    var url: String?

    init?(map: Map) {
        if(map.JSON["name"] as? String == nil) {
            return nil
        }

        name <- map["name"]
        url <- map["url"]
    }
}

let repo = Mapper<Repo>().mapArray(JSONString: jsonFile) ?? Array()

Result: JSON

[
{
   "user":null,
   "url":"https://github.com/Hearst-DD/ObjectMapper1"
},
{
   "user":"Swiftter",
   "url":"https://github.com/Hearst-DD/ObjectMapper2"
}
]

Swift Output:

repo = [GitHubIssue.Repo(name: Optional("Swiftter"), url: Optional("https://github.com/Hearst-DD/ObjectMapper2"))]

//Or with your JSON file
repo = []

Let me know if I helped you or if I didn't understand ;)

ShenYj commented 3 years ago

Hi, I may have a solution for this, as I understood you want that if there's a null in the name it should return nothing.

[IF]: user and url are Any types then if you make an optional downcast to both of them you can determine that url could be a String because it has quotes but on the other side name can´t be a string so it assigns to nil.

[?? Array]: Assign an empty array

struct Repo: Mappable {
    var name: String?
    var url: String?

    init?(map: Map) {
        if(map.JSON["name"] as? String == nil) {
            return nil
        }

        name <- map["name"]
        url <- map["url"]
    }
}

let repo = Mapper<Repo>().mapArray(JSONString: jsonFile) ?? Array()

Result: JSON

[
{
   "user":null,
   "url":"https://github.com/Hearst-DD/ObjectMapper1"
},
{
   "user":"Swiftter",
   "url":"https://github.com/Hearst-DD/ObjectMapper2"
}
]

Swift Output:

repo = [GitHubIssue.Repo(name: Optional("Swiftter"), url: Optional("https://github.com/Hearst-DD/ObjectMapper2"))]

//Or with your JSON file
repo = []

Let me know if I helped you or if I didn't understand ;)

Thanks for your replay.

That's my wanna effect, The optional is the universal way by me, but it's not well for used where the optional need to work with ??, I wanna a new way easily enough for me