0

I've been trying to research optionals in Swift all morning, and I know there are plenty of stack overflow posts, but none seem to clarify this properly.

For the following code, is this the most concise way of validating an optional?

let overlays:String = "overlays=" + self.preferences.string(forKey: "overlays")! == nil ? "" : self.preferences.string(forKey: "overlays")!

Note, I've seem it's possible to do

if( self.preferences.string(forKey:="overlays" != nil) {
    //do something
}

however this is less consice and readable in my opinion.

Edit: Turns out, that doesn't even handle nil properly, as I got

"Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value"

So can you provide the most concise working method to only include the string where it exists

Wayneio
  • 3,466
  • 7
  • 42
  • 73
  • That question clearly explains what are optionals, how to create them and how to use them safely. You should also check the Swift programming guide [Optionals chapter](https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html#ID330). – Dávid Pásztor Jun 08 '18 at 10:36
  • @DávidPásztor all those examples use if statements, as I mentioned, that's not very concise. I can't see that Swift makes you use an if statement for every occurrence of an optional, there must be a better way – Wayneio Jun 08 '18 at 10:37
  • @LeoDabus that accepted answer, using self.preferences.string(forKey: "overlays") ?? "" throws an error for me, about it still not being unwrapped so I'm not sure how that's the accepted answer on that page – Wayneio Jun 08 '18 at 10:40
  • @Wayneio that's not a simple if statement, that's called Optional binding which you'd know if you actually read through the answers for that question. You only have to safely unwrap an optional once using optional binding in the current scope. The ternary operator is not the way to handle Optionals safely in Swift. Use optional binding (use `guard let` if you want to avoid nested `if let`s). For some situations, especially when you only want to use an unwrapped optional a value once, you can simply use a default value. – Dávid Pásztor Jun 08 '18 at 10:41

2 Answers2

1

What you did is forced unwrapping. You must use either if let or guard let for optionaal handling.

if let a = self.preferences.string(forKey: "overlays"), let b = self.preferences.string(forKey: "overlays") {
    let overlays:String = "overlays=\(a)\(b)" +  
}
Manish Mahajan
  • 2,062
  • 1
  • 13
  • 19
0

Here let overlays:String = "overlays=" + self.preferences.string(forKey: "overlays")! == nil ? "" : self.preferences.string(forKey: "overlays")! will crash because + have more preference then ==. So it first do "overlays=" + self.preferences.string(forKey: "overlays")! then compare it with nil which always fails. And if self.preferences.string(forKey: "overlays")! returns nil, app will crash.

You can try :

var overlays:String = "overlays="
if let value = self.preferences.string(forKey: "overlays") {
    overlays = overlays + value
}
Chanchal Chauhan
  • 1,530
  • 13
  • 25