Reputation: 489
It has been a long time since I have coded in iOS and I am upgrading the old app to swift 3. I am really struggling with one issue of using optional variables.
I have a textfield which is optional. I want it unwrapped into a non-optional Int so that I can use it in the other functions for calculation.
@IBOutlet weak var txtRuns: UITextField!
func sendScore()
{
let runs = txtRuns.text!
let overs = txtOvers.text!
let balls = txtBalls.text!
let wkts = txtWkts.text!
let target = txtTarget.text!
let totalOvers = txtTotalOvers.text!
let strData = "S|R\(runs)" + getOptionalScoreData(
runs: Int(runs),
wkts: Int(wkts),
overs: Int(overs),
balls: Int(balls),
target: Int(target),
totalOvers: Int(totalOvers)
)
}
func getOptionalScoreData(runs: Int, wkts: Int, overs: Int, balls: Int, target: Int, totalOvers: Int) -> String
{
if ( runs == 0 ) {
return getCurrentRunRate(runs: runs)
}
return "";
}
As you can see, I have so many functions to call and I want this textfield to turn into non-optional INT.
Now I have tried several options that I read over here but the error messages only change. The problem didn't solve.
Current ERROR is
The value of optional type 'Int?' not unwrapped; did you mean to use '!' or '?'?
Please help. Thanks
.................
Please note that I don't think nested check is a nice idea here because all these variables are independent of each other. One can be nil but other can be still passed and used.
If I nest checks like this, it means that no other value will be passed if runs are nil.
if let runs = txtRuns.text, let runsInInt = Int(runs) {
if let overs = txtOvers.text, let oversInInt = Int(overs) {
if let wkts = txtWkts.text, let wktsInInt = Int(wkts) {
strData = "S|R\(runs)\(overs)\(wkts)" + getOptionalScoreData( runs: runsInInt, overs: oversInInt, wkts: wktsInInt)
}
Upvotes: 1
Views: 576
Reputation: 2092
If you are frequently getting value from UITextField
as Int
, you can add an extension as follows:
extension UITextField {
var intValue: Int {
get {
if let text = self.text {
return Int(text) ?? 0
}
return 0
}
set {
self.text = String(newValue)
}
}
}
You can add the above as private extension in your viewcontroller too. Now you can rewrite your code as:
func sendScore() {
let strData = "S|R\(txtRuns.intValue)\(overs.intValue)\(wkts.intValue)" + getOptionalScoreData(
runs: txtRuns.intValue,
wkts: wkts.intValue,
overs: overs.intValue,
balls: balls.intValue,
target: target.intValue,
totalOvers: totalOvers.intValue)
)
}
Upvotes: 4
Reputation: 1473
Int(runs)
call constructor of Int following:
public init?(_ text: String, radix: Int = default)
Because String
to Int
might failed due to the String might not a valid integer.
How would you deal with it?
You can reference Sallu's comment.
!
to guarantee the String
in UITextField
is absolute a valid integer, or app crash.runs: Int(runs)!
??
to give a default value if the String
in UITextField
is not a valid integer.runs: Int(runs) ?? 0
In the case the default value is 0
Upvotes: 0