1

I'm relatively new to coding iOS and have not fully wrapped my head around optionals, downcasting, dictionaries and related fun concepts. I would greatly appreciate help on the following.

I am downloading data from a database and want to perform checks on the data to avoid a crash. In this particular case I want to check if an Object in a dictionary is an Int before performing a task to avoid a crash.

//The downloaded dictionary includes Int, Double and String data
var dictionaryDownloaded:[NSDictionary] = [NSDictionary]()

//Other code for downloading the data into the dictionary not shown.

for index in 1...dictionaryDownloaded.count {

    let jsonDictionary:NSDictionary = self.dictionaryDownloaded[index]

    if (jsonDictionary["SUNDAY OPEN TIME"] as? [Int]) != nil {
        self.currentlyConstructingRecommendation.sundayOpenTime = jsonDictionary["SUNDAY OPEN TIME"] as! Int!
    }

    self.recommendationsArray.append(currentlyConstructingRecommendation)
}

I followed the approach from this related question and answer. However, the problem is the "if (jsonDictionary["SUNDAY OPEN TIME"] as? [Int]) != nil" line is never true. I believe that is because the value is an optional object. I tried adjusting the dictionary to be of type [String:AnyObject] but that did not have an impact.

I'm stuck and any ideas you have would be appreciated. Please let me know if there is any more detail that is helpful. Thanks!

Community
  • 1
  • 1
Ben
  • 3,346
  • 6
  • 32
  • 51
  • What is the value of `jsonDictionary["SUNDAY OPEN TIME"]` ? – Midhun MP Jul 20 '16 at 17:58
  • 2
    Is it supposed to be an `Int` or an `[Int]`? They aren't the same thing and if your if statement was true your program would just crash on the next line because that cast would always fail. – dan Jul 20 '16 at 18:01
  • try with `jsonDictionary["SUNDAY OPEN TIME"] as? [Int]) is[NSNull()` to check whether is null or not. – triandicAnt Jul 20 '16 at 18:07
  • It was supposed to be an Int, not [Int]. Doh! – Ben Jul 20 '16 at 18:52

2 Answers2

3

With this code: jsonDictionary["SUNDAY OPEN TIME"] as? [Int], you are trying to convert the value to Array<Int>, not an Int.

And in your code, you have another flaw: index in 1...dictionaryDownloaded.count. This causes Index out of range exception, when index gets to dictionaryDownloaded.count.

So, a quick fix would be:

for index in 0..<dictionaryDownloaded.count {

    let jsonDictionary:NSDictionary = self.dictionaryDownloaded[index]

    if (jsonDictionary["SUNDAY OPEN TIME"] as? Int) != nil {
        self.currentlyConstructingRecommendation.sundayOpenTime = jsonDictionary["SUNDAY OPEN TIME"] as! Int!
    }

    self.recommendationsArray.append(currentlyConstructingRecommendation)
}

But I recommend you to do it in a more Swifty way.

for jsonDictionary in dictionaryDownloaded {

    if let sundayOpenTime = jsonDictionary["SUNDAY OPEN TIME"] as? Int {
        self.currentlyConstructingRecommendation.sundayOpenTime = sundayOpenTime
    }

    self.recommendationsArray.append(currentlyConstructingRecommendation)
}
OOPer
  • 47,149
  • 6
  • 107
  • 142
  • Ah yes, thank you so much. Worked like a charm. I feel a little silly for not thinking about the [Int] array part now! Thanks for the guidance to get Swifty also! – Ben Jul 20 '16 at 18:45
1

I think you've confused Int (which is an integer) with [Int] (which is an array of integers). Furthermore, this section of your code is redundant:

if (jsonDictionary["SUNDAY OPEN TIME"] as? [Int]) != nil {
    self.currentlyConstructingRecommendation.sundayOpenTime = jsonDictionary["SUNDAY OPEN TIME"] as! Int!
}

You use the excellent as? operator to perform a conditional cast, but then you discard the result and use the dangerous as! on the next line. You can use an if let to make this safer and clearer:

if let sundayOpenTime = jsonDictionary["SUNDAY OPEN TIME] as? Int {
    self.currentlyConstructingRecommendation.sundayOpenTime = sundayOpenTime
}

This casts the type to Int, and if that result is not nil, unwraps it and sets sundayOpenTime to it. We then use this new sundayOpenTime constant of type Int in the next line. If, however, the result of the cast is nil, the entire if statement fails and we move on safely.

andyvn22
  • 14,696
  • 1
  • 52
  • 74
  • Ah yes, thank you so much. Works like a charm. I feel a little silly for not thinking about the [Int] array part now! – Ben Jul 20 '16 at 18:46