Cannot force unwrap the value - swift

var tuples: String! = "subash"
if let goin = tuples {
print(goin!)
}
I am receiving this error:
Cannot force unwrap the value of non-optional type String
I don't what happening constant goin is same as tuples but why it's showing me an error when I do force unwrap
Instead of the above code, this is running well:
var tuples: String! = "subash"
print(tuples!)
But kindly I need a solution to my above problem

That's something normal if you know how optionals work.
Inside the if statement, the right expression must be either Optional or Implicitly Unwrapped Optional, BUT NOT "normal" value.
This is the correct code:
let tuples: String! = "subash"
if let goin = tuples {
print(goin) // NO NEED to unwrap, because going IS NOT Optional
}
The reason this code runs fine:
var tuples: String! = "subash"
print(tuples!)
print(tuples)
... is because tuples is of type Implicitly Unwrapped Optional.
However, in general cases like this:
let myVar: String! = "some string"
if let myNewVar = myVar {
// Some code...
}
... myVar is always an Implicitly Unwrapped Optional, whereas myNewVar is of String type, because of how Optional Unwrapping works with if let statements.
Finally, if we unwrap the value this way:
let myVar: String! = "some string"
if let myVar = myVar {
// Some code...
print(myVar)
}
The printed value is the temp myVar, which is of type String and shadows the Implicitly Unwrapped myVar variable we initially declare.

Related

ImplicitlyUnwrappedOptional in init vs later

I would like to understand why I don't get ImplicitlyUnwrappedOptional when I do params["bar"] = str but I get it when I declare params with the same force unwrapped variable.
See the playground below:
import UIKit
var str: String!
str = "Hello"
var params: [String: Any] = [
"foo": str
]
params["bar"] = str
print(params)
// ["bar": "Hello", "foo": Swift.ImplicitlyUnwrappedOptional<Swift.String>.some("Hello")]
In Swift 4.1, when you do:
var str: String!
str = "Hello"
var params: [String: Any] = [
"foo": str
]
The ImplicitlyUnwrappedOptional (IUO) value is coerced to Any, which is why it appears as an IUO inside your dictionary. It won't be force unwrapped, because the compiler will only force unwrap an IUO when the context demands its unwrapped type, which isn't the case with Any.
However the fact that you end up with an ImplicitlyUnwrappedOptional value is legacy behaviour. With the removal of the IUO type in Swift 4.2, you'll get an Optional value inside your dictionary instead, which will print as Optional("Hello").
There's more discussion of the above behaviour in this Q&A:
Why does implicitly unwrapped optional not unwrap in dictionary of type [String : Any]
When you do:
params["bar"] = str
You're using Dictionary's subscript(key: Key) -> Value?, which takes an Optional value – performing a removal if nil is passed, otherwise doing an insertion of the unwrapped value.
In Swift 4.1, the IUO value str will be implicitly converted to an Optional which can then be passed to the subscript.
In Swift 4.2, the IUO type has been removed, so str already is an Optional, which can be passed straight to the subscript without any intermediate conversions.
In both cases, str's unwrapped value is inserted into the dictionary, which is why you see it as being unwrapped. If str had been nil, no value for the key "bar" would have been inserted.

Why optional is not giving warning or asking for force unwraping?

struct SomeStruct {
var optVar : String?
var nonOptVar : String = "Hello"
var optvar2 : String!
}
let obj2 = SomeStruct(optVar: "a", nonOptVar: "b", optvar2: "c")
let a = obj2.optVar // why it is not asking for force unwraping
let b = obj2.nonOptVar
let c = obj2.optvar2
print(a)
print(b)
print(c)
Please share your view on this. But while I use optionals in project generally it gives warling
'Expression implicitly coerced from String? to Any'
This is mainly due to type inference. Here:
let a = obj2.optVar
a is inferred to be of type String?, because that's the type of the expression on the right, isn't it?
// basically this:
let a: Optional<String> = obj2.optVar
An optional value can be assigned to a variable of an optional type. Nothing wrong with that.
If you declare a to be of type String, however, you need to unwrap it:
let a: String = obj2.optVar // error!
The warning 'Expression implicitly coerced from String? to Any' appears when you are trying to put an optional value into a variable of type Any, like this:
let a: Any = obj2.optVar // warning!

swift 3.0 Problems about String initialization

