Reputation: 161
I created an API that has a JSON response in the following format:
[{"name":"xxx","direct_link":"http:\/\/domain.com\/images\/xxx.png","image":"http:\/\/domain.com\/images\/xxx.png"},{"name":"yyy","direct_link":"http:\/\/domain.com\/images\/yyy.png","image":"http:\/\/domain.com\/images\/yyy.png"}]
Notice how the JSON response has no array title.
My Swift code looks like this:
do {
//converting resonse to NSDictionary
var teamJSON: NSDictionary!
teamJSON = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
//getting the JSON array teams from the response
let teams: NSArray = teamJSON["teams"] as! NSArray
//looping through all the json objects in the array teams
for i in 0 ..< teams.count{
//getting the data at each index
let teamId:Int = teams[i]["name"] as! String!
let teamName:String = teams[i]["direct_link"] as! String!
let teamMember:Int = teams[i]["image"] as! Int!
//displaying the data
print("name -> ", teamId)
print("direct_link -> ", teamName)
print("image -> ", teamMember)
print("===================")
print("")
}
Notice how the array is looking for a title "teams". How can I ensure the JSON is properly parsed and displays the 3 values I need for the JSON response? I'm new to app coding and have a web background, still trying to wrap my head around this.
As it stands when I try to build and run I get the following error: fatal error unexpectedly found nil while unwrapping an optional value
Upvotes: 1
Views: 159
Reputation: 2598
ISSUE:
Your NSJSONSerialization.JSONObjectWithData
would return an NSArray
and not NSDictionary
SOLUTION:
Update code as below:
var teamJSON = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSArray
//getting the JSON array teams from the response
let teams: NSArray = teamJSON
ALSO
Don't force cast values using !
Always cast it as optional using ?
Upvotes: 0
Reputation: 63271
Try this:
do {
guard let teams = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSArray else {
//Doesn't exist, or isn't an NSArray
return
}
for team in teams {
//getting the data at each index
let teamId = team["name"] as! String
let teamName = team["direct_link"] as! String
let teamMember = team["image"] as! Int
//displaying the data
print("name -> ", teamId)
print("direct_link -> ", teamName)
print("image -> ", teamMember)
print("===================")
print()
}
}
//...
Some notes:
String!
)guard let
to enforce preconditions (e.g. the JSON
isn't nil, and is castable to NSArray
).for team in teams
) over iterating a range (for i in 0..<teams.count
)
for i in teams.indices
for (index, team) in teams.enumerate()
Upvotes: 1
Reputation: 13679
The problem is this line:
teamJSON = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary
because you are trying to cast a JSON array to a dictionary.
Just use
teamJSON = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSArray
And then you also won't need to do this:
//getting the JSON array teams from the response
let teams: NSArray = teamJSON["teams"] as! NSArray
Because teamJSON is already the array.
I think the key issue you have to be aware of is that NSJSONSerialization.JSONObjectWithData()
can return either an NSDictionary OR an NSArray, depending on whether the root level data in the JSON is an array or a dictionary.
Upvotes: 1