Wednesday, February 13, 2013

Reversing a String in iPhone

Sometimes we want to perform some task on an object that is not included in the methods of that class. An example of this might be reversing the order of characters in an NSString object. While we could certainly do this in code, it would be better if we could add a class method to NSString itself that would reverse any string. In this blog, we’ll use a category to add the string reversal method to NSString.

A category is an Objective – C construct that allows us to add methods to any class, regardless of whether we have the source code for that class. Once we add a category to a class, all the methods in the category are added to all instances of the class in our code. Since categories are maintained in separate files, it is a simple matter to include them in any project where the extended features of the class are desired.

Open Xcode, choose “Create a new Xcode project,” select the Single View Application template, and click Next. Name the project “CategoryDemo,” and choose options as shown here:

Click Next, choose a location to save the project, and click Create.

When the app template has been created, open the ViewController.zib file, and drag controls to the view as shown below:

Note that the first control is a UITextField and the second is a UILabel. Set the UITextField’s return button type to “Done.”

Now we’re going to add the category. Right – Click on the ViewController.zib file, and select New File from the popup menu. Select Objective-C Category as shown here:

Click Next, then name the new category “AddedMethods”. Make sure that the category is on NSString, as shown:

Click Next, then Create. Two new files will be generated with the names NSString+AddedMethods.h and NSString+AddedMethods.m. This file naming convention makes it easy to see categories that we have added.

Open the NSString+AddedMethods.h file and add the declaration for our new class method as shown here:

#import <Foundation/Foundation.h>

@interface NSString (AddedMethods)

+ (NSString *)stringByReversingString:(NSString *)str;

@end

Save the file, and open the NSString+AddedMethods.m file. We’ll be adding the definition for our new class method here, as shown:

#import "NSString+AddedMethods.h"

@implementation NSString (AddedMethods)

+ (NSString *)stringByReversingString:(NSString *)str
{
    char cString[50];
    char revString[50];
    NSString *retval;
    [str getCString:cString
          maxLength:[str lengthOfBytesUsingEncoding:NSUTF8StringEncoding] + 1
           encoding:NSUTF8StringEncoding];
    printf("%s", cString);
   
    for (int i = 0; i < strlen(cString); i++) {
        revString[i] = cString[strlen(cString) - (i + 1)];
    }
    revString[strlen(cString)] = \0;
    retval = [NSString stringWithCString:revString encoding:NSUTF8StringEncoding];
     
    return retval;
}

@end

It is much easier to index into C strings and build them up character by character than it would be for NSString objects. In this method, we set up two buffers (char arrays). Then we get a C string representation of the str argument by using the getCString:maxLength:encoding method. In this method, the maxLength parameter must be one more than the number of bytes in the NSString to account for the NULL terminator on C strings.

We then copy each character from the cString to the revString in reverse order (in the for loop). After doing this, we put a NULL terminator ( ‘\0′) at the end of the reversed string, create a new NSString (retval) from the contents of the reversed string, and return it.

Next, open the ViewController.h file, and make changes as shown below:

#import <UIKit/UIKit.h>
#import "NSString+AddedMethods.h"

@interface ViewController : UIViewController

@property (nonatomic, strong)IBOutlet UILabel *output;

- (IBAction)inputDone:(UITextField *)sender;

@end

We must import the category in order to use it, as shown in the above listing. Declare one outlet for the label, and one action method for the text field. Using Interface Builder, wire up the output outlet to the UILabel object and the inputDone: method to the UITextField’s Did End On Exit event.

After the buttons are wired up to their corresponding methods, open the ViewController.m file and add the statements shown here:

@synthesize output;

- (IBAction)inputDone:(UITextField *)sender
{
    self.output.text = [NSString stringByReversingString:sender.text];
    NSLog(@"%@", self.output.text);
    [sender resignFirstResponder];
}

Add these lines immediately after the @implementation line in the .m file. As always, we synthesize properties, then add methods. The action method sets the output label’s text property to the reversed contents of the input text field’s text property using the stringByReversingString method we just added to the NSString class. After doing this, the method calls resignFirstResponder on the sender, which dismisses the keyboard.

Run the application now, enter a string in the text field, then click the Done button on the keyboard and observe the result.

Categories are a very powerful tool for adding functionality to existing classes. When we add a category to a class, all child classes of that class will inherit the added methods as well. As a further exercise, try to add another method to NSString category we defined that replaces all spaces in a string with underscores!


Source : edumobile[dot]org

0 comments:

Post a Comment