Saturday, November 18, 2017

Guard Statement in Swift

What is guard statement in swift?

Guard statement is combination of two powerful concepts that we’re already used to in Swift: optional unwrapping and where clauses. The previous allows us to avoid the pyramid of doom or its alternative, the very long if let statement. The latter attaches simple but powerful expressions with the where clause so we can further vet the results we’re validating.

When do we use guard?

If we have  got a view controller with a few UITextField elements or some other type of user input,we’ll immediately notice that you must unwrap the textField.text optional to get to the text inside (if any!). isEmptywon’t do you any good here, without any input the text field will simply return nil.
So you have a few of these which you unwrap and eventually pass to a function that posts them to a server endpoint. We don’t want the server code to have to deal with nil values or mistakenly send invalid values to the server so we’ll unwrap those input values with guard first.
func submit() {
    guard let userName = txtName.text else {
        show("No name to submit")
        return
    }

    guard let userAddress = txtAddress.text else {
        show("No address to submit")
        return
    }

    guard let userPhone = txtPhone.text else {
        show("No phone to submit")
        return
    }

    sendToServer(name, address: address, phone: phone)
}

func sendToServer(name: String, address: String, phone: String) {
  ...
}

You’ll notice that our server communication function takes non-optional String values as parameters, hence the guard unwrapping beforehand. The unwrapping is a little unintuitive because we’re used to unwrapping with if let which unwraps values for use inside a block. Here the guard statement has an associated block but it’s actually an else block - i.e. the thing you do if the unwrapping fails - the values are unwrapped straight into the same context as the statement itself.

Without usingguard:

Without using guard, we’d end up with a big pile of code that resembles a pyramid of doom. This doesn’t scale well for adding new fields to our form or make for very readable code. Indentation can be difficult to follow, particularly with so many else statements at each fork.
 func nonguardSubmit() {
    if let userName = txtName.text {
        if let userAddress = txtAddress.text {
            if let userPhone = txtPhone.text {
                sendToServer(name, address: address, phone: phone)
            } else {
                show("no phone to submit")
            }
        } else {
            show("no address to submit")
        }
    } else {
        show("no name to submit")
    }
}
Yes, we could even combine all these if let statements into a single statement separated with commas but we would loose the ability to figure out which statement failed and present a message to the user.
If you start seeing this kind of code appear in one of your view controllers, it’s time to start thinking about how to do the same thing with guard.

Validation and testing with guard:

One argument against using guard is that it encourages large and less testable functions by combining tests for multiple values all in the same place. If used naïvely this could be true but with the proper use, guard allows us to smartly separate concerns, letting the view controller deal with managing the view elements while the validation for these elements can sit in a fully tested validation class or extension.
Let’s take a look at this naïvely constructed guard statement with validation:
guard let name = nameField.text where name.characters.count > 3 && name.characters.count <= 16, let range = name.rangeOfCharacterFromSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()) where range.startIndex == range.endIndex else {
    show("name failed validation")
    return
}

submit(name)
You can probably tell we’re stuffing too much functionality into a single line here. Not only do we check for existence of the name field, we also check that the name is between 3 and 16 characters in length and that it contains no newlines or whitespaces. This is busy enough to be nearly unreadable, and it’s unlikely to be tested because we can’t validate the name field without interacting with the UI and submitting the name to the server.
Realistically, this view controller could be handling 5 inputs and each should be checked for validity before it’s submitted. Each one could look just like this, leading to a truly massive view controller.
Here’s a better example of real world guard usage.
func tappedSubmitButton() {
    guard let name = nameField.text where isValid(name) else {
        show("name failed validation")
        return
    }

    submit(name)
}

func isValid(name: String) -> Bool {
    // check the name is between 4 and 16 characters
    if !(4...16 ~= name.characters.count) {
        return false
    }

    // check that name doesn't contain whitespace or newline characters
    let range = name.rangeOfCharacterFromSet(.whitespaceAndNewlineCharacterSet())
    if let range = range where range.startIndex != range.endIndex {
        return false
    }

    return true
}
You’ll notice a few differences in the updated version. First, our name validation function is separated into a testable validation function (located either in your view controller or in a different, fully tested class depending on your preferences). isValid has clearly marked steps for validating a name: a length check and a character check.
Instead of cramming all that validation into the where clause, we simply call the isValid function from the where clause, failing the guard statement if the text is nil or fails validation.
Testing is great but the best part of this implementation is the clarity of code. tappedSubmitButton has a very small responsibility, much of which is unlikely to fail. View controllers are difficult to test on iOS using standard MVC organization (which, despite many new players, is still the clearest organizational pattern) so minimizing their responsibility or likelihood of failure is an important part of architecting your iOS app.

guard has clear use cases but can be tempting to use as part of a massive view controller. Separating your guardvalidation functions allows you to maintain more complex view controllers without loosing clarity or readability.

Thursday, February 13, 2014

Insert Text in new line without deleting the previous text in Text View

When you want to add text in new line without deleting the previous text , you have to follow the steps below:
  • Assign the value of the textField in NSString type variable  say NSString*newText;
  • Assign the value of the textView in another NSString type variable say NSString*oldText;
  • Take a NSString type variable and append the value of your textField with new line @"\n" say NSString *myString;
  • Now append the value of myString and oldString and you well get your desired output. The Code is given below

  NSString *oldText,*newText,*myString;
- (IBAction)addNewItem:(id)sender {
    [self updateTextField];
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];
   
    return YES;
}

-(void)updateTextField
{
    oldText=displayTextView.text;
    newText=entryTextField.text;
    myString = [newText stringByAppendingFormat:@"\n"];
    myString = [myString stringByAppendingString:oldText];
    displayTextView.text=myString;
   
   
}

The Screenshot of the application is provided below




Happy Coding
Mahboob