Convert String to int in Swift 3 - swift

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?

Related

"Implicitly unwrapped property" warning?

I have a class where I have a property like this:
var residenceId: Int!
When building with Xcode 10 and Swift 4.2 there are no issues. However, after installing Xcode 11 Beta and converting to Swift 5 I get the following warning:
Implicitly unwrapped property 'residenceId' declared here
Later in the class I also have this function:
func jsonDictionary() -> [String : Any] {
return ["residenceId": residenceId]
}
Here I get the warning
Coercion of implicitly unwrappable value of type 'Int?' to 'Any' does not unwrap optional
Are we no longer allowed to use implicitly unwrapped optional?
EDIT:
After some more looking into it, I have come to believe that "Implicitly unwrapped property 'residenceId' declared here" is not actually a warning, but rather some info (it is in a grey label rather than usual yellow) to help me understand why I am getting the second warning.
And to clarify, my question is if we are no longer able to use the '!' symbol on properties to define an implicitly unwrapped property (obviously only if we are sure it will not be nil) in order to later avoid explicitly unwrapping it (and thus simplifying the code).
Since Swift 4, ImplicitlyUnwrappedOptional or ! as we knew it, became Optional.
Check:
let a: ImplicitlyUnwrappedOptional<Int> = 1
will spit out the error:
'ImplicitlyUnwrappedOptional' has been renamed to 'Optional'
So instead if we do:
let a: Int! = 1
print(type(of: a)) //will print "Optional<Int>"
It's still Optional<Int> but indicates to the compiler that it can be implicitly unwrapped.
Implicit Unwrapping is Part of a Declaration.
...
consider ! to be a synonym for ? with the addition that it adds a flag on the declaration letting the compiler know that the declared value can be implicitly unwrapped.
Ref: Reimplementation of Implicitly Unwrapped Optionals
Now getting to the main question:
If you do:
let a: Int! = 1
let b: Any = a
print(type(of: b)) //prints "Optional<Int>"
It will give the following warning:
Expression implicitly coerced from 'Int?' to 'Any'
or as per Xcode 11
Coercion of implicitly unwrappable value of type 'Int?' to 'Any' does not unwrap optional
Note here that we tried to get a non-optional Any out of an Int? which means we were basically expecting an Int but just by specifying Any it won't also unwrap the Optional.
It will remain an Optional, and this is the meaning behind that warning.
Solutions:
To handle this warning gracefully, we can do any of the following:
let a: Int! = 1
let b: Any? = a
type(of: b) //Optional<Any>.Type
let c: Any! = a
type(of: c) //Optional<Any>.Type
let d: Any = a!
type(of: d) //Int.Type
EDIT: (based on comment)
! instead of ? have any practical difference for the programmer?
! tells the compiler that it can be implicitly unwrapped so it can help ease in the need for optional chaining.
Example:
With ?
class A {
var n: Int? = 1
}
class B {
var a: A? = A()
}
let b: B? = B()
print(b?.a?.n)
/*
but the following won't compile as compiler
will not implicitly unwrap optionals
print(b.a.n)
*/
With !
class A {
var n: Int! = 1
}
class B {
var a: A! = A()
}
let b: B! = B()
print(b.a.n) //compiler will implicitly unwrap `!` similar to print(b!.a!.n)
//also... you can still safely unwrap if you want
print(b?.a?.n)
b.a.n and b?.a?.n will both give an Optional<Int> at the end
Ofcourse if b or a is nil then b.a.n will crash because it's implicitly unwrapping b and a to get to n which is Optional<Int>
To get Int instead of Optional<Int>, you would do b.a.n! and so in your case you would do: print(residenceId!) to get Int
I hope I made sense

The difference between Swift Optional Property Declarations [duplicate]

