Parse json in Swift, AnyObject type - json

I'm trying to parse a json but I have some difficulties with the data types and notably the AnyObject type + downcasting.
Let's consider the following json (it's an extract of a full json).
{ "weather":
[
{
"id":804,
"main":"Clouds",
"description":"overcast clouds",
"icon":"04d"
}
],
}
To me, the json can be described as follow :
- json: Dictionary of type [String: AnyObject] (or NSDictionary, so = [NSObject, AnyObject] in Xcode 6 b3)
- "weather": Array of type [AnyObject] (or NSArray)
- Dictionary of type [String: AnyObject] (or NSDictionary, so = [NSObject, AnyObject] in Xcode 6 b3)
My json is of type AnyObject! (I use JSONObjectWithData to get the JSON from a URL).
I then want to access the weather Dictionary. Here is the code I wrote.
var localError: NSError?
var json: AnyObject! = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &localError)
if let dict = json as? [String: AnyObject] {
if let weatherDictionary = dict["weather"] as? [AnyObject] {
// Do stuff with the weatherDictionary
}
}
Here is the error I got
Playground execution failed: error: <EXPR>:28:56: error: '[AnyObject]' is not a subtype of '(String, AnyObject)'
if let weatherDictionary = dict["weather"] as? [AnyObject] {
I don't understand why dict["weather"] is compared to a subtype of (String, AnyObject) and not AnyObject.
I declared my dictionary as [String: AnyObject], so I i access a value using the String key, I should have an AnyObject, no ?
If I use NSDictionary instead of [String: AnyObject], it works.
If I use NSArray instead of [AnyObject], it works.
- The Xcode 6 beta 3 release notes tell that "NSDictionary* is now imported from Objective-C APIs as [NSObject : AnyObject].".
- And the Swift book: "When you bridge from an NSArray object to a Swift array, the resulting array is of type [AnyObject]."
EDIT
I forgot to force unwrapping the dict["weather"]!.
if let dict = json as? [String: AnyObject] {
println(dict)
if let weatherDictionary = dict["weather"]! as? [AnyObject] {
println("\nWeather dictionary:\n\n\(weatherDictionary)")
if let descriptionString = weatherDictionary[0]["description"]! as? String {
println("\nDescription of the weather is: \(descriptionString)")
}
}
}
Note that we should double check for the existence of the first Optional.
if let dict = json as? [String: AnyObject] {
for key in ["weather", "traffic"] {
if let dictValue = dict[key] {
if let subArray = dictValue as? [AnyObject] {
println(subArray[0])
}
} else {
println("Key '\(key)' not found")
}
}
}

This works fine for me in the playground and in the terminal using env xcrun swift
UPDATED FOR SWIFT 4 AND CODABLE
Here is a Swift 4 example using the Codable protocol.
var jsonStr = "{\"weather\":[{\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"}],}"
struct Weather: Codable {
let id: Int
let main: String
let description: String
let icon: String
}
struct Result: Codable {
let weather: [Weather]
}
do {
let weather = try JSONDecoder().decode(Result.self, from: jsonStr.data(using: .utf8)!)
print(weather)
}
catch {
print(error)
}
UPDATED FOR SWIFT 3.0
I have updated the code for Swift 3 and also showed how to wrap the parsed JSON into objects. Thanks for all the up votes!
import Foundation
struct Weather {
let id: Int
let main: String
let description: String
let icon: String
}
extension Weather {
init?(json: [String: Any]) {
guard
let id = json["id"] as? Int,
let main = json["main"] as? String,
let description = json["description"] as? String,
let icon = json["icon"] as? String
else { return nil }
self.id = id
self.main = main
self.description = description
self.icon = icon
}
}
var jsonStr = "{\"weather\":[{\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"}],}"
enum JSONParseError: Error {
case notADictionary
case missingWeatherObjects
}
var data = jsonStr.data(using: String.Encoding.ascii, allowLossyConversion: false)
do {
var json = try JSONSerialization.jsonObject(with: data!, options: [])
guard let dict = json as? [String: Any] else { throw JSONParseError.notADictionary }
guard let weatherJSON = dict["weather"] as? [[String: Any]] else { throw JSONParseError.missingWeatherObjects }
let weather = weatherJSON.flatMap(Weather.init)
print(weather)
}
catch {
print(error)
}
-- Previous Answer --
import Foundation
var jsonStr = "{\"weather\":[{\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"}],}"
var data = jsonStr.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: false)
var localError: NSError?
var json: AnyObject! = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers, error: &localError)
if let dict = json as? [String: AnyObject] {
if let weather = dict["weather"] as? [AnyObject] {
for dict2 in weather {
let id = dict2["id"]
let main = dict2["main"]
let description = dict2["description"]
println(id)
println(main)
println(description)
}
}
}
Since I'm still getting up-votes for this answer, I figured I would revisit it for Swift 2.0:
import Foundation
var jsonStr = "{\"weather\":[{\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"}],}"
var data = jsonStr.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: false)
do {
var json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)
if let dict = json as? [String: AnyObject] {
if let weather = dict["weather"] as? [AnyObject] {
for dict2 in weather {
let id = dict2["id"] as? Int
let main = dict2["main"] as? String
let description = dict2["description"] as? String
print(id)
print(main)
print(description)
}
}
}
}
catch {
print(error)
}
The biggest difference is that the variable json is no longer an optional type and the do/try/catch syntax. I also went ahead and typed id, main, and description.