I am quite new to Swift and when I learning about initializing a string, I find a wired syntax that I cannot understand.
For example
If I initialize a string using:
var str:String = "Hello, playground"
str.isEmpty
This works well
However, if I initialize a string with a constructor
var str = String("Hello, playground")
str.isEmpty
this does not work.
And the compiler fix it by changing the syntax to
str?.isEmpty
I have no idea about what is that “?” for.
Any suggestion is appreciated.
When you say:
let str = String("Hello, playground")
you're using String's init?(_ description: String) initialiser, which satisfies LosslessStringConvertible's initialiser requirement, as not all types that conform have a representation for an arbitrary string (for example, Double).
Because the initialiser is failable, it returns an optional string instance (i.e String?), hence why the compiler is prompting you to use optional chaining (if not already, I would highly recommend reading the optionals section of the language guide).
However it's worth noting there's absolutely no need for String's implementation of this initialiser to be failable – as a string can always represent a string! This will be fixed in Swift 4, it will be implemented as a non-failable initialiser satisfying the failable requirement. This is because it doesn't break the contract with the protocol of either returning a new instance or nil (it just never happens to do the latter).
In the mean time however, you could just force unwrap the result, as it will always succeed. But really the use of the initialiser here is completely redundant. You should use a string literal, such as in your first example:
let str = "Hello, playground"
str will simply be initialised to a non-optional String instance with the contents of the string literal. Note that Swift can infer str to be of type String – you don't need to explicitly annotate it as such.
var str = String("Hello, playground")
This produces what is called an "Optional". In Swift, if something can be null/nil, then it is wrapped in an Optional. The '?' tries to unwrap the optional and produce a String.
If you KNOW that the value can never be null, then you can force unwrap it like this:
var str = String("Hello, playground")
str!.isEmpty
or
var str2 = String("Hello, playground")!
str2.isEmpty
Generally though forced unwrapping is frowned upon, as it can lead to crashes. Better approaches:
struct MyError:Error {
var message:String
}
guard let str3 = String("Hello, playground") else {
throw MyError(message:"failed")
}
str3.isEmpty
if let str4 = String("Hello, playground") {
str4.isEmpty
}

Convert String to int in Swift 3

