0

Sorry new to all this, but could do with a hand. Realise its probably a very simple solution, but here is my troublesome code:

@IBAction func loginAction(sender: AnyObject) {

    var username = self.usernameField.text
    var password = self.passwordField.text

    if (count(username.utf16) < 4 || count(password.utf16) < 5) {

        var alert = UIAlertView(title: "Invalid", message: "Username must be greater then 4 and Password must be greater then 5", delegate: self, cancelButtonTitle: "OK")
        alert.show()

    }else {

        self.actInd.startAnimating()

        PFUser.logInWithUsernameInBackground(username, password: password, block: { (user, error) -> Void in

            self.actInd.stopAnimating()

            if ((user) != nil) {

                var alert = UIAlertView(title: "Success", message: "Logged In", delegate: self, cancelButtonTitle: "OK")
                //alert.show()

                self.navigationController!.popToRootViewControllerAnimated(false)

            }else {

                var alert = UIAlertView(title: "Error", message: "\(error)", delegate: self, cancelButtonTitle: "OK")
                alert.show()

Photo of Errors: Value of optional type 'String?' not unwrapped; did you mean to use '!' or '?'

2 Answers2

1

The error message is pretty much self-explanatory, you need to unwrap the optionals. outlets are optionals so both usernameField.text and passwordField.text return a type String? (The type is optional string, not string) so you can't do any string related unless you unwrap it to be String. here is how you can do that

if  let username = self.usernameField.text, password = self.passwordField.text {
    //your code
}
Lukas
  • 3,423
  • 2
  • 14
  • 26
  • One correction tho: The type is an _Optional String_, not an optional, not a string. ;) It's pronounced "Optional " :) – Martin Marconcini Oct 16 '15 at 00:17
  • Thanks, I'll edit that :) I just wanted to emphasize its not a string – Lukas Oct 16 '15 at 00:31
  • :) Fun fact, Optional is actually an Enum :) – Martin Marconcini Oct 16 '15 at 01:02
  • I'm having one of those days where I have no idea what I'm doing... Would you be able to show me how I'd implement your example above? Thank you very much for your help so far btw! – Alexander Payne Oct 16 '15 at 19:22
  • I made the edit on your question. its actually very very simple :) – Lukas Oct 16 '15 at 19:43
  • Yeah :) I just can't work out where to put it into my code... haha. I've tried it and then on my ' if (count(username.utf16) < 4 || count(password.utf16) < 5)' I get the error "'Count' is unavailable: access the 'count property on the collection" Sorry for my ignorance, you will be surprised to know that I actually have two working Apps on the App store and yet I can't do this simple thing! Thank you :) (Also just made it exactly as you suggested in the edit... didn't know that feature existed! But still the same error as I've put above) – Alexander Payne Oct 16 '15 at 19:53
  • yeah, its changed. If you're using swift 2.0 use username.utf16.count but why are u using utf16? if you just wanna count the characters, use username.characters.count – Lukas Oct 16 '15 at 19:57
  • Thank you very very much, got the hang of it now! All fixed, means I can finally issue the iOS9 App updates. Thank you! :) – Alexander Payne Oct 16 '15 at 20:03
0

The purpose of optionals in Swift is to reduce the number of runtime errors. It allows the code to recognize when a variable has no value. 'no value' is different from nil and all other values.

When you reference an optional type you can force the compiler to get the value from the variable by adding an ! to the name. This should only be done when you are absolutely certain that there is a value to access. If you do this and no value is defined, your app will have a runtime error (crash). The optional can also be tested with an if to see if it has a value.

Think of this error message as a warning to you to check for a possible failure point.

john elemans
  • 2,578
  • 2
  • 15
  • 26