Try:
https://github.com/dankogai/swift-json
With it you can go like this:
let obj:[String:AnyObject] = [
"array": [JSON.null, false, 0, "", [], [:]],
"object":[
"null": JSON.null,
"bool": true,
"int": 42,
"double": 3.141592653589793,
"string": "a α\t弾\n𪚲",
"array": [],
"object": [:]
],
"url":"http://blog.livedoor.com/dankogai/"
]
let json = JSON(obj)
json.toString()
json["object"]["null"].asNull // NSNull()
json["object"]["bool"].asBool // true
json["object"]["int"].asInt // 42
json["object"]["double"].asDouble // 3.141592653589793
json["object"]["string"].asString // "a α\t弾\n𪚲"
json["array"][0].asNull // NSNull()
json["array"][1].asBool // false
json["array"][2].asInt // 0
json["array"][3].asString // ""

Using my library (https://github.com/isair/JSONHelper) you can do this with your json variable of type AnyObject:
var weathers = [Weather]() // If deserialization fails, JSONHelper just keeps the old value in a non-optional variable. This lets you assign default values like this.
if let jsonDictionary = json as? JSONDictionary { // JSONDictionary is an alias for [String: AnyObject]
weathers <-- jsonDictionary["weather"]
}
Had your array not been under the key "weather", your code would have been just this:
var weathers = [Weather]()
weathers <-- json
Or if you have a json string in your hands you can just pass it as well, instead of creating a JSON dictionary from the string first. The only setup you need to do is writing a Weather class or struct:
struct Weather: Deserializable {
var id: String?
var name: String?
var description: String?
var icon: String?
init(data: [String: AnyObject]) {
id <-- data["id"]
name <-- data["name"]
description <-- data["description"]
icon <-- data["icon"]
}
}

Related

Decoding JSON with variable parameters using Codable

I have a json response like this
{
"name":"test",
"params":{
"param1":"testA",
"param2":4055,
"param3":9593.34959,
"question":"is this is a test?",
"anything":"testing?",
"random":true
},
"price":103.3
}
My codable struct looks like this
struct:Codable {
var name:String
var params:[String:String]?
var price:Double
}
I have set params to optional because sometimes there are no params but a lot of times there are and codable has an issue because I don't know what types the values in the params dictionary are. I don't even know what the keys are sometimes. I just want to parse them as a dictionary of keys and values with values of type Bool, Int, Double, or String. so a dict like this
let params = ["paramA":1, "param2":"test", "param3":true]
or in the case of the above json this:
let params = ["param1":"testA", "param2":4055, "param3": 9593.34959, "question":"is this is a test?", "anything":"testing?", "random":true]
I am pretty sure I have to create a custom decoder but not exactly sure how to do it.
In your case it's easier to decode json manually like so:
public enum SerializationError: Error {
case wrongRootElement(String)
case missing(String)
case invalid(String, Any)
}
struct YourStruct {
var name:String
var params:[String: String]?
var price:Double
}
extension YourStruct {
public init(json: Any) throws {
guard let jsonDict = json as? [String: Any] else {
throw SerializationError.wrongRootElement("Expected json dictionary not \(json)")
}
guard let name = jsonDict["name"] as? String else {
throw SerializationError.missing("name")
}
let params = jsonDict["params"] as? [String: Any]
let paramsStrs = params?.reduce(into: [String: String]()) { (result, keyValue) in
result[keyValue.key] = String(describing: keyValue.value)
}
guard let price = jsonDict["price"] as? Double else {
throw SerializationError.missing("price")
}
self.init(name: name, params: paramsStrs, price: price)
}
}
let anyYourStruct = try? JSONSerialization.jsonObject(with: jsonData, options: [])
let yourStruct = try? YourStruct(json: anyYourStruct)

The JSON output does not contain a key: "value"

I have a JSON parsing issue with my Swift code below. The error I am getting says that my JSON output does not contain a key value.
My code:
Alamofire.request(url, method: .get, headers: headers).responseJSON { (response) -> Void in
let jsonValue = response.result.value as! NSDictionary
if let bpArray = jsonValue["value"] as? [NSDictionary]{
for results in bpArray {...}
Issue:
This conversion doesnt work: if let bpArray = jsonValue["value"] as? [NSDictionary]
My JSON Structure:
{
d: {
results: [
{
__metadata: {},
Key: "AFBWhULFHtKU4j4FhWCmKg==",
ParentKey: "AAAAAAAAAAAAAAAAAAAAAA==",
RootKey: "AFBWhULFHtKU4j4FhWCmKg==",
Partner: "MM-CARR-01",
Type: "2",
Description: "MM Demo Carrier Created for Single Stop / MA",
FrieghtOrder: {}
},
...
Assuming you want to access the results key so try like this:-
if let bpArray = jsonValue["results"] as? [String: AnyObject]{
//yourcode
}
Well your json structure haven't got any key named as value and that's why it's giving an error.
In order to get results array, you first need to get the object in which they are nested and for example 'g' in your case:
if let data = jsonValue["d"] as? [NSDictionary]{
if let resultsArray = data["results"] as? NSArray {
//your code
}
}
Please Use Swifty Json Pod And Try this code
pod 'SwiftyJSON'
In Your file where you get response
import SwiftyJSON
Then After Use This Code
switch response.result {
case .success(let JSON2):
print("Success with JSON: \(JSON2)")
// print("Request failed with error: \(response.response?.statusCode)")
if let response = JSON2 as? NSMutableDictionary
{
}
else if let response = JSON2 as? NSDictionary
{
if let data = response?.object(forKey: "d") as? NSDictionary
{
if let resultsArray = data?.object(forKey: "results") as? NSArray
{
}
}
}
else if JSON2 is NSArray
{
let swjson = JSON(response.result.value!)
print(swjson)
// callback(swjson,nil)
var myMutableDictionary = [AnyHashable: Any]()
myMutableDictionary["myArray"] = swjson
callback(myMutableDictionary as NSDictionary?,nil)
print("accc")
}
else if ((JSON2 as? String) != nil)
{
let userDic : [String : String] = ["quatid":JSON2 as! String]
print(userDic)
}
break
case .failure(let error):
print("Request failed with error: \(error)")
}
Remember it's better we not use NSArray & NSDictionary like things in SWIFT, SWIFT it self providing let, var keyword for various data type.
First you can create your model where you can save the data.
MyModel.swift
class MyModel: NSObject {
var ParentKey : Int?
init(jsonObject:[String:Any]) {
ParentKey = jsonObject["ParentKey"] as? String ?? ""
}
}
Viewcontroller.Swift
var myModel : [MyModel] = []
if let responseData = response["d"] as? [String:Any]{
if let dataObject = responseData["results"] as? [[String:Any]]{
self.myModel = dataObject.map({return MyModel(jsonObject: $0)})//for assigning data into model
}
}
As most people said, I was wrong with "value". Hussain's answer to using [String:AnyObject] Helped.
I am not sure if the below is neat to achieve, but it did the magic. App loaded as expected. Code expert below:
Solution:
if let bpData = jsonValue["d"] as? [String: AnyObject]{
for results in bpData {
let arrayInterim = results.value as? NSArray
for i in 0 ..< arrayInterim!.count {

Parse JSON data in swift

I am trying to parse my json data in swift 3.0. I am using Alamofire 4.0+
Here is my json
{
"token":
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MDQ0MjgzNzgxMTF9.CNonyvtQbRgaqqkdPO5KwqpVaUmlGrpaTqlBxmvaX80",
"expires": 1504428378111,
"user":
[{"user_id":13,"user_first_name":"Himanshu","user_last_name":"Srivastava","full_name":"Himanshu Srivastava"}]
}
Here is my model class to hold these values
import Foundation
import ObjectMapper
class LoginResult:Mappable{
var token:String?
var expires:Double?
var users:[[String:Any]]?
required init?(map:Map){
}
func mapping(map:Map)->Void{
self.token <- map["token"]
self.expires <- map["expires"]
self.users <- map["user"]
}
}
None of the solution available on internet worked for me. How can I parse this json and map to the model class?
Any help here?
I was mistaken, the value for key user is indeed a regular array.
This is a solution without a third party mapper and with an extra User struct (by the way the value for key expires is an Int rather than Double).
Assuming the user data comes from a database which always sends all fields the user keys are forced unwrapped. If this is not the case use optional binding also for the user data:
struct User {
let firstName : String
let lastName : String
let fullName : String
let userID : Int
}
class LoginResult {
let token : String
let expires : Int
var users = [User]()
init(json : [String:Any]) {
self.token = json["token"] as? String ?? ""
self.expires = json["expires"] as? Int ?? 0
if let users = json["user"] as? [[String:Any]] {
self.users = users.map { User(firstName: $0["user_first_name"] as! String,
lastName: $0["user_last_name"] as! String,
fullName: $0["full_name"] as! String,
userID: $0["user_id"] as! Int)
}
}
}
}
let json = "{\"token\":\"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MDQ0MjgzNzgxMTF9.CNonyvtQbRgaqqkdPO5KwqpVaUmlGrpaTqlBxmvaX80\",\"expires\":504428378111,\"user\":[{\"user_id\":13,\"user_first_name\":\"Himanshu\",\"user_last_name\":\"Srivastava\",\"full_name\":\"Himanshu Srivastava\"}]}"
let jsonData = json.data(using: .utf8)!
do {
if let userData = try JSONSerialization.jsonObject(with: jsonData) as? [String:Any] {
let loginResult = LoginResult(json: userData)
print(loginResult.users[0])
// do something with loginResult
}
} catch {
print(error)
}
Here is the answer with map replaced by dictionary. Don't forget to handle error or unwrap carefully :)
let str = "{\"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MDQ0MjgzNzgxMTF9.CNonyvtQbRgaqqkdPO5KwqpVaUmlGrpaTqlBxmvaX80\",\"expires\": 1504428378111,\"user\": [{\"user_id\":13,\"user_first_name\":\"Himanshu\",\"user_last_name\":\"Srivastava\",\"full_name\":\"Himanshu Srivastava\"}]}"
let data = str.data(using: .utf8)
do{
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? [String: Any]
//Pass this json into the following function
}catch let error{
}
func mapping(json:[String: Any]?)->Void{
self.token <- json?["token"] as? String
self.expires <- json?["expires"] as? Double
self.users <- json?["user"] as? [[String: Any]]
}

How to properly create objects from a JSON dictionary that start with a numbers instead of strings?

I'm having a tough time creating objects from the JSON below. It's weirdly formatted with = and ; but that's how it looks when printed to console:
result = (
{
media = {
image = {
1000 = "/assets/img/cities/basel-switzerland-1000px.jpg";
1500 = "/assets/img/cities/basel-switzerland-1500px.jpg";
250 = "/assets/img/cities/basel-switzerland-250px.jpg";
500 = "/assets/img/cities/basel-switzerland-500px.jpg";
};
};
}
)
I've created custom objects but I keep getting a
EXC_BAD_INSTRUCTION
error when I use [Int: Any] for the "image" and when I substitute NSNumber instead I get an error:
Could not cast value of type 'NSTaggedPointerString' (0x10ee4ad10) to
'NSNumber' (0x10bc88488).
Here is my custom class for the JSON objects:
class sampleJSON {
var mediaDictionary: [String: Any]
var imageDictionary: [Int: Any]
var image: URL
init( mediaDictionary: [String: Any], imageDictionary: [Int: Any], image: URL){
self.mediaDictionary = mediaDictionary
self.imageDictionary = imageDictionary
self.image = image
}
init(resultsDictionary:[String: Any]){
mediaDictionary = (resultsDictionary["media"] as? [String: Any])!
imageDictionary = (mediaDictionary["image"] as? [Int: Any])!
image = URL(string: imageDictionary[1000] as! String)!
}
This is how I'm parsing the JSON data:
static func downloadAllData(urlExtension: String, completionHandler: #escaping (sampleJSON?) -> ()) {
let usm = UrlSessionNetworkManager.sharedManager
if let jsonDictionary = usm.parseJSONFromData(urlExtension:"\(urlExtension)")
{
let resultDictionaries = jsonDictionary["result"] as! [[String : Any]]
for resultsDictionary in resultDictionaries {// enumerate through dictionary
let nomadInfo = sampleJSON(resultsDictionary: resultsDictionary)
print(nomadInfo.mediaDictionary)
completionHandler(nomadInfo)
}
} else {
print("Error: Cannot retrieve JSON Data")
}
}
}
Replace all occurences of [Int: Any] with [String: Any], and make that change in the server code, too. As mentioned by #Paulw11, JSON keys can only be strings (but a value can be a string in double quotes, or a number, or true or false or null, or an object or an array). Also, as I mentioned, never use (a as? b)!, instead use a as! b.
The new (and now valid) JSON should look like:
result = (
{
media = {
image = {
"1000" = "/assets/img/cities/basel-switzerland-1000px.jpg";
"1500" = "/assets/img/cities/basel-switzerland-1500px.jpg";
"250" = "/assets/img/cities/basel-switzerland-250px.jpg";
"500" = "/assets/img/cities/basel-switzerland-500px.jpg";
};
};
}
)
The custom class should be:
class sampleJSON {
var mediaDictionary: [String: Any]
var imageDictionary: [String: Any]
var image: URL
init( mediaDictionary: [String: Any], imageDictionary: [String: Any], image: URL){
self.mediaDictionary = mediaDictionary
self.imageDictionary = imageDictionary
self.image = image
}
init(resultsDictionary:[String: Any]){
mediaDictionary = resultsDictionary["media"] as! [String: Any]
imageDictionary = mediaDictionary["image"] as! [String: Any]
image = URL(string: imageDictionary["1000"] as! String)!
}
And the parsing function should be (just a small, unrelated issue fixed):
static func downloadAllData(urlExtension: String, completionHandler: #escaping (sampleJSON?) -> ()) {
let usm = UrlSessionNetworkManager.sharedManager
if let jsonDictionary = usm.parseJSONFromData(urlExtension: urlExtension)
{
let resultDictionaries = jsonDictionary["result"] as! [[String : Any]]
for resultsDictionary in resultDictionaries {// enumerate through dictionary
let nomadInfo = sampleJSON(resultsDictionary: resultsDictionary)
print(nomadInfo.mediaDictionary)
completionHandler(nomadInfo)
}
} else {
print("Error: Cannot retrieve JSON Data")
}
}
}

TableView Json Swift

I currently developing an app which list user object by making an request to a webservice, which send a response in JSON in this format :
{
"0":
{
"id":"30",
"title":"galaxys6",
"price":"550",
"description":"neuf",
"addedDate":"2015-07-16 15:04:24",
"user_id":"2",
"user_name":"",
"user_zipCode":"69003",
"category_id":"1",
"category_label":"PHONE",
"subcategory_id":"1",
"subcategory_label":"Phone",
"picture":"",
"bdd":{},
"picture_url":"http:\/\/jdl-barreme-orange.dyndns.org\/WEBSERVICE\/pictures\/galaxy s6.JPG"
},
"1":
{
"id":"31",
"title":"iphone4",
"price":"570",
"description":"neuf",
"addedDate":"2015-07-16 15:14:54",
"user_id":"2",
"user_name":"",
"user_zipCode":"69003",
"category_id":"1",
"category_label":"PHONE",
"subcategory_id":"1",
"subcategory_label":"Phone",
"picture":"",
"bdd":{},
"picture_url":"http:\/\/jdl-barreme-orange.dyndns.org\/WEBSERVICE\/pictures\/iphone.JPG"
},
}
For each object my webservice create a dictionary (0;1;2;3....)
I search a method to retrieve for each dictionary the value title and price and put them in a tableView.
Code I used (tableviewcontroller) :
if let jsonData:NSDictionary = NSJSONSerialization.JSONObjectWithData(urlData!, options:NSJSONReadingOptions.MutableContainers , error: &error) as? NSDictionary{
// 4
if let resp = jsonData["1"] as? [NSDictionary] {
NSLog("%#", resp)
// 5
for item in resp {
repositories.append(Repository(jsonData: item))
}
repository controller :
class Repository {
var name: String?
var description: String?
var html_url: String?
init(jsonData: NSDictionary) {
self.name = jsonData["id"] as? String
self.description = jsonData["description"] as? String
self.html_url = jsonData["title"] as? String
}
}
But it doesn't work, I put a breakpoint, and xcode stop to interpret here :
if let resp = jsonData["1"] as? [NSDictionary] {
NSLog("%#", resp)
What am I doing wrong?
Thank you.
Here's how to get the title and price for your JSON:
if let json = NSJSONSerialization.JSONObjectWithData(urlData!, options: nil, error: nil) as? [String:AnyObject] {
for (_, value) in json {
if let dict = value as? [String:AnyObject] {
if let title = dict["title"] as? String {
println(title)
}
if let price = dict["price"] as? String {
println(price)
}
}
}
}
This can also be used to init your Repository classes if you want:
class Repository {
var name: String?
var description: String?
var html_url: String?
init(jsonData: [String:AnyObject]) {
self.name = jsonData["id"] as? String
self.description = jsonData["description"] as? String
self.html_url = jsonData["title"] as? String
}
}
var repos = [Repository]()
if let json = NSJSONSerialization.JSONObjectWithData(urlData!, options: nil, error: nil) as? [String:AnyObject] {
for (_, value) in json {
if let dict = value as? [String:AnyObject] {
let repo = Repository(jsonData: dict)
repos.append(repo)
}
}
}
for repo in repos {
println(repo.name)
println(repo.description)
println(repo.html_url)
}
In the loop I'm ignoring the key: for (_, value) in json but you can use it if needed of course:
for (key, value) in json {
println(key) // "1", "2", ...
// ...
}
UPDATE:
Following your comment asking how to use this answer if your data format is different: if you want an array of dictionaries, change the typecast of the NSJSONSerialization result to reflect that: [[String:AnyObject]]. Next you can iterate over your array to get each dictionary properties:
if let jsonArray = NSJSONSerialization.JSONObjectWithData(urlData!, options: nil, error: nil) as? [[String:AnyObject]] {
for dict in jsonArray {
if let title = dict["title"] as? String {
println(title)
}
}
}
You are making a mistake here
if let resp = jsonData["1"] as? [NSDictionary]
This should be a NSDictionary not [NSDictionary], (which would be an array of dictionaries).
Also this conditional block
if let reposArray = jsonData["items"] as? [NSDictionary]
will never be executed because jsonData does not contain a key "items".
I guess it is the [NSDictionary]
if let resp = jsonData["1"] as? [NSDictionary]
[NSDictionary] is array of NSDictionary same as Array<NSDictionary>
just remove the brackets [] and change to
if let resp = jsonData["1"] as? NSDictionary