I have the following variable:
var npill : String!
It's an Int value, but I can't set it as Int because of:
npillIn: fieldNumeroPillole.text!,
How can I convert this var to a Int var? I have tried the following:
var number1: Int = (npill! as NSString).intValue
By the above code I receive the following error:
cannot use instance member 'npill' within property initializer, property initializers run before "self" is aviable
If I then set:
var number1: Int = (self.npill! as NSString).intValue
The error it outputs is as follows:
Value of type '(NSObject) -> () -> Farmaco' has no member 'npill'
If anyone knows how I should be converting it properly, please let me know.
Update
Thank you to #Hamish for pointing out what the OP was asking
So the problem seems to be this
import Foundation
class Foo {
var npill : String!
var number1: Int = (npill! as NSString).intValue
}
error: cannot use instance member 'npill' within property initializer; property initializers run before 'self' is available
var number1: Int = (npill! as NSString).intValue
^
What's going on here?
You are using a property to populate another property, and this is not allowed.
Solution
However you can easily fix the problem postponing the initialisation of number1. Infact if you make number1 lazy, it will be populated only when used.
class Foo {
var npill : String!
lazy var number1: Int = { return Int(self.npill!)! }()
}
Warning: Of course this code will crash if npill is still nil when number1 is used.
Old version
You can simply write
let npill: String! = "34"
if let npill = npill, let num = Int(npill) {
print(num) // <-- here you have your Int
}
(As #Hamish pointed out in a comment below, I misunderstood what the OP was really asking about. I'll leave my answer, however, as some curiosa and insights regarding ! type annotation, which may be relevant for future readers of this question)
For any type of String optionals, their values needs to be unwrapped prior to using the failable init?(_ text: String) initializer or Int.
In your example, the variable npill is an optional, as you've annotated its type with the ! specifier (which should be used with care). Quoting from the implemented evolution proposal SE-0054 [emphasis mine]
Appending ! to the type of a Swift declaration will give it optional
type and annotate the declaration with an attribute stating that it
may be implicitly unwrapped when used.
Hence, it's entirely legal to use npill directly with the init?(_ text: String) initializer of Int, as it will be unwrapped (without any safety check for nil content!) on-the-fly upon use.
// UNSAFE example!
var npill: String! = "42"
if let npillInt = Int(npill) {
/* ^^^^^^^^ ^^^^^- since 'npill' has a type annotated with
| '!', it will be unsafely unwrapped at
| this point
\
the optional binding here safely unwraps the return from
the failable Int initializer, but has nothing to do with
the unwrapping of 'npill' */
print(npillInt) // 42
}
// why unsafe? consider
npill = nil
if let npillInt = Int(npill) { // runtime exception!
// ...
}
Generally you should avoid using the ! annotation, however, unless you are entirely certain that the content of the resulting optional variable will never ever be nil.
Leaving aside the cons of even using the ! annotation: you may implement a safe version of the unsafe example above, by overriding the unsafe implicit unwrapping with safe explicit unwrapping techniques. For a given optional variable declared using the ! annotation, we may still apply safe means to unwrap it, e.g. optional binding or using the nil coalescing operator. #appzYourLife has already showed one perfectly valid and safe way to handle the unwrapping and attempted type conversion of npill using optional binding, so I'll simply include another example using the nil coalescing operator instead:
// "safe" example (STILL: why use the `!` annotation?)
var npill: String! = "42"
if let npillInt = Int(npill ?? "x") {
/* ^^^^^ if 'npill' is 'nil', the Int initializer will
be given the value "x", which itself will lead
it to fail, which is safe here as we intend to
bind the result of the initialization to 'npillInt' */
print(npillInt) // 42
}
npill = nil
if let npillInt = Int(npill ?? "x") {
// ... doesnt enter
}
The consensus of the examples above is that if we're even slightly uncertain whether npill can ever be nil or not, we need to treat it as if it was just an optional not type annotated with ! (i.e. String?); overriding the default unsafe unwrapping with safe means when working with the variable. In such a case, why would we even want to use the ! typ annotation at all, as it only brings fragility/danger to our application?

How to use guard statement to detect nil after an assignment?

I'm trying to use guard statement to check against nil.
I'm puzzled why the following let it slip through and generate a BAD_EXEC error:
guard let event:Event! = eventsImagesLoading.removeValueForKey(location) else {
return
}
images[location] = responseData
event!.iconImgData = images[location]
I'm trying to check if "event" is nil after the method call. If it is it should just return. But in reality it slips through and crashes on the event!.iconImageData... line.
The other answers show you how to solve your issue, but doesn't really explain why this error occurs, so I thought I'd pitch in on that.
The guard let ... else statement, much like if let ..., attempts to bind the unwrapped value of an optional---generally as long as this is not nil---to a non-optional immutable of the same underlying type; using optional binding
var a: Int? = 5
if let b = a {
// b unwrapped, type inferred to non-optional type Int
print(b) // "5"
}
The above binding would fail if a had the value nil, as b, as per default (by type inference), is of type Int which cannot hold nil.
In this context, it makes no sense to explicitly declare b to be an implicitly unwrapped optional, as this will allow a successful binding even if a is nil. An equivalently non-sense block would be to explicitly declare b to be an optional, whereafter the "attempted optional binding" of optional a (Int?) to optional b (Int?) would naturally always succeed, and the if let ... block reduces to a completely redundant block-local assignment.
a = nil
if let b: Int! = a {
print(b) // "nil"
// wups, we managed to bind a to b even though a is nil ...
// note also this peculiarity
print(b.dynamicType) // Optional<Int>
let c: Int! = nil
print(c.dynamicType) // ImplicitlyUnwrappedOptional<Int>
}
if let b: Int? = a {
print(b) // nil
// wups, we managed to bind a to b even though a is nil ...
}
Note the peculiarity that no matter if we explicitly specify b to be of type Int? (optional) or type Int! (implicitly unwrapped optional), the binded immutable b passing into the if let block is, for both cases, just a regular optional (of type Int?). This explains why you need to unwrap event (event!.iconImgData) after the guard let clause, even though we declared it to be of an implicitly unwrapped type.
Hence, in your example, your guard let ... else statement will not catch cases where eventsImagesLoading.removeValueForKey(location) is nil, as the binding to event (which is of implicitly unwrapped optional type Event!) will success even for nil cases.
func foo() {
let bar : Int? = nil
guard let _: Int! = bar else {
print("this is surely nil")
return
}
print("but an implicitly unwrapped optional will fall through")
}
foo() // "but an implicitly unwrapped optional will fall through"
You should generally only use implicitly unwrapped optionals for immutables where you need delayed initialization (value nil until initialized). After initialization of an implicitly unwrapped optional, its value should never be nil (whereas in the example above, it's value is, after initialization by optional binding, just that; nil).
Also, you should generally let the compiler infer the non-optional type of the immutable to which you are trying to bind in the guard let INFER_THIS = ... else or if let INFER_THIS = ... clauses.
We could ponder over whether it should even be allowed to use optional binding to optional types (guaranteed success), but that is another discussion.
Change Event! to Event (line 1) and event! to event (line 5).
guard let event:Event = eventsImagesLoading.removeValueForKey(location) else {
return
}
images[location] = responseData
event.iconImgData = images[location]