How to use max with swift3? - swift

i am getting an error for the bellow code:
var bubbleWidth:CGFloat!
bubbleWidth:CGFloat = max( CGFloat(15) , bubbleWidth )
here is the error message:
no candidates produce the expected contextual result type 'cgfloat!'
this code was working without any problem on swift 2 , i don't know why i am getting that error now !
EDIT:
here is my real code:
var bubbleWidth:CGFloat!
bubbleWidth = imageView.frame.width + 11
bubbleWidth = max( CGFloat(15) ,
bubbleWidth )
and here is the error that i am receving:
Edit:
please note: i don't want to assign value to bubbleWidth, like that
var bubbleWidth:CGFloat = -1
Thanks

This is a consequence of SE-0054 Abolish ImplicitlyUnwrappedOptional type which has been implemented in Swift 3:
However, the appearance of ! at the end of a property or variable declaration's type no longer indicates that the declaration has IUO type; rather, it indicates that (1) the declaration has optional type, and (2) the declaration has an attribute indicating that its value may be implicitly forced. ...
If the expression can be explicitly type checked with a strong optional type, it will be. However, the type checker will fall back to forcing the optional if necessary.
Now one could argue that the compiler should fall back to unwrapping
the optional in
bubbleWidth = max(CGFloat(15), bubbleWidth)
but for some reason that works only with a float literal
bubbleWidth = max(15, bubbleWidth)
and I am not sure if this is a bug or not. Alternatively, unwrap the value explicitly
bubbleWidth = max(CGFloat(15), bubbleWidth!)
or – better – provide a default value with the nil-coalescing operator ??:
bubbleWidth = max(CGFloat(15), bubbleWidth ?? 0)

Related

Unexpectedly found nil while unwrapping an Optional value but value exist

I know I need to bind my varaible for unwrap but the problem is my value is not reconized but present.
This is my code :
surveyW.karmaWin = Int(endedSurvey["karma"].string!)
endedSurvey is a array dictionary of my JSON backend. I get a Unexpectedly found nil while unwrapping an Optional value error.
I specify that I force the unwrapping to show you my problem.
The problem is my array contains the karma value. I show you the screen of the value:
So we can see that the value existing. Why I get a Unexpectedly found nil...?
The value contained in "karma" is not String. You're trying to force cast it with SwiftyJSON but it tells you it has a nil. You first need to extract value as it is - .int, and after that convert that to something else if needed.
surveyW.karmaWin = endedSurvey["karma"].int
You can use intValue because SwiftyJSON has two kinds of "getters" for retrieving values: Optional and non-Optional
.string and .int are the optional getters for the String and Int representation of a value, so you have to unwrap it before use
if let fbId = fbJson["id"].string {
print(fbId)
}
If you are 100% sure that there will always be a value, you can use the equivalent of "force unwrap" by using the non-Optional getter and you don't need if let anymore:
let fbId = fbJson["id"].stringValue
In your code :
surveyW.karmaWin = endedSurvey["karma"].intValue
endedSurvey["karma"] is an Integer not string and also good way to unwrap an optional is:
if let karma = endedSurvey["karma"] as? Int{
surveyW.karmaWin = karma
}

Difference of ? and ! when using an instance of optional type?

var neilPeart: Drummer? = Drummer()
var rush: Band? = Band(drummer: neilPaert!)
Suppose we have an instance named neilPeart of optional type of Drummer, and an instance named rush of optional type of Band. There is a band property for Drummer instances. If I want to change the band property of neilPeart, what's the difference between "neilPeart?.band = rush" and "neilPeart!.band = rush"
Optionals use ? marks which means that if I were to say var title: String?. That would mean that title could either contain a value or be nil. The ! points are used to unwrap an optional value. This could create an issue for you and give you an error if your value is nil. The error would result in not being able to unwrap a nil object. Hope this helps!
? will set it to nil if there is no value
! will force unwrap the value and will crash the app if there is no value

Swift: what's the difference between Array<OtherModule.MyType>() and [OtherModule.MyType]()

