Understanding ? and ! in swift - Specific case - ios

I am begining with swift and iOS and I have crashed against a doubt. Let see, having this particular source code:
if object?.stringValue != nil {
// send it to server
session.stopRunning()
sendQRCodeToApiServer(stringValueObtained: (object?.stringValue)!)
}
I understand that in if object?.stringValue != nil the ? character means that object var could be nil, so it is an optional. But in the internal line:
sendQRCodeToApiServer(stringValueObtained: (object?.stringValue)!)
The interpreter throws an error if I don't unwrap the object?.stringValue in () and with a exclamation mark (!), that (if I had understood perfect) means that you are sure that the result have a value and it has the type required, I mean, the object.stringValue has a value and IT IS a string.
Well, I understand this perfect, but the compiler says that ? and ! are required, first says that maybe has a value and second that is sure that has a value, ........
I see this syntax incongruent and confusing, can anyone explain me?
Thanks a lot for your time

Optionality / force unwrapping / optional chaining can be very confusing.
As a rule of thumb if you are finding that you have to force unwrap variables 'unexpectedly' then it is absolutely worth revisiting the code to deliberately unwrap variables you wish to access.
Some might say "Every time you use an ! , a baby unicorn dies (horribly)"
In your first line of code, object is an optional
if object?.stringValue != nil {
unless you specifically unwrap object you have to use the ? notation whenever you access it or it's members. Thats why when you access it again later inside the method call to sendQRCodeToApiServer, you have to unwrap it again.
When you unwrap an optional, the name you give to the unwrapped version of the variable works just like any other variable in that scope. Also when you unwrap an optional bear in mind that you are actively reducing the number of ? and ! that appear in your code so you are really making it much more readable and understandable for yourself in 6 months time or the next developer that sees your code (Hey and the unicorns love you).
Let's unwrap specifically the only variable you wish to use (if you had many lines of code that access object members then we could unwrap object - but let's stick with your code example)
if let stringValueObtained = object?.stringValue {
// send it to server
session.stopRunning()
sendQRCodeToApiServer(stringValueObtained: stringValueObtained)
}
Note:
Outside of the scope of the if statement stringValueObtained does not exist
I specifically have named the unwrapped variable for it's intended use

The syntax force-unwraps an optional chained expression object?.stringValue. As you can't write object?.stringValue! because the result of stringValue is not an optional you have add the parentheses (object?.stringValue)!
Unfortunately the compiler suggests that syntax although it's practically exactly the same as object!.stringValue which is perfectly fine in your case as object is definitely not nil after the check.

sendQRCodeToApiServer(stringValueObtained: (object?.stringValue)!)
In this line the compiler prompts you to unwrap because the function "stringValueObtained" needs a non-nill value as an argument. If you change the parameter of the function as optional it won't prompt you to unwrap.
Hope this helps you.

