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

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 = ""
}
}
}

Related

Assign value with optional question mark

I'm currently learning Swift from basics. Now I'm on optionals and I'm trying to understand this case:
var text: String? = nil
text? = "some text"
What happens exactly if we assign value with question mark? I don't understand why the value of text is nil. Can you explain me what is the difference between assigning text = "some text" and text? = "some text"?
You're right to be surprised. text? = means "If text is nil don't perform the assignment."
You've stumbled across a highly obscure language feature. See https://ericasadun.com/2017/01/25/pretty-much-every-way-to-assign-optionals/
(As she rightly says, you can count on the fingers of zero hands the number of times you'll ever actually talk like this, because who would ever want to assign a value only just in case the lvalue is already non-nil?)
NOTE I prefer to look at this as a zero-length variant of optional chaining. It is extremely useful to be able to say e.g.
self.navigationController?.hidesBarsOnTap = true
meaning, if self.navigationController is nil, fuhgeddaboudit. Well, your use case is sort of a variant of that, with nothing after the question mark. Most people are unaware that if the last object in the chain is an Optional, the chain can end in a question mark. The expressions in f are all legal:
class C {
struct T {
var text : String?
}
var t : T?
func f() {
self.t?.text = "howdy"
self.t? = T()
self.t?.text? = "howdy"
}
}
But only the first one, self.t?.text =, is common to say in real life.

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

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

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

How to better understand optionals

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if (segue.identifier == "segueone")
{
let cellIndexPath = self.tableView!.indexPathForCell(sender as UITableViewCell)
if let unwrappedCellindexPath = cellIndexPath
{
var nextVC = (segue.destinationViewController as TableTwo)
nextVC.items = items[unwrappedCellindexPath.row]
}
}
}
With this piece of code, I have a few questions regarding the optionals. I recently read-through the apple developer web document as well as a few personal explanations of optionals but still have question.
Anyways,
in the line
let cellIndexPath = self.tableView!.indexPathForCell(sender as UITableViewCell)
Is this statement only considered to be an optional because a user may not select one of the cells in my table? And with that, since I know that as long as a user wants to continue through the app, they must select a cell, I can place the exclamation point in to notify the compiler that this cell does in deed have a value(index path)?
Why does the exclamation point go after "self.tableview" and not after "sender as UITableView) in parentheses?
If my assuming is correct, I am able to use the if let syntax because I have an optional in the previous line of code?
let cellIndexPath = self.tableView!.indexPathForCell(sender as UITableViewCell)
Uses an exclamation point after tableView, because self.tableView! may not have been set (it may be nil).
It is an optional because it has the option to have a value, and it also has the option to be nil. Variables that are not optionals cannot be nil, they have to have a value.
The exclamation point goes after tableView because that is the optional which could be nil. If it went after .indexPathForCell(sender as UITableViewCell), that would imply that the value returned could be nil.
You can use the if let syntax because of this optional. This will return true if the value can be assigned to the variable. For example:
var myNilValue: String?
if(let nonNilValue = myNilValue){
//this will not be called
}
if let will return false, but:
var myNonNilValue: String? = "Hello, World!"
if(let nonNilValue = myNilValue){
//this will be called
}
Will return true.
Question marks ? are used after variable declarations to define that the variable may not have a value, and it may never have a value. They need to be unwrapped by using an exclamation point ! after the variable name. This can be used for results from a database, in case there is no result.
Exclamation points ! are used after variable declarations to define that the variable may not have a value, but it will have a value when you need to access it. They do not need to be unwrapped, but the compiler will throw an error if the variable is nil at the time of accessing it. This is typically used in #IBOutlets or #IBActions which are not defined until the program compiles
Both self.tableView and indexPathForCell() are optionals. By banging one, you only have one optional to dereference in the result. sender is also an optional and indexPathForCell() doesn't take an optional so it probably needs a bang too, but I haven't compiled it so I can't say for sure what the compiler will do.
self.tableView is reference to a property that might not have been set (e.g. is nil), so it is an optional. You can declare it for example an #IBOutlet with a ! at the end if you know it will ALWAYS be defined, such as from the Storyboard, and then you don't have to bang dereference it later.
A common thing to do is:
#IBOutlet var tableView : UITableView!
That's an implicitly unwrapped optional, and will generate an error if it's referenced when nil. But you don't need to use a ! to dereference.
Correct. The result of the line will produce an optional that you can test with if let

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