P. 50: Optionals and casting

Inside insertSampleData() is this code:

let imageName = btDict["imageName"] as? String
let image = UIImage(named: imageName!)
let photoData = UIImagePNGRepresentation(image!)!
bowtie.photoData = NSData(data: photoData)

Why potentially crash the program on the third line? It’s not critical to obtain a value for bowtie.photoData, after all it’s an optional type, so why not write something like:

  if let imgName = btdict["imageName"] as? String,
     let image = UIImage(named: imgName),
     let data = UIImagePNGRepresentation(image)
  {
    bowtie.photoData = NSData(data: data)
  }
  else {
    bowtie.photoData = nil
  }

But, I wouldn’t even write it like that because in these lines in the book:

let imageName = btDict["imageName"] as? String
let image = UIImage(named: imageName!)

imageName is guaranteed not to be nil. I tested the case when a String type in a plist file has no entry, and you do not read in nil, rather you read in a blank String. So, I think those two lines could be written like:

let imageName = btDict["imageName"] as! String  //forced cast 
let image = UIImage(named: imageName)

I don’t really understand why the book does an optional cast on the first line, then on the very next line force unwraps the result of the optional cast. Incorporating the forced cast in my suggested code would look like this:

  let imgName = btdict["imageName"] as! String  //forced cast

  if let image = UIImage(named: imgName),
     let data = UIImagePNGRepresentation(image)
  {
    bowtie.photoData = NSData(data: data)
  }
  else {
    bowtie.photoData = nil
  }

Hi @7stud,

Generally the ‘swift’ way to handle this is with the optional using ‘?’ and enclosing that in an if of a guard depending on the situation, like so

let imageName = bDict["imageName"] //?? ""
if imageName != nil ,
    let image = UIImage(named: imageName!),
    let photoData = UIImagePNGRepresentation(image)
{
    bowtie.photoData = NSData(data: photoData)
}

it is worth considering some form of error checking in the code otherwise it can fail in places .

You can also use a default value using the nil coalescent operator ‘??’ for which you can check != “” instead of != nil

cheers,

Jayant

just a quick thought, you can also use the let to check for the nil and unwrap the optional for you as in

let imageName = bDict["imageName"] //?? ""
if let imageName = imageName,
    let image = UIImage(named: imageName),
    let photoData = UIImagePNGRepresentation(image)
{
    bowtie.photoData = NSData(data: photoData)
}

just a quick thought, you can also use the let to check for the nil and unwrap the optional for you as in

let imageName = bDict["imageName"] 
if let imageName = imageName,
    let image = UIImage(named: imageName),
    let photoData = UIImagePNGRepresentation(image)
{
    bowtie.photoData = NSData(data: photoData)
}

For some reason, you like those 4 lines of code over the 3 lines I proposed:

 if let imgName = btdict["imageName"] as? String,
     let image = UIImage(named: imgName),
     let data = UIImagePNGRepresentation(image)
  {

For what reason?

Yes. My question is why did the author write it like this:

let photoData = UIImagePNGRepresentation(image!)!

and then why did the technical editor not question that line? You can’t just write ! because you are tired of dealing with all the optionals.

Hi @7stud,
what you are missing in reading the code is that your code is using an else which will have one line that will never get full code coverage. So, the choice is entirely upto you, you can look at it as 3 lines of code or 4 lines of code with a better structure and code coverage.

Secondly, about your point on why the author used explicit optional unwraping, I cannot answer that as I was not involved with that tutorial. Secondly, I must admit that when Swift was released and I wrote my book on Swift, I am as guilty to using the ! as that was what the compiler offered and my Tech editor also did not question that - I believe that at the time that was how the official code form Apple looked, now we have a better understanding and code is evolving.

Your questions are quite valid but you can rephrase your questions to be a bit more polite.

Cheers,

Jayant

Can you explain in more detail what you mean by that statement? Thanks.

This topic was automatically closed after 166 days. New replies are no longer allowed.