This question already has answers here:
Swift variable decorations with "?" (question mark) and "!" (exclamation mark)
(1 answer)
What is the difference between String? and String! (two ways of creating an optional variable)?
(7 answers)
Closed 4 years ago.
I noticed that some coding examples for Swift declare optional properties in different ways. However, I seem to have trouble trying to tell them apart (or, rather, when to use each.)
class MyClass {
// I believe this can start as nil but should always be set
// once it is.
var optionalProperty1: Type!
// I believe this can be set or nil anytime.
var optionalProperty2: Type?
// I think this is the same as
// var optionalProperty3: Type!
lazy var optionalProperty3: Type
}
How does each one differ from the others and when should each one be used?
var optionalProperty1: Type!
When you're sure you will have value for this property such as timestamp it will be something for sure. And Yes it can be nil too.
var optionalProperty2: Type?
When you're not sure about the value (Or this field is not mandatory) take it as optional for example:- If I make a Person class address can be optional and name will not.
lazy var optionalProperty3: Type
This syntax is wrong you can not declare lazy property in this way. You must assign something to it initially. See below example:
/// First way
lazy var optionalProperty3: String = {
return "Hello"
}()
/// Second way
lazy var optionalProperty4 = "Hello"
A lazy stored property is a property whose initial value is not calculated until the first time it is used. You indicate a lazy stored property by writing the lazy modifier before its declaration. lazy variables are great for things that need to be setup once, then never re-set.
One more thing you really don't need to specify type in modern Swift. Means if you will assign 0 it will be an integer itself, if you will assign 0.0 it will take it as double and same for String, Array etc.
The third declaration is not an optional.
The third one declares a lazy property. Lazy properties will only be initialised when they are first used. Example:
class A {
lazy var a: Int = {
print("hello")
return 1 + 1
}()
}
let a = A()
print(a.a)
If you remove the last line, hello will not be printed.
The first declaration is a implicitly unwrapped optional while the second declaration is a normal optional.
When you access members of a normal optional, you need to unwrap it with ? or !:
var myInt: Int? = ...
print(myInt.description) // doesn't compile, must unwrap
print(myInt!.description) // will crash if myInt is nil
print(myInt?.description) // will print "nil" if myInt is nil
On the other hand, implicitly unwrapped optionals do this implicitly - whenever you try to access a member, it will implicitly unwrap it with ! for you:
var myInt: Int! = ...
print(myInt.description) // equivalent to "myInt!.description"
From Apple's Swift documentation:
Optionals (?): "You use optionals in situations where a value may be absent. An optional represents two possibilities: Either there is a value, and you can unwrap the optional to access that value, or there isn’t a value at all."
Implicitly Unwrapped Optionals (!): "As described above, optionals indicate that a constant or variable is allowed to have “no value”. Optionals can be checked with an if statement to see if a value exists, and can be conditionally unwrapped with optional binding to access the optional’s value if it does exist.
Sometimes it’s clear from a program’s structure that an optional will always have a value, after that value is first set. In these cases, it’s useful to remove the need to check and unwrap the optional’s value every time it’s accessed, because it can be safely assumed to have a value all of the time.
These kinds of optionals are defined as implicitly unwrapped optionals. You write an implicitly unwrapped optional by placing an exclamation mark (String!) rather than a question mark (String?) after the type that you want to make optional.
Implicitly unwrapped optionals are useful when an optional’s value is confirmed to exist immediately after the optional is first defined and can definitely be assumed to exist at every point thereafter. The primary use of implicitly unwrapped optionals in Swift is during class initialization, as described in Unowned References and Implicitly Unwrapped Optional Properties."
Read more at https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html
Explicitly Unwrapped Variable
var optionalProperty1: Type!
This means that the value should never be nil. It will always be initialized but it is better to use var optionalProperty1: Type
Optional
var optionalProperty2: Type?
This is an optional value, meaning that it can either have a value or be nil. normally to use the value you would need to unwrap it. using either conditional unwrapping or a guard statement...
if let value = optionalProperty2 {
print("optionalProperty2 had a value, value is set")
}
guard let value = optionalProperty2 else {
print("optionalProperty2 was nil value is nil")
}
or you can just check if it has a value and explicitly unwrap it (which is not considered best practice)
if optionalProperty2 != nil {
print("optionalProperty2 is set to \(optionalProperty2!)")
}
Lazy Variable
lazy var optionalProperty3: Type a lazy variable is different, it is not an optional unless you define it to be optional. Lazy variables do not initialise to a value until the value is first used. So if you do not call/use the variable it will never be set.

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
}

About variable type in Swift

