I am trying to parse the following JSON:
{
"String For Key 1": [
"Some String A",
"Some String B",
"Some String C",
],
"String For Key 2": [
"Some String D",
"Some String E",
"Some String F"
],
"String For Key 3": [
"Some String G",
"Some String H",
"Some String I",
],
"String For Key 4": [
"Some String J",
"Some String K",
"Some String L"
],
"String For Key 5": [
"Some String M",
"Some String N",
"Some String O"
],
"String For Key 6": [
"Some String P",
"Some String Q",
"Some String R"
]
}
I am also following this tutorial. It's on Github in Playground
In the example, they are parsing an Array
of dictionaries using typealias JSONDictionary = [String: AnyObject]
I need to parse a Dictionary
that has a Key
which is String
, and Value
that is an Array
. Hence: typealias JSONDictionary = [String: [AnyObject]]
and I am getting an error when returning a flatMap
.
extension Resource {
init(url: NSURL, parseJSON: AnyObject -> A?) {
self.url = url
self.parse = { data in
let json = try? NSJSONSerialization.JSONObjectWithData(data, options: []) as? [String: [AnyObject]]
//This is where I get an error
return json.flatMap(parseJSON)
}
}
}
Error:
Cannot convert value of type `AnyObject -> A? to expected argument type `([String: [AnyObject]]?) -> _?
How can I get a dictionary with Keys
as String
and Values
as an Array
? I would like to keep their Generic
approach.
Type of jsonString is Dictionary<String, Array<String>>
You can give it a type like Dictionary<String, AnyObject>
AnyObject can contain class and struct i.e Array
, Dictionary
, String
, Int
, Obj C Classes
Hence an Array<String>
is represented by AnyObject
not [AnyObject]
let jsonString:[String: AnyObject] =
[
"String For Key 1": [
"http://www.urlToSomePathA.jpg",
"http://www.urlToSomePathB.jpg",
"http://www.urlToSomePathC.jpg",
],
"String For Key 2": [
"http://www.urlToSomePathD.jpg",
"http://www.urlToSomePathE.jpg",
"http://www.urlToSomePathF.jpg"
]
]
// Now you can map a function on the value type
let values = jsonString.flatMap { $0.1 as? [String] }
print(values)
// RESULT: [["http://www.urlToSomePathA.jpg", "http://www.urlToSomePathB.jpg", "http://www.urlToSomePathC.jpg"], ["http://www.urlToSomePathD.jpg", "http://www.urlToSomePathE.jpg", "http://www.urlToSomePathF.jpg"]]
Update
let keys = jsonString.flatMap { $0.0 } // ["String For Key 1", "String For Key 2"]
As commented by @dffri, you can use keys property on dictionary which will return LazyMapCollection
which will realise only if you access the object inside.
let keys = jsonString.keys
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With