Closed edasque closed 7 years ago
One way to handle this is to make use of the error JSON.Error.valueNotConvertible
that Freddy provides. Below, data
could be whatever you pull down from your server API. The Resident
type comes from Freddy's test suite.
func getDataThatMaybeIsArrayOrDictionary() {
// let data = [ ["name": "Matt", "age": 33, "hasPet": false, "rent": 1000.0],
// ["name": "Drew", "age": 34, "hasPet": true, "rent": 1234.5] ] as JSON
let data = ["name": "Pat", "age": 40, "hasPet": false, "rent": 111.11] as JSON
do {
let residents = try data.decodedArray(type: Resident.self)
print("It's an array: \(residents)")
} catch let JSON.Error.valueNotConvertible(value, type) where type == Array<JSON>.self {
do {
let pat = try value.decode(type: Resident.self)
print("It's a dictionary: \(pat)")
} catch {
// Handle error
}
} catch {
// Handle error
}
}
The nested do/catch
is not ideal. You could do something like this instead if dealing with an optional makes sense:
func getDataThatMaybeIsArrayOrDictionary() {
// let data = [ ["name": "Matt", "age": 33, "hasPet": false, "rent": 1000.0],
// ["name": "Drew", "age": 34, "hasPet": true, "rent": 1234.5] ] as JSON
let data = ["name": "Pat", "age": 40, "hasPet": false, "rent": 111.11] as JSON
do {
let residents = try data.decodedArray(type: Resident.self)
print("It's an array: \(residents)")
} catch let JSON.Error.valueNotConvertible(value, type) where type == Array<JSON>.self {
- do {
- let pat = try value.decode(type: Resident.self)
- print("It's a dictionary: \(pat)")
- } catch {
- // Handle error
- }
+ guard let pat = try? value.decode(type: Resident.self) else { return }
+ print("It's a dictionary: \(pat)")
} catch {
// Handle error
}
}
thank you, I'll try that.
Hi,
I have a call that typically returns an array of dictionaries which I am able to map into an array of structure (via getArray followed by a map). When there is just one result though, the call returns a simple dictionary for that one result (instead of an array of one dictionary). This is a third party API so I cannot change this behavior.
While I can get the keys and values with the dictionary, I can't figure out a way to map it using the same structure init function that I wrote for the array.
Ideally I'd want to do the following: 1) Figure out whether
at:"query","results","quote"
is an array or a dictionary 2) Based on that usegetArray.map
or map automatically the dictionary intoelement
and return it as[element]
a one item array.Thank you in advance,
Erik