Fr0zt
Fr0zt

Reputation: 1255

Non-optional expression of type uitextfield used in a check for optionals

I am doing an UIAlertController and I got this message: "Non-optional expression of type uitextfield used in a check for optionals". This is in the line where I have the "if let my field".

I got this code:

let alertController = UIAlertController(title: "Adding", message: "Type something", preferredStyle: UIAlertControllerStyle.alert)
let DestructiveAction = UIAlertAction(title: "Confirm", style: UIAlertActionStyle.default) { (result : UIAlertAction) -> Void in

if let field : UITextField = (alertController.textFields? [0])! as UITextField  {

 if field.text != "" {
//my actions                
        }

    }
    let okAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.default) { (result : UIAlertAction) -> Void in
    }
    alertController.addTextField { (textField) in
        textField.placeholder = "Type designation here"

    }
    alertController.addAction(okAction)
    alertController.addAction(DestructiveAction)
    self.present(alertController, animated: true, completion: nil)
}

Can anyone tell me how to remove this warning please? I tried to remove the "!" with no success.

Upvotes: 0

Views: 1334

Answers (3)

Chan Jing Hong
Chan Jing Hong

Reputation: 2461

Doing (alertController.textFields? [0])! as UITextField, don't really make sense, because it means that you are trying to cast alertController.textFields[0] to a UITextField, when it is already a type of UITextField.

What you should do instead is to check if the first element of alertController.textFields exist, which you can do so with the code below.

if let field : UITextField = alertController.textFields.first  {
    ...
}

Upvotes: 0

Jeffery Thomas
Jeffery Thomas

Reputation: 42588

You don't need to do the cast, the type of alertController.textFields is already [UITextField]. Adding the cast is what's really causing you the problem.

let alertController = UIAlertController(title: "Adding", message: "Type something", preferredStyle: UIAlertControllerStyle.alert)
let DestructiveAction = UIAlertAction(title: "Confirm", style: UIAlertActionStyle.default) { (result : UIAlertAction) -> Void in
    if let field : UITextField = alertController.textFields?[0]  {
        if field.text != "" {
            //my actions
        }
    }
}

I would like to show you something more. You don't need to set the type and I try to make my conditionals as specific as possible.

let alertController = UIAlertController(title: "Adding", message: "Type something", preferredStyle: UIAlertControllerStyle.alert)
let DestructiveAction = UIAlertAction(title: "Confirm", style: UIAlertActionStyle.default) { (result : UIAlertAction) -> Void in
    if let text = alertController.textFields?[0].text, !text.isEmpty {
        //my actions
    }
}

In addition, I think I would use a guard here.

let alertController = UIAlertController(title: "Adding", message: "Type something", preferredStyle: UIAlertControllerStyle.alert)
let DestructiveAction = UIAlertAction(title: "Confirm", style: UIAlertActionStyle.default) { (result : UIAlertAction) -> Void in
    guard let text = alertController.textFields?[0].text, !text.isEmpty else {
        return
    }

    //my actions
}

Upvotes: 0

vadian
vadian

Reputation: 285039

You are forced unwrapping the value so it's a non-optional. That's what the message tells you.

Since you have definitely added the text field to the alert controller you don't need any check and the code can be shortened:

let field  = alertController.textFields![0] // or textFields.first!

No type annotation, no type casting, the compiler can infer the type.

To check for empty string there is also a more convenient syntax:

if !field.text.isEmpty { ...

Upvotes: 4

Related Questions