Why Is Optional("Text") - Swift

text field receiving optional('value) instead of value

When retrieving the value, use ! after the value. The downcast should force unwrap any optionals. Anything set as? can be force unwrapped by using !.
For example,

let intString = 7 as? String

print(intString!)

This should print "7", rather than Optional("7")

Firebase returning Optional() with Swift 3.0

You just need to unwrap the value that you recieve:-

FIRDatabase.database().reference().child("Ring1Fighting").observe(.value) { (snap: FIRDataSnapshot) in

print((snap.value as! String))

}

Why do I have to use the optional ? in this code?

Think about what you would get if you try to access the response before you assign it:

let cheeseQuestion = SurveyQuestion(text: "Do you like cheese?")
print(cheeseQuestion.response) // what would this print?

It's gotta be some kind of a value, right? The value that makes the most sense is something that represents "this question has no response yet", which is what nil is - the absence of a value. Making response optional has the side effect of making its default value nil.

If you don't want it to be optional, that's fine too, but you have to give it a default value (not nil, only optionals can have nil as a value!)

class SurveyQuestion {
var text: String
var response: String = "some default response"
init(text: String) {
self.text = text
}
}

or you can initialise it in the initialiser:

init(text: String) {
self.text = text
self.response = "some default response"
}

or you can add a parameter to the initialiser and initialise it to that:

init(text: String, response: String) {
self.text = text
self.response = response
}

Essentially, if response is not optional, it needs to have some value that is not nil when its initialiser finishes running.

How to add an optional string extension?

In Swift 3.1 you can add an extension to optional values as well:

extension Optional where Wrapped == String {
var isBlank: Bool {
return self?.isBlank ?? true
}
}

Swift trouble with optionals

There are optionals on three levels:

  • The sender: AnyObject? parameter is an optional.
  • Sending arbitrary messages to AnyObject behaves similar to optional
    chaining and returns an implicitly unwrapped optional
    (compare The strange behaviour of Swift's AnyObject).
  • The var urlString: String? property is an optional.

To resolve the first two optionals, use optional binding/casting to the
concrete button class:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "segueToWebView") {
if let button = sender as? TestButton {
// The type of `button` is `TestButton`
// ...
}
}
}

Now

var destUrl: String
if button.urlString == nil {
destUrl = "http://www.google.com"
} else {
destUrl = button.urlString!
}

would compile, but that is better handled with the
nil-coalescing operator:

let destUrl = button.urlString ?? "http://www.google.com"

Note that there is no forced unwrapping ! operator anymore!

value of optional type 'string?' not unwrapped when checking if values are empty

As already noted, UITextFields property text is of type String? (aka Optional<String>), so you cannot directly apply methods or get properties of String.

Forced unwrapping (!) would be very risky, as that property may actually be nil.

In such cases, you have some options to treat the Optional value:

  • Use optional bindings, its representative is if let, but guard let or sometimes while let may be useful.
  • Use optional chaining, represented with ?.. Maybe you are using this somewhere else.
  • Giving default value using nil-coalescing operator ??.

With the latter two, I get this line:

if((userEmail?.isEmpty ?? true) || (userPassword?.isEmpty ?? true) || (userRepeatPassword?.isEmpty ?? true)) {

As you see, userEmails type is String?, so I have chosen optional chaining:

userEmail?.isEmpty

Which may return three kinds of values:

  • Optional.Some(true)
  • Optional.Some(false)
  • Optional.None (this is called nil)

(I omitted specifying <Bool>, for readability.)


It's still Optional, so I added ?? true to supply a default value for nil case.

userEmail?.isEmpty ?? true
  • lhs:Optional.Some(true) -> true (left hand side of ?? is not nil, use lhs value unwrapped)
  • lhs:Optional.Some(false) -> false (left hand side of ?? is not nil, use lhs value unwrapped)
  • lhs:Optional.None -> true (left hand side of ?? is nil, so right hand side value is used)

You know, when the text is nil, you should think it as empty, so supplying default value true for nil case is appropriate.

You need to write similar code for all three variables, and you get the line I have shown above.



Related Topics



Leave a reply



Submit