First, let inspect this:
if object?.stringValue != nil {
If object is nil or stringValue is nil, the condition will be false. That's objects?.whatEver will return nil if object is nil, and object?.stringValue will return nil if stringValue is nil.
sendQRCodeToApiServer(stringValueObtained: (object?.stringValue)!)
sendQRCodeToApiServer require a String, but object?.stringValue return a String? so you need to unwrap. Because of the if condition, so it's safe to unwrap here. Either by object!.stringValue (unwrap object) or (object?.stringValue)! - unwrap the returned value.
The better option is unwrap in if condition:
if let stringVal = object?.stringValue {
// send it to server
session.stopRunning()
sendQRCodeToApiServer(stringValueObtained: stringVal)
}

use it with optional binding with 'if let'
if let stringVal = object?.stringValue {
// send it to server
session.stopRunning()
sendQRCodeToApiServer(stringValueObtained: stringVal)
}
Always when you use optional chaining , then use if let binding because optional chaining always return an optional value ,whether the declaration of that value container means object is non optional.

if object?.stringValue != nil is only checked not nil.
So, you need to unwrapping value.
Recommand to use this code.
if let stringValue = object?.stringValue {
session.stopRunning()
sendQRCodeToApiServer(stringValueObtained: stringValue)
}

Related

Check if a String Contains Another String in Swift [duplicate]

I'm learning Swift for iOS 8 / OSX 10.10 by following this tutorial, and the term "unwrapped value" is used several times, as in this paragraph (under Objects and Class):
When working with optional values, you can write ? before operations
like methods, properties, and subscripting. If the value before the ?
is nil, everything after the ? is ignored and the value of the whole
expression is nil. Otherwise, the optional value is unwrapped, and
everything after the ? acts on the unwrapped value. In both cases, the
value of the whole expression is an optional value.
let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare?.sideLength
I don't get it, and searched on the web without luck.
What does this means?
Edit
From Cezary's answer, there's a slight difference between the output of the original code and the final solution (tested on playground) :
Original code
Cezary's solution
The superclass' properties are shown in the output in the second case, while there's an empty object in the first case.
Isn't the result supposed to be identical in both case?
Related Q&A : What is an optional value in Swift?
First, you have to understand what an Optional type is. An optional type basically means that the variable can be nil.
Example:
var canBeNil : Int? = 4
canBeNil = nil
The question mark indicates the fact that canBeNil can be nil.
This would not work:
var cantBeNil : Int = 4
cantBeNil = nil // can't do this
To get the value from your variable if it is optional, you have to unwrap it. This just means putting an exclamation point at the end.
var canBeNil : Int? = 4
println(canBeNil!)
Your code should look like this:
let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare!.sideLength
A sidenote:
You can also declare optionals to automatically unwrap by using an exclamation mark instead of a question mark.
Example:
var canBeNil : Int! = 4
print(canBeNil) // no unwrapping needed
So an alternative way to fix your code is:
let optionalSquare: Square! = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare.sideLength
EDIT:
The difference that you're seeing is exactly the symptom of the fact that the optional value is wrapped. There is another layer on top of it. The unwrapped version just shows the straight object because it is, well, unwrapped.
A quick playground comparison:
In the first and second cases, the object is not being automatically unwrapped, so you see two "layers" ({{...}}), whereas in the third case, you see only one layer ({...}) because the object is being automatically unwrapped.
The difference between the first case and the second two cases is that the second two cases will give you a runtime error if optionalSquare is set to nil. Using the syntax in the first case, you can do something like this:
if let sideLength = optionalSquare?.sideLength {
println("sideLength is not nil")
} else {
println("sidelength is nil")
}
The existing correct answer is great, but I found that for me to understand this fully, I needed a good analogy, since this is a very abstract and weird concept.
So, let me help those fellow "right-brained" (visual thinking) developers out by giving a different perspective in addition to the correct answer. Here is a good analogy that helped me a lot.
Birthday Present Wrapping Analogy
Think of optionals as being like birthday presents that come in stiff, hard, colored wrapping.
You don't know if there's anything inside the wrapping until you unwrap the present — maybe there is nothing at all inside! If there is something inside, it could be yet another present, which is also wrapped, and which also might contain nothing. You might even unwrap 100 nested presents to finally discover there was nothing but wrapping.
If the value of the optional is not nil, now you have revealed a box containing something. But, especially if the value is not explicitly typed and is a variable and not a predefined constant, then you may still need to open the box before you can know anything specific about what's in the box, like what type it is, or what the actual value is.
What's In The Box?! Analogy
Even after you unwrap the variable, you are still like Brad Pitt in the last scene in SE7EN (warning: spoilers and very R-rated foul language and violence), because even after you have unwrapped the present, you are in the following situation: you now have nil, or a box containing something (but you don't know what).
You might know the type of the something. For example, if you declared the variable as being type, [Int:Any?], then you'd know you had a (potentially empty) Dictionary with integer subscripts that yield wrapped contents of any old type.
That is why dealing with collection types (Dictionaries and Arrays) in Swift can get kind of hairy.
Case in point:
typealias presentType = [Int:Any?]
func wrap(i:Int, gift:Any?) -> presentType? {
if(i != 0) {
let box : presentType = [i:wrap(i-1,gift:gift)]
return box
}
else {
let box = [i:gift]
return box
}
}
func getGift() -> String? {
return "foobar"
}
let f00 = wrap(10,gift:getGift())
//Now we have to unwrap f00, unwrap its entry, then force cast it into the type we hope it is, and then repeat this in nested fashion until we get to the final value.
var b4r = (((((((((((f00![10]! as! [Int:Any?])[9]! as! [Int:Any?])[8]! as! [Int:Any?])[7]! as! [Int:Any?])[6]! as! [Int:Any?])[5]! as! [Int:Any?])[4]! as! [Int:Any?])[3]! as! [Int:Any?])[2]! as! [Int:Any?])[1]! as! [Int:Any?])[0])
//Now we have to DOUBLE UNWRAP the final value (because, remember, getGift returns an optional) AND force cast it to the type we hope it is
let asdf : String = b4r!! as! String
print(asdf)
Swift places a high premium on type safety. The entire Swift language was designed with safety in mind. It is one of the hallmarks of Swift and one that you should welcome with open arms. It will assist in the development of clean, readable code and help keep your application from crashing.
All optionals in Swift are demarcated with the ? symbol. By setting the ? after the name of the type in which you are declaring as optional you are essentially casting this not as the type in which is before the ?, but instead as the optional type.
Note: A variable or type Int is not the same as Int?. They are two different types that can not be operated on each other.
Using Optional
var myString: String?
myString = "foobar"
This does not mean that you are working with a type of String. This means that you are working with a type of String? (String Optional, or Optional String). In fact, whenever you attempt to
print(myString)
at runtime, the debug console will print Optional("foobar"). The "Optional()" part indicates that this variable may or may not have a value at runtime, but just so happens to currently be containing the string "foobar". This "Optional()" indication will remain unless you do what is called "unwrapping" the optional value.
Unwrapping an optional means that you are now casting that type as non-optional. This will generate a new type and assign the value that resided within that optional to the new non-optional type. This way you can perform operations on that variable as it has been guaranteed by the compiler to have a solid value.
Conditionally Unwrapping will check if the value in the optional is nil or not. If it is not nil, there will be a newly created constant variable that will be assigned the value and unwrapped into the non-optional constant. And from there you may safely use the non-optional in the if block.
Note: You can give your conditionally unwrapped constant the same name as the optional variable you are unwrapping.
if let myString = myString {
print(myString)
// will print "foobar"
}
Conditionally unwrapping optionals is the cleanest way to access an optional's value because if it contains a nil value then everything within the if let block will not execute. Of course, like any if statement, you may include an else block
if let myString = myString {
print(myString)
// will print "foobar"
}
else {
print("No value")
}
Forcibly Unwrapping is done by employing what is known as the ! ("bang") operator. This is less safe but still allows your code to compile. However whenever you use the bang operator you must be 1000% certain that your variable does in fact contain a solid value before forcibly unwrapping.
var myString: String?
myString = "foobar"
print(myString!)
This above is entirely valid Swift code. It prints out the value of myString that was set as "foobar". The user would see foobar printed in the console and that's about it. But let's assume the value was never set:
var myString: String?
print(myString!)
Now we have a different situation on our hands. Unlike Objective-C, whenever an attempt is made to forcibly unwrap an optional, and the optional has not been set and is nil, when you try to unwrap the optional to see what's inside your application will crash.
Unwrapping w/ Type Casting. As we said earlier that while you are unwrapping the optional you are actually casting to a non-optional type, you can also cast the non-optional to a different type. For example:
var something: Any?
Somewhere in our code the variable something will get set with some value. Maybe we are using generics or maybe there is some other logic that is going on that will cause this to change. So later in our code we want to use something but still be able to treat it differently if it is a different type. In this case you will want to use the as keyword to determine this:
Note: The as operator is how you type cast in Swift.
// Conditionally
if let thing = something as? Int {
print(thing) // 0
}
// Optionally
let thing = something as? Int
print(thing) // Optional(0)
// Forcibly
let thing = something as! Int
print(thing) // 0, if no exception is raised
Notice the difference between the two as keywords. Like before when we forcibly unwrapped an optional we used the ! bang operator to do so. Here you will do the same thing but instead of casting as just a non-optional you are casting it also as Int. And it must be able to be downcast as Int, otherwise, like using the bang operator when the value is nil your application will crash.
And in order to use these variables at all in some sort or mathematical operation they must be unwrapped in order to do so.
For instance, in Swift only valid number data types of the same kind may be operated on each other. When you cast a type with the as! you are forcing the downcast of that variable as though you are certain it is of that type, therefore safe to operate on and not crash your application. This is ok as long as the variable indeed is of the type you are casting it to, otherwise you'll have a mess on your hands.
Nonetheless casting with as! will allow your code to compile. By casting with an as? is a different story. In fact, as? declares your Int as a completely different data type all together.
Now it is Optional(0)
And if you ever tried to do your homework writing something like
1 + Optional(1) = 2
Your math teacher would have likely given you an "F". Same with Swift. Except Swift would rather not compile at all rather than give you a grade. Because at the end of the day the optional may in fact be nil.
Safety First Kids.
'?' means optional chaining expression
the'!'means is force-value
There are 7 ways to unwrapping optional value in Swift.
Optional Binding - Safe
Optional Chaining - Safe
Optional Pattern - Safe
Nil Coalescing - Safe
Guard Statement - Safe
Force Unwrapping - Unsafe
Implicit Unwrapping - Unsafe

Why does Swift 2 favor forced unwrap over optionals?

I no longer see Xcode complaining that certain things need optionals (the "?"). Now it is always forced unwrapped (the bang "!"). Is there any reason to use optionals anymore when we now have forced unwrap?
I don't really know what you mean when you write that you no longer see Xcode complaining that "certain things need optionals. Now it is always forced unwrapped". These two sentences contradict eachother:
You may have non-optional variables as much as you wish, but optional can really nice once you get to know all the benefits of using them.
If you have a property that is not an optional, then it won't need, by definition, any unwrapping.
Perhaps what you ment was that Xcode seemingly complains less often when you actually do force unwrap optionals, or, as a bad habit of Xcode, prompts you to force unwrap things to avoid compile time errors. This is generally because Xcode cannot know at compile time that you just wrote code that will break your app at runtime.
Xcode may seemingly at times have only one single purpose with its "smart hints": namely to absolve compile time errors. If you try to assign the value of a String? type (optional String) to String type, Xcode will prompt you with a compiler error and ask if you ment to add the forced unwrapping operator !. Smart Xcode, you say? Meh, Xcode is good for many things, but deciding how you unwrap your optionals is, not yet anyway, one of them. So even with Xcode prompting you for all kinds of things: if you can use optional chaining, do.
There might be exception, of course. For the controller part of the MVC design pardigm, you usually use the as! operator to do "forced conversion" (casting), with Xcode sometimes telling you to explicitly to use as! instead of as, e.g. "Did you mean as! ... ?". In these situations, Xcode can sometimes actually know what its doing and infer that you are trying to cast, as an example, a custom UIViewController class instance to type UIViewController, i.e., to it's parent class. I'd say that this is perhaps one of the few times I use the "forced" marker ! without go-arounds; forced conversion to types I know with 100% certainty to be castable.
The as! operator
But let's leave the subject of type conversion/casting and move on to optional types, wrapping, and optional chaining, in general.
Generally, you should avoid force unwrapping unless you explicitly knows that the entity you unwrap will be non-nil. For general class properties, variables and so on, given that you state this question the way you do, I'll give your the following advice:
If you can use conditional unwrapping (if-let, guard-let, nil
coalescing operator ??), then don't use forced unwrapping (!).
Below follows an example of the dangers of forced unwrapping. You can treat the first if clause (if arc4random...) as any smaller or larger segment of some program you've written with imperative programming techniques: we don't really know in detail just how 'name' will turn out until runtime, and our compiler can't really help us out here.
var name : String?
/* 'name' might or might not have a non-nil
value after this if clause */
if arc4random_uniform(2) < 1 {
name = "David"
}
/* Well-defined: us an if-let clause to try to unwrap your optional */
if let a = name {
print("Hello world "+a)
/* Very well-behaved, we did a safe
unwrap of 'name', if not nil, to constant a */
print("Hello world "+name!)
/* Well... In this scope, we know that name is,
for a fact, not nil. So here, a force unwrap
is ok (but not needed). */
}
let reallyGiveMeThatNameDammit = name!
/* NOT well-defined. We won't spot this at compile time, but
if 'name' is nil at runtime, we'll encounte a runtime error */
I recommend you to read up on optional chaining, a key subject in Swift.
Swift Language Guide - Optional Chaining
do you mean that cocoa stuff? do you mean implicitly unwrapped?
protocol AnyObject { ... }
The protocol to which all classes implicitly conform.
When used as a concrete type, all known #objc methods and properties are available, as implicitly-unwrapped-optional methods and properties respectively, on each instance of AnyObject. For example:
class C {
#objc func getCValue() -> Int { return 42 }
}
// If x has a method #objc getValue()->Int, call it and
// return the result. Otherwise, return nil.
func getCValue1(x: AnyObject) -> Int? {
if let f: ()->Int = x.getCValue { // <===
return f()
}
return nil
}
// A more idiomatic implementation using "optional chaining"
func getCValue2(x: AnyObject) -> Int? {
return x.getCValue?() // <===
}
// An implementation that assumes the required method is present
func getCValue3(x: AnyObject) -> Int { // <===
return x.getCValue() // x.getCValue is implicitly unwrapped. // <===
}

Swift Optionals which to choose

In swift, when making a variable optional, when would you want to use ! over ? or vice versa. I understand the difference between them, but are there some scenarios where one would not be appropriate and the other would?
Only use an implicitly unwrapped optional (!) if you are absolutely sure that its value will be set to something other than nil when you go to use it. If you try to access the value of an implicitly unwrapped optional when it's set to nil, it will trigger a runtime crash.
For example, this will compile:
var a: Int! = nil
var b = a + 1
But, it will crash when you try to call a + 1.
However, if you use a standard optional (?), it will tell you at compile time that you made an error and catch your potential crash before it happens:
var a: Int? = nil
var b = a + 1 // Compile error here
You can, of course, check for nil in both cases but, if you need to check for nil anyway, why not just use the safer standard optional and catch any checks you may have missed at compile time instead of crashing at some unknown point in the future.
Implicitly unwrapped optionals (those declared with !) can be used when you know the value will never be nil (because you test for that case and handle it) but need to have an optional for some reason. I use these to capture the results of Cocoa methods that return optionals, check them immediately and handle the error case, and then can use them without an unwrapping operator.
let myData: NSData! = NSDate(contentsOfFile: filePath)
if myData == nil {
// handle error reporting, etc
}
Regular optionals (declared with ?) should basically be used everywhere else you truly need an optional value -- you lose the safety that optionals provide otherwise.
let myInt: Int? = myString.toInt()
Of course, with the addition of the null coalescing operator (??), there are lots of times when you simply don't need an optional at all.
let myInt: Int = myString.toInt() ?? 0

What is an "unwrapped value" in Swift?

I'm learning Swift for iOS 8 / OSX 10.10 by following this tutorial, and the term "unwrapped value" is used several times, as in this paragraph (under Objects and Class):
When working with optional values, you can write ? before operations
like methods, properties, and subscripting. If the value before the ?
is nil, everything after the ? is ignored and the value of the whole
expression is nil. Otherwise, the optional value is unwrapped, and
everything after the ? acts on the unwrapped value. In both cases, the
value of the whole expression is an optional value.
let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare?.sideLength
I don't get it, and searched on the web without luck.
What does this means?
Edit
From Cezary's answer, there's a slight difference between the output of the original code and the final solution (tested on playground) :
Original code
Cezary's solution
The superclass' properties are shown in the output in the second case, while there's an empty object in the first case.
Isn't the result supposed to be identical in both case?
Related Q&A : What is an optional value in Swift?
First, you have to understand what an Optional type is. An optional type basically means that the variable can be nil.
Example:
var canBeNil : Int? = 4
canBeNil = nil
The question mark indicates the fact that canBeNil can be nil.
This would not work:
var cantBeNil : Int = 4
cantBeNil = nil // can't do this
To get the value from your variable if it is optional, you have to unwrap it. This just means putting an exclamation point at the end.
var canBeNil : Int? = 4
println(canBeNil!)
Your code should look like this:
let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare!.sideLength
A sidenote:
You can also declare optionals to automatically unwrap by using an exclamation mark instead of a question mark.
Example:
var canBeNil : Int! = 4
print(canBeNil) // no unwrapping needed
So an alternative way to fix your code is:
let optionalSquare: Square! = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare.sideLength
EDIT:
The difference that you're seeing is exactly the symptom of the fact that the optional value is wrapped. There is another layer on top of it. The unwrapped version just shows the straight object because it is, well, unwrapped.
A quick playground comparison:
In the first and second cases, the object is not being automatically unwrapped, so you see two "layers" ({{...}}), whereas in the third case, you see only one layer ({...}) because the object is being automatically unwrapped.
The difference between the first case and the second two cases is that the second two cases will give you a runtime error if optionalSquare is set to nil. Using the syntax in the first case, you can do something like this:
if let sideLength = optionalSquare?.sideLength {
println("sideLength is not nil")
} else {
println("sidelength is nil")
}
The existing correct answer is great, but I found that for me to understand this fully, I needed a good analogy, since this is a very abstract and weird concept.
So, let me help those fellow "right-brained" (visual thinking) developers out by giving a different perspective in addition to the correct answer. Here is a good analogy that helped me a lot.
Birthday Present Wrapping Analogy
Think of optionals as being like birthday presents that come in stiff, hard, colored wrapping.
You don't know if there's anything inside the wrapping until you unwrap the present — maybe there is nothing at all inside! If there is something inside, it could be yet another present, which is also wrapped, and which also might contain nothing. You might even unwrap 100 nested presents to finally discover there was nothing but wrapping.
If the value of the optional is not nil, now you have revealed a box containing something. But, especially if the value is not explicitly typed and is a variable and not a predefined constant, then you may still need to open the box before you can know anything specific about what's in the box, like what type it is, or what the actual value is.
What's In The Box?! Analogy
Even after you unwrap the variable, you are still like Brad Pitt in the last scene in SE7EN (warning: spoilers and very R-rated foul language and violence), because even after you have unwrapped the present, you are in the following situation: you now have nil, or a box containing something (but you don't know what).
You might know the type of the something. For example, if you declared the variable as being type, [Int:Any?], then you'd know you had a (potentially empty) Dictionary with integer subscripts that yield wrapped contents of any old type.
That is why dealing with collection types (Dictionaries and Arrays) in Swift can get kind of hairy.
Case in point:
typealias presentType = [Int:Any?]
func wrap(i:Int, gift:Any?) -> presentType? {
if(i != 0) {
let box : presentType = [i:wrap(i-1,gift:gift)]
return box
}
else {
let box = [i:gift]
return box
}
}
func getGift() -> String? {
return "foobar"
}
let f00 = wrap(10,gift:getGift())
//Now we have to unwrap f00, unwrap its entry, then force cast it into the type we hope it is, and then repeat this in nested fashion until we get to the final value.
var b4r = (((((((((((f00![10]! as! [Int:Any?])[9]! as! [Int:Any?])[8]! as! [Int:Any?])[7]! as! [Int:Any?])[6]! as! [Int:Any?])[5]! as! [Int:Any?])[4]! as! [Int:Any?])[3]! as! [Int:Any?])[2]! as! [Int:Any?])[1]! as! [Int:Any?])[0])
//Now we have to DOUBLE UNWRAP the final value (because, remember, getGift returns an optional) AND force cast it to the type we hope it is
let asdf : String = b4r!! as! String
print(asdf)
Swift places a high premium on type safety. The entire Swift language was designed with safety in mind. It is one of the hallmarks of Swift and one that you should welcome with open arms. It will assist in the development of clean, readable code and help keep your application from crashing.
All optionals in Swift are demarcated with the ? symbol. By setting the ? after the name of the type in which you are declaring as optional you are essentially casting this not as the type in which is before the ?, but instead as the optional type.
Note: A variable or type Int is not the same as Int?. They are two different types that can not be operated on each other.
Using Optional
var myString: String?
myString = "foobar"
This does not mean that you are working with a type of String. This means that you are working with a type of String? (String Optional, or Optional String). In fact, whenever you attempt to
print(myString)
at runtime, the debug console will print Optional("foobar"). The "Optional()" part indicates that this variable may or may not have a value at runtime, but just so happens to currently be containing the string "foobar". This "Optional()" indication will remain unless you do what is called "unwrapping" the optional value.
Unwrapping an optional means that you are now casting that type as non-optional. This will generate a new type and assign the value that resided within that optional to the new non-optional type. This way you can perform operations on that variable as it has been guaranteed by the compiler to have a solid value.
Conditionally Unwrapping will check if the value in the optional is nil or not. If it is not nil, there will be a newly created constant variable that will be assigned the value and unwrapped into the non-optional constant. And from there you may safely use the non-optional in the if block.
Note: You can give your conditionally unwrapped constant the same name as the optional variable you are unwrapping.
if let myString = myString {
print(myString)
// will print "foobar"
}
Conditionally unwrapping optionals is the cleanest way to access an optional's value because if it contains a nil value then everything within the if let block will not execute. Of course, like any if statement, you may include an else block
if let myString = myString {
print(myString)
// will print "foobar"
}
else {
print("No value")
}
Forcibly Unwrapping is done by employing what is known as the ! ("bang") operator. This is less safe but still allows your code to compile. However whenever you use the bang operator you must be 1000% certain that your variable does in fact contain a solid value before forcibly unwrapping.
var myString: String?
myString = "foobar"
print(myString!)
This above is entirely valid Swift code. It prints out the value of myString that was set as "foobar". The user would see foobar printed in the console and that's about it. But let's assume the value was never set:
var myString: String?
print(myString!)
Now we have a different situation on our hands. Unlike Objective-C, whenever an attempt is made to forcibly unwrap an optional, and the optional has not been set and is nil, when you try to unwrap the optional to see what's inside your application will crash.
Unwrapping w/ Type Casting. As we said earlier that while you are unwrapping the optional you are actually casting to a non-optional type, you can also cast the non-optional to a different type. For example:
var something: Any?
Somewhere in our code the variable something will get set with some value. Maybe we are using generics or maybe there is some other logic that is going on that will cause this to change. So later in our code we want to use something but still be able to treat it differently if it is a different type. In this case you will want to use the as keyword to determine this:
Note: The as operator is how you type cast in Swift.
// Conditionally
if let thing = something as? Int {
print(thing) // 0
}
// Optionally
let thing = something as? Int
print(thing) // Optional(0)
// Forcibly
let thing = something as! Int
print(thing) // 0, if no exception is raised
Notice the difference between the two as keywords. Like before when we forcibly unwrapped an optional we used the ! bang operator to do so. Here you will do the same thing but instead of casting as just a non-optional you are casting it also as Int. And it must be able to be downcast as Int, otherwise, like using the bang operator when the value is nil your application will crash.
And in order to use these variables at all in some sort or mathematical operation they must be unwrapped in order to do so.
For instance, in Swift only valid number data types of the same kind may be operated on each other. When you cast a type with the as! you are forcing the downcast of that variable as though you are certain it is of that type, therefore safe to operate on and not crash your application. This is ok as long as the variable indeed is of the type you are casting it to, otherwise you'll have a mess on your hands.
Nonetheless casting with as! will allow your code to compile. By casting with an as? is a different story. In fact, as? declares your Int as a completely different data type all together.
Now it is Optional(0)
And if you ever tried to do your homework writing something like
1 + Optional(1) = 2
Your math teacher would have likely given you an "F". Same with Swift. Except Swift would rather not compile at all rather than give you a grade. Because at the end of the day the optional may in fact be nil.
Safety First Kids.
'?' means optional chaining expression
the'!'means is force-value
There are 7 ways to unwrapping optional value in Swift.
Optional Binding - Safe
Optional Chaining - Safe
Optional Pattern - Safe
Nil Coalescing - Safe
Guard Statement - Safe
Force Unwrapping - Unsafe
Implicit Unwrapping - Unsafe

In Apple Swift, in what case(s) would I not want an implicitly unwrapped optional?

I believe I understand why optionals are handy (my best thought for use is to be able to return a nil Boolean value), but in what case would I want to declare a wrapped optional using ? rather than ! for an implicitly unwrapped optional.
It just seems unnecessary to declare it with ? and then have to type ! all over the place rather than just using ! once.
I don't want to disregard the ? as useless, but I just can't find a use for it... Any ideas?
If you try to access the content of an implicitly unwrapped optional and there's nothing there, your app will crash.
If you use the patterns for checking the content of an optional — like optional binding and optional chaining - you can control how your app should fail gracefully in unforeseen situations. And it doesn't make your code all that more complicated.
Not crashing seems like a good reason to me.
First lets talk about what the point of ? is in swift. You might create a var that looks like this.
var number : Int?
You are basically saying that there is a possibility that this variable could be nil. If there is ever a possibility that an object could be nil, then you would not want to do something like this.
var secondNumber = number! + 5
Basically in that statement you are saying, there is a possibility this variable could be nil but, I will totally ignore that fact and pretend there is no way that it could be nil.
Instead you will want to check if that variable exists first and then set it like so
var number : Int?
var number2 : Int?
number = 10
if let unwrappedNumber = number {
number2 = unwrappedNumber + 5
}
Hope this helps!
Implicitly unwrapped optionals introduce a possible failure similar to dereferencing null pointers. You should only use them when you can be sure that no one will accidentally pass nil, or when you're comfortable telling clients of the interface that the function will crash if they violate the interface requirements.
Another way to avoid using ? Repeatedly is the if let statement:
func foo(bar:Int?) -> Int? {
if let x = bar {
if Int.max / x >= x {
return x * x
}
}
return nil
}
x here is an Int rather than Int?.

Resources