I understand the difference between String! type and String? type. But what about String type? How does it differs from String! and String? in swift? Does String! type identical to String type?
Say, I have a class like this:
class Person {
private var _name: String!
var name: String {
return _name
}
init(name: String) {
_name = name
}
}
There is no compiler error, looks like String type is identical to String! type. But I am not sure...
String and String! are not identical. There is just happens to be enough sugar in the language to convert between them. Similarly there is sugar in the language to convert between String and String? (but not in reverse).
Start with the basics. There is String. Unless there is some strong reason, you should use String when you mean a string of characters. Everything else is "more stuff" and you shouldn't add it unless you need it.
There is Optional<String>. This is just an enum with two cases, one with a value, and one without a value:
public enum Optional<Wrapped> : _Reflectable, NilLiteralConvertible {
case None
case Some(Wrapped)
// ...
}
There is a postfix operator ! for Optional which will return Wrapped if it's available, and crash if it is not. So far, no magic. This is stuff you could build yourself.
There are are few pieces of magic around Optional. First, the type Wrapped? is magically converted to Optional<Wrapped> by the compiler (for any Wrapped). This is just syntactic sugar. The two notations are identical. Second, there is optional-chaining with the ?. "operator" (it's not really an operator; it's part of the language and you couldn't build it yourself). And then there's optional promotion. Any type Wrapped can be automatically and implicitly converted to Wrapped? if needed. There are are few other pieces of magic around Optional like if-let syntax, and there's nil which is a synonym for Optional.None (I believe they're actually identical). But Optional really is just a generic type, implemented as an enum. It's just a type the compiler knows special things about.
Then there is ImplicitlyUnwrappedOptional<Wrapped>. This is also just an enum (in Swift 2.2; this will change in Swift 3).
public enum ImplicitlyUnwrappedOptional<Wrapped> : _Reflectable, NilLiteralConvertible {
case None
case Some(Wrapped)
// ...
}
This is not the same as Optional and it is not the same as Wrapped. It's a completely different type. But it also has some magic associated with it. First, the type Wrapped! is syntactic sugar for ImplicitlyUnwrappedOptional<Wrapped>. Again, it's just sugar. The two are the same (in Swift 2.2, not in Swift 3). Next, if IUO<Wrapped> is found in a place that Wrapped is expected, it will automatically be converted to Wrapped or crash if there is no value. If it is found in a place that Wrapped? is expected, it will automatically be converted to Wrapped?. Those are magical, and it's why sometimes String and String! seem to be the same type. That's just the compiler magically "making it work" for you by adding an invisible conversion step. It doesn't mean they're really the same type.
IUO is mostly useful in bridging to certain Objective-C patterns, especially involving Storyboards, and should be avoided outside of those situations. Even in those situations, IUO is just there for convenience. You could do all the same things using regular Optionals, you'd just have to check them with if-let more often. Using Optionals is much safer than using IUO. It's easy to think "I know for certain this value will always be set before it is used." And just this week I chased down a crasher due to being wrong about that. There's a difference between "it should be" and "it must be." But, being totally safe with Optionals in Storyboards could be very inconvenient and might mask some bugs (by doing nothing rather than crashing), so that's the most common place for IUO.
IUO properties used to be valuable for dealing with failable init methods. That's no longer a problem in Swift 2.2, so that use has gone away. The last "pure Swift" use that I run into is when you must pass self to the initializer of something you store as a property (you can't pass self at that point because all your properties have been initialized). That's an unfortunate use-case and very messy, and I hope we come up with a fix for it. Outside of these kinds of cases, you should avoid Implicitly Unwrapped Optionals.
String and String! are same and different at the same time. If you declare let or var as String, you will have to set some value at init method. If you declare it as String! you can set value when you want but you must do it before reading this value.
So, if your _name will be nil, your app will crash.
If you declare it as String, compiler guarantees that _name != nil before the first reading. If you declare it as String!, you should guarantee it.
This things have same type because of this:
var test1: String = "test"
var test2: String! = "test"
if test1 is String { // True
print("test1 is String")
}
if test2 is String { // True
print("test2 is String")
}
This types are equal but this things are different
Note the difference between these two functions:
func f() {
let x: String? = nil
guard let y: String = x else {
print("failed")
return
}
}
func g() {
let x: String? = nil
guard let y: String! = x else {
print("failed")
return
}
print(y.dynamicType, y)
}
f() # failed
g() # Optional<String> nil
You are better to read swift documentation than any answer here. Properly undestandig swift's type system is very important, so do it first.
both String! and String? are optional types.
Using String? requires you to test whether the value is nil (.None) or a value (.Some). For example using guard statements or if-let clauses.
String! is an optional that is assumed to be non-nil and is unwrapped automatically. This allows you to write cleaner-looking code and avoid unwrapping wherever the value is used. BUT: if your value is nil a fatal error will occur.

Incrementing an implicitly unwrapped optional

I declare an implicitly unwrapped optional as:
var numberOfRows: Int!
and initialize it in init:
numberOfRows = 25
Later I need to decrement it by one so I write:
numberOfRows--
but this doesn't compile. The error message says the decrement operator can't be applied to an implicitly unwrapped optional. With a little experimentation I find that the following compiles without error:
numberOfRows!--
I would like to understand this. What is the explanation for what seems like the extra '!'?
Implicitly unwrapped optional is a type on its own, and is different from the type it that wraps. Some operators on optionals and implicitly unwrapped optionals are pre-defined for you out of the box by the language, but for the rest you have to define them yourself.
In this particular case an operator postfix func --(inout value: Int!) -> Int! is just not defined. If you want to use postfix -- operator on Int! just the same way you use it on Int then you will have to define one.
E.g. something like:
postfix func --<T: SignedIntegerType>(inout value: T!) -> T! {
guard let _value = value else { return nil }
value = _value - 1
return _value
}
If we look at what the optional type is, we will see that this is enum like:
enum Optional<T> {
case Some(T)
case None
}
And it can be Some Type like Int for example or None and in this case it's have nil value.
When you make this:
var numberOfRows: Int!
you directly is indicated by the ! that this is not Int type but this is the enum Optional<Int> type. At moment of creation it's will be Some<Int> if equal it value but with this ! you have that it is enum Optional<Int> and in some next moment it will be the None. That's why you have to use ! second time when make this:
numberOfRows!--
Your nomberOfRows value is Optional<Int> type and it may be Int or nil and you have to directly indicate that this is Int type to make -- action.