How to use optional "?" and "!" in swift? [duplicate] - ios

This question already has answers here:
What does "Fatal error: Unexpectedly found nil while unwrapping an Optional value" mean?
(16 answers)
Closed 6 years ago.
I am studying XCode7.3. The "?" and "!" always make me confused.
I have code like below.
The lines name : name, type : type and image : image displaying error message :
Value of optional type 'String?' not unwrapped, did you mean to use '!' or '?'?
#IBAction func unwindToHomeScreen( segue : UIStoryboardSegue ) {
if let addRestaurantController = segue.sourceViewController as? AddRestaurantController {
let name = addRestaurantController.name
let location = addRestaurantController.location
let type = addRestaurantController.type
let isVisited = addRestaurantController.isVisited
let image = addRestaurantController.imageView
restaurants.append( Restaurant(
name : name,
type : type,
location : location,
phoneNumber : "UNKNOW",
image : image,
isVisited : isVisited? ?? false
) )
print( addRestaurantController.imageView )
}
}
I modify code to name : name! or name : name?, it still doesn't work. How can I fix it?

I think this will solve your problem.
If addRestaurantController.location, addRestaurantController.name and addRestaurantController.type are optional.
#IBAction func unwindToHomeScreen( segue : UIStoryboardSegue ) {
if let addRestaurantController = segue.sourceViewController as? AddRestaurantController , name = addRestaurantController.name, location = addRestaurantController.location, type = addRestaurantController.type, isVisited = addRestaurantController.isVisited, image = addRestaurantController.imageView
{
restaurants.append( Restaurant(
name : name,
type : type,
location : location,
phoneNumber : "UNKNOW",
image : image,
isVisited : isVisited? ?? false
) )
}
}
You haven't specify that whether addRestaurantController.location, addRestaurantController.name and addRestaurantController.type are optional or not. And you randomly submitted your question without even analysing it properly.
Please give more value to other people's time. And ask meaningful questions. Read more about guidelines for a Stackoverflow question.

There might be few reasons, but first I'd suggest you to read about optionals (?) and explicitly unwrapped optionals (!) here https://itunes.apple.com/us/book/swift-programming-language/id881256329?mt=11
As far as the problem, it is most likely that optionality of variable name in Restaurant is defined differently comparing to local definition. While locally variable name is defined to be optional, e.g. let name: String?, Restaurant expects it to be non optional (probably it defined as let name: String (note no ? at the end)). That mean that you need to unwrap optional value to pass it to the Restaurant (please see the link above for ways of unwrapping, there are few depending on your use-case)
If you are switching to Swift 3, keep in mind that behavior of explicitly unwrapped optionals changed. For motivation and in depth description, please read this proposal https://github.com/apple/swift-evolution/blob/master/proposals/0054-abolish-iuo.md
But as it's been pointed out, Swift 3 can not be compiled in Xcode 7, you need to download beta of Xcode 8 for that

Related

What is difference between below 2 lines? [duplicate]

This question already has answers here:
What's the difference between "as?", "as!", and "as"?
(3 answers)
Closed 4 years ago.
I am trying to add code in cellForRowAt indexPath method like below
cell.itemNameLabel.text = nameArray[indexPath.row]
but it is showing error as Cannot assign value of type 'Any' to type 'String?'
so it can be solved by below 2 ways,
cell.fruitName.text = fruitArray[indexPath.row] as? String
or
cell.fruitName.text = (fruitArray[indexPath.row] as! String)
so, my question is what is the difference between 2 answers?
cell.fruitName.text = fruitArray[indexPath.row] as? String
Above return type is optional value. means it will be nil value return if array is not consist string value.
cell.fruitName.text = (fruitArray[indexPath.row] as! String)
Above return type is non-optional value. means it will be fire fatal error if array is not consist string value.
Below is the generic information for all optionals. Please find it.
When you are using ! and the fruitArray[indexPath.row] is nil it will trigger run time error but if use ? it will fail gracefully.
You can find more detail information in Apple document