I'm using a type from a different module, let's call it OtherModule.MyType,
This code:
var a = [OtherModule.MyType]()
will produce an error invalid use of '()' to call a value of non-function type '[MyType.Type]'
This code won't:
var ax = [OtherModule.MyType]
But I believe ax is not an array any more, since this code
ax.append(OtherModule.MyType())
will cause an error Cannot invoke 'append' with an argument list of '(MyType)'
So I wonder what ax really is?
Besides, this code works fine:
var ay = Array<OtherModule.MyType>()
ay.append(OtherModule.MyType())
UPDATE:
I'm using swift 1.2 with Xcode 6.3
For some reason best known to the Swift team (modules are very scantly documented), Module.Thing behaves differently to Thing.
While Int is just a type name:
let i: Int = 1 // fine
// not fine, "expected member name or constructor call after type name"
let j = Int
Swift.Int can be both:
// used as a type name
let k: Swift.Int = 1
let t = Swift.Int.self
// but also used as a value
let x = Swift.Int
// equivalent to this
let y = Int.self
toString(x) == toString(y) // true
Under some uses it only wants to be a value, not a type name though. Hence this works:
// a will be of type [Int.Type], initialized with an array
// literal of 1 element, the Int metatype
let a = [Swift.Int]
But trying to use it as a type name in this context fails: [Swift.Int]() is no more valid than writing [1]() or let strs = ["fred"]; strs().
This behaviour seems a little arbitrary, and may even be a bug/unintentional.
Since the only way in which Swift.Int can be used in this context:
Array<Swift.Int>()
is as a type not a value (since only types can go between the angle brackets), it kind of makes sense that this works while the more ambiguous array literal syntax behaves differently.

Difference between optional and forced unwrapping [duplicate]

This question already has answers here:
What is an optional value in Swift?
(15 answers)
Closed 5 years ago.
Below is the code for optional string for variable name yourname and yourname2.
Practically what is difference between them and how forced unwrapping in case of yourname2
var yourname:String?
yourname = "Paula"
if yourname != nil {
println("Your name is \(yourname)")
}
var yourname2:String!
yourname2 = "John"
if yourname2 != nil {
println("Your name is \(yourname2!)")
}
The String? is normal optional. It can contain either String or nil.
The String! is an implicitly unwrapped optional where you indicate that it will always have a value - after it is initialized.
yourname in your case is an optional, yourname2! isn't.
Your first print statement will output something like "Your name is Optional("Paula")"
Your second print statement will output something like "Your name is John". It will print the same if you remove the exclamation mark from the statement.
By the way, Swift documentation is available as "The Swift Programming Language" for free on iBooks and the very latest is also online here.
What you call 'forced unwrapping' is known as an 'implicitly unwrapped optional'. An implicitly unwrapped optional is normally used in objects that can't or won't assign a value to a property during initialization, but can be expected to always return a non-nil value when used. Using an implicitly unwrapped optional reduces code safety since its value can't be checked before runtime, but allows you to skip unwrapping a property every time it's used. For instance:
var a: Int!
var b: Int?
var c = a + b //won't compile
var d = a + b! //will compile, but will throw an error during runtime
var e = a + a //will compile, but will throw an error during runtime
a = 1
b = 2
var f = a + b //still won't compile
var g = a + b! //will compile, won't throw an error
var h = a + a //will compile, won't throw an error
Generally speaking you should always use optionals if you don't assign a value to a variable at initialization. It will reduce program crashes due to programmer mistakes and make your code safer.
Forced unwrapping an optional, give the message to the compiler that you are sure that the optional will not be nil. But If it will be nil, then it throws the error:
fatal error: unexpectedly found nil while unwrapping an Optional value.
The better approach to unwrap an optional is by optional binding. if-let statement is used for optional binding : First the optional is assign to a arbitrary constant of non-optional type. The assignment is only valid and works if optional has a value. If the optional is nil, then this can be proceed with an else clause.

Why my optional value is not unwrapped, Swift?

I have pretty simple example and have no clue why it doesn't work as expected.
var list:Array<Int> = [1,2,3,4,5]
var item:Int?
for var index = 0; index < list.count; index++ {
item! = list[index]
item = item + 5 // <-- error value of optional type 'Int?' not unwrapped
}
Why Swift forces me to write: item = item! + 5
I unwrapped it here: item! = list[index] and if list returns nil - the Exception will be thrown.
As I understand on this step a.e.: item! = list[index] the item is not nil
I tried several options like:
item! = list[index] as Int!
item! = list[index] as AnyOblect! as? Int
But still get the same demand to write item = item! + 5
I use playground
Let me break it down for you:
var item:Int? tells the compiler that whenever the word item is used, it refers to a variable of type optional Int (aka Int?).
var item:Int on the other hand, tells the compiler that whenever the word item is used, it refers to a variable simply of type Int.
In order to access the unwrapped value of your variable declared in var item:Int?, you will always have to use item!. The compiler is not going to guess whether the variable item has a value or not. That, after all, is the the whole purpose of optionals. To make it clear that these kind of variables may or may not have a value.
Essentially, what I'm trying to say is that a variable once declared as an optional, will always be an optional regardless of whether it contains a value or not. To get the unwrapped value, you will always have to use the character !, unless you decide to store it's value in another variable (ex. var unwrappedItem = item!)
To get rid of your error, simply declare your item variable to be of type Int, and not Int?.
As to why Swift throws an error instead of just letting the runtime raise an exception, it's just an extra precaution to probably discourage people from using bad practice.