Reputation: 149
Sorry, I wasn't quite sure how to phrase the question. So I know exactly what the problem is. I am reading from several plists. Some of the plists have no Array stored in "evolved_species_id", which gives the error
Index out of range
How do I get my code to skip over the instances of "evolved_species_id" that have no stored array? This is the code I'm using to grab the data.
convenience init(fromDict dict: [String:Any]) {
let ef = dict["evolves-from"] as? [[String:Any]]
let ef1 = ef?[0]["evolved_species_id"]
self.init(
prevo: ef1 as? Int ?? 0,
)
}
It never gets to the self.init line because the console error is created at let ef1 = ef?[0]["evolved_species_id"]
Upvotes: 1
Views: 415
Reputation: 107211
You should always check whether the array contains anything before indexing it, it will avoid index out of bound exceptions. Since you are trying to get the 0th index element you can re-write your code using first
property of array:
init(fromDict dict: [String:Any])
{
let ef = dict["evolves-from"] as? [[String:Any]]
let ef1 = ef?.first?["evolved_species_id"]
self.init(prevo: ef1 as? Int ?? 0)
}
Use the first and last properties for safe access to the value of the array’s first and last elements. If the array is empty, these properties are nil.
Upvotes: 0
Reputation: 285180
You could check if the array exists and is not empty
convenience init(fromDict dict: [String:Any]) {
let ef1 : Int
if let ef = dict["evolves-from"] as? [[String:Any]], !ef.isEmpty {
ef1 = ef[0]["evolved_species_id"] as! Int
} else {
ef1 = 0
}
self.init(
prevo = ef1 // the colon syntax won't compile most likely.
)
}
or use a failable initializer
convenience init?(fromDict dict: [String:Any]) {
guard let ef = dict["evolves-from"] as? [[String:Any]], !ef.isEmpty else {
return nil
}
self.init(
prevo = ef[0]["evolved_species_id"] as! Int
)
}
Upvotes: 1
Reputation: 2455
You can do something like this
convenience init(fromDict dict: [String:Any]) {
let ef = dict["evolves-from"] as? [[String:Any]]
if !(ef.isEmpty){ /// OR if (ef.count > 0)
let ef1 = ef?[0]["evolved_species_id"]
self.init(
prevo: ef1 as? Int ?? 0,
)
}
}
Upvotes: 0
Reputation: 9226
You can use if let
construct for safely unwrap and check array elements is greater than zero using where
.
if let ef = dict["evolves-from"] as? [[String:Any]] where ef.count > 0 {
let ef1 = ef[0]["evolved_species_id"]
self.init(
prevo: ef1 as? Int ?? 0,
)
} else {
self.init(
prevo: 0
)
}
and if you're using Swift 3.0
if let ef = dict["evolves-from"] as? [[String:Any]], ef.count > 0 {
let ef1 = ef[0]["evolved_species_id"]
self.init(
prevo: ef1 as? Int ?? 0,
)
} else {
self.init(
prevo: 0
)
}
Upvotes: 0