How can i use the implicitly unwrapped optional in swift programming? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
iam very new to the swift programming.i have a wrote a basic program in swift. i confused about the unwrapped optional concept and in this program i have already declared celsius and fahrenheit as unwrapped optional by default. my question is
Why do we need to unwrap again as celsius.text!
can you please provide solution for this...Thank you
PROGRAM CODE
You have non-optional UITextField, but its property text is String? type, you must unwrap it like:
if let text = celsius.text {
print(text)
}
You need to include the defintion of celsius and fahrenheit.
I'm guessing that they are UITextField or UITextView objects.
Those two view types have properties text which are declared as optionals. So you have optional reference to a text field that contains a reference to an optional string.
So even though you declared celsius as celsius: UITextField!, the text property is also an optional, so you need to say
celsius.text? = ""
Note that declaring a variable as an implicitly unwrapped optional is dangerous, because any time you reference that variable, the compiler will try to unwrap it for you (It says "This is an Optional, but trust me, it will never be nil.) This is like having an elevator where you push the button and the door opens, whether the car is there or not, and you step through without looking. If the car is there, great. If not, you fall to your death. You better be sure the elevator will always be there!
Outlets are one case where it's common to use implicitly declared optionals, because the outlets should be hooked up in IB (Interface Builder). If an outlet is not hooked up, you want to know about it right away, so crashing is reasonable.
Think of the ! operator as the "crash if nil" operator, and avoid it until you really understand optionals. (With the exception of outlets, as discussed above.)
You can do it like that. Try to avoid using force unwrapping (! operator) on optionals.
func conversion() {
if ( celsius.text == "" ) {
if let fahrenheitText = fahrenheit.text, let fahrenheitValue = Double(fahrenheitText) {
let celsiusValue = fahrenheitValue - 32 * 5 / 9 //or whatever is the formula..
celsius.text = "\(celsiusValue)"
fahrenheit.text = ""
}
} else if ( fahrenheit.text == "" ) {
if let celsiusText = celsius.text, let celsiusValue = Double(celsiusText) {
let fahrenheitValue = 9 * celsiusValue / 5 + 32 //or whatever is the formula..
fahrenheit.text = "\(fahrenheitValue)"
celsius.text = ""
}
}
}

Why is Apple using this "if let" code? [duplicate]

This question already has answers here:
Why would I use if and let together, instead of just checking if the original variable is nil? (Swift)
(2 answers)
Closed 7 years ago.
Apple has this segment of code on one of their sample projects:
let existingImage = cache.objectForKey(documentIdentifier) as? UIImage
if let existingImage = existingImage where cleanThumbnailDocumentIDs.contains(documentIdentifier) {
return existingImage
}
why is apple using this if let? Isn't more logical to simply use
if cleanThumbnailDocumentIDs.contains(documentIdentifier) {
return existingImage!
}
???!!
If you use
let existingImage = cache.objectForKey(documentIdentifier) as? UIImage
if let existingImage = existingImage where cleanThumbnailDocumentIDs.contains(documentIdentifier) {
return existingImage
}
This will make sure that if existingImage == nil,it will not
execute return existingImage.
Besides,if let also unwrap existingImage from UIImage? to
UIImage
As Abhinav mentioned above, Apple introduced a new type called optional type with Swift.
What does optional mean?
Short and Sweet, "Optional types are types, which can contain a value of a particular data type or nil".
You can read more about optionals and their advantages here : swift-optionals-made-simple
Now whenever you want to make use of value present in an optional type, first you need to check what it contains i.e. does it contains a proper value or it contains nil. This process is called optional unwrapping.
Now there are two types of unwrapping,
Forced unwrapping : If you're sure that an optional will have an value all the time, you can then unwrap the value present in the optional type using "!" mark. This is force unwrapping.
The one more way is to use if let expression, this is safe unwrapping, here you'll check in your program that, if optional has a value you will do something with it; if it doesn't contain value you'd do something else. A simple example is this (You can test this in play ground:
func printUnwrappedOptional (opt:String?) {
if let optionalValue = opt { //here we try to assign opt value to optionalValue constant, if assignment is successful control enters if block
println(optionalValue) // This will be executed only if optionalValue had some value
}
else {
println("nil")
}}
var str1:String? = "Hello World" //Declaring an optional type of string and assigning it with a value
var str2:String? //Declaring an optional type of string and not assigning any value, it defaults to nil
printUnwrappedOptional(str1) // prints "Hello World"
printUnwrappedOptional(str2) // prints "nil"
Hope this clears your question, read through the link given above it'll be more clear to you. Hope this helps. :)
Edit: In Swift 2.0, Apple introduced "guard" statements, once you're good with optionals go through this link, guard statement in swift 2. This is another way to deal with optionals.
Using if let, makes sure that the object (existingImage) is not nil, and it unwraps it automatically, so you are sure inside the if that the condition is true, and the object is not nil, and you can use it without unwrap it !
With Swift, Apple has introduced a new concept/type - Optional Type. I think you better go through Apple Documentation.
Swift also introduces optional types, which handle the absence of a
value. Optionals say either “there is a value, and it equals x” or
“there isn’t a value at all”. Optionals are similar to using nil with
pointers in Objective-C, but they work for any type, not just classes.
Optionals are safer and more expressive than nil pointers in
Objective-C and are at the heart of many of Swift’s most powerful
features.
existingImage is an optional (as? UIImage) and therefor needs to be unwrapped before used, otherwise there would be a compiler error. What you are doing is called forced unwrapping via !. Your program will crash, if existingImage == nil and is therefor only viable, if you are absolutely sure, that existingImage can't be nil
if let and optional types is more help where is there is changes to get nil values to void crashes and unwanted code executions.
In Swift 2.0,
guard
will help us lot where our intention is clear not to execute the rest of the code if that particular condition is not satisfied

Cannot subscript a value of type [String: AnyObject]? with an index of type String

I know have many the same question but still cannot find the way to fix my error. Please see the image for more detail. I used Xcode 7 and swift 2.0
Edit: fcking the warning of Swift. finnaly (change?[NSKeyValueChangeNewKey]?.boolValue)! fixed the error
change is an optional. Either unwrap the optional
let isCaptureStillImage = change![NSKeyValueChangeNewKey]!.boolValue
or use optional bindings
if let changeNewKey = change?[NSKeyValueChangeNewKey] {
let isCaptureStillImage = changeNewKey.boolValue
...

Using ? (optionals) in Swift variables [duplicate]

This question already has answers here:
What is an optional value in Swift?
(15 answers)
Closed 8 years ago.
What exactly is the difference between a property definition in Swift of:
var window: UIWindow?
vs
var window: UIWindow
I've read it's basically an "optional" but I don't understand what it's for.
This is creating a class property called window right? so what's the need for the '?'
The ? identifier means that the variable is optional, meaning its value can be nil. If you have a value in your code, declaring it as non-optional allows the compiler to check at build time if it has a chance to become nil.
You can check whether it is nil in an if statement:
var optionalName: String? = "John Appleseed"
if optionalName {
// <-- here we know it's not nil, for sure!
}
Many methods that require a parameter to be non-nil will declare that they explicitly need a non-optional value. If you have an optional value, you can convert it into non-optional (for example, UIWindow? -> UIWindow) by unwrapping it. One of the primary methods for unwrapping is an if let statement:
var greeting = "Hello!"
// at this point in the code, optionalName could be nil
if let name = optionalName {
// here, we've unwrapped it into name, which is not optional and can't be nil
greeting = "Hello, \(name)"
}
See The Swift Programming Language, page 11 for a brief introduction, or page 46 for a more detailed description.
UIWindow? means that the value may be absent. It's either an UIWindow instance or nothing.

Resources