<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>White Pigeon Design</title>
	<atom:link href="http://whitepigeondesign.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://whitepigeondesign.com</link>
	<description></description>
	<lastBuildDate>Thu, 24 Mar 2011 02:38:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Text Validation Category</title>
		<link>http://whitepigeondesign.com/2010/09/27/text-validation-category/</link>
		<comments>http://whitepigeondesign.com/2010/09/27/text-validation-category/#comments</comments>
		<pubDate>Tue, 28 Sep 2010 02:16:59 +0000</pubDate>
		<dc:creator>mgreene</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://whitepigeondesign.com/?p=135</guid>
		<description><![CDATA[<p>Categories are easy to use extensions for the Objective-C language that allow you to write additional functionality to existing classes.  They are easy to write, easily customizable, can be used between applications and they allow you to remove your code from your applications implementation (.m) files. This makes your code cleaner and easier to bug fix.</p>
<p>While <span style="color:#777"> . . . &#8594; Read More: <a href="http://whitepigeondesign.com/2010/09/27/text-validation-category/">Text Validation Category</a></span>]]></description>
			<content:encoded><![CDATA[<p>Categories are easy to use extensions for the Objective-C language that allow you to write additional functionality to existing classes.  They are easy to write, easily customizable, can be used between applications and they allow you to remove your code from your applications implementation (.m) files. This makes your code cleaner and easier to bug fix.</p>
<p>While writing an application that used a UITextField it became clear that we needed a method for text validation.  Neither the UITextField nor the UITextFieldDelegate protocols provide any text validation methods.  In order to address text validation we needed to access the UITextField and UITextFieldDelegate methods and write validation methods.  We originally wrote all of our validation methods this way but soon found limitations. Specifically this approach is not easy to implement, is not easy to utilize between applications, is not easy to scale and is not easy to troubleshoot or bug find.</p>
<p>In order to addresses these shortcomings, we determined that a NSString category would be the easiest and most functional method to use.  Additionally, using a category reduced our validation code to a one line call within our UITextFieldDelegate.  The returned result is then assessed using a switch statement in order to address the validation outputs.</p>
<p>The text validation example that we were working with was for image files and we determined that the validation items of interest were:</p>
<ul>
<li>Format of the text &#8211; We wanted to make sure that the text started with a character other than a period.</li>
<li>Multiple use of periods &#8211; We wanted to make sure that the text did not include more than one period.</li>
<li>Proper image suffix use &#8211; We wanted to make sure that the images ended with a .jpg, .jpeg or .png.</li>
</ul>
<p>We started the category by writing a typedef enum statement that declared our error codes as integer values.  This allowed us to write a category method that returned a integer value based on the error returned.  We found this method helpful in that it allowed us to easily write  new error codes, write the validation code and utilize the output in a scalable approach.  If our validation method returns any error codes that we are not interested in, than we can ignore that entry in our applications code.</p>
<p style="text-align: left;"><strong><span style="text-decoration: underline;">Category Files</span></strong><br />
TextValidationMethods.h</p>
<pre>
<div style="padding: 2px 6px 4px 6px; height: 300px; overflow: auto; color: #555555; background-color: #eeeeee; border: #dddddd 2px solid;"><code>//
//  TextValidationMethods.h
//  TextEntry
//
//  Created by Mike Greene on 8/1/10.
//  Copyright 2010 White Pigeon Design. All rights reserved.
//

typedef enum{
	kTextValidationErrorNone,
	kTextValidationErrorNoValue,
	kTextValidationErrorStartsWithPeriod,
	kTextValidationErrorMultiplePeriodsUsed,
	kTextValidationErrorNoPeriodImageSuffix,
	kTextValidationErrorNoImageSuffix,
	kTextValidationErrorIncorrectImageSuffix
}MGTextError;	

#import 

@interface NSString (TextValidationMethods)

-(int)validateTextEntry:(NSString *)inputTextString;

@end</code></div>
</pre>
<p>TextValidationMethods.m</p>
<pre>
<div style="padding: 2px 6px 4px 6px; height: 300px; overflow: auto; color: #555555; background-color: #eeeeee; border: #dddddd 2px solid;"><code>//
//  TextValidationMethods.m
//  TextEntry
//
//  Created by Mike Greene on 8/1/10.
//  Copyright 2010 White Pigeon Design. All rights reserved.
//

#import "TextValidationMethods.h"

@implementation NSString (TextValidationMethods)

-(int)validateTextEntry:(NSString *)inputTextString{

	int textCount = [inputTextString length];

	if (textCount==0) { //Test to see if any values have been entered.  If no values, stop.
		return 	kTextValidationErrorNoValue;//No value present
	}

	else{ //Continue, values have been entered

		if ([inputTextString hasPrefix:@"."] ==YES) {//test to see if the first charater entered is a period.
			return kTextValidationErrorStartsWithPeriod;
		}
		else{//Loop through the entered text and determine if more than one period is used.
			//If more than one period is entered, set alert and ask to redo
			int n;
			int periodRangeInteger =0;
			for (n=0; n&amp;lt;[inputTextString length]; n++) { 				NSString *nString = [NSString stringWithFormat:@"%C", [inputTextString characterAtIndex:n]]; 				NSRange periodRange = [nString rangeOfString:@"."]; 				 				if (periodRange.length ==1) {//Use to increment the periodRangeInteger every time that a period is identified 					periodRangeInteger ++; 				} 			} 			 			if (periodRangeInteger &amp;gt;1) {//More than one period is used
				return kTextValidationErrorMultiplePeriodsUsed;
			}

			else if (periodRangeInteger == 0) {//No periods are used  

				if ([inputTextString hasSuffix:@".jpg"]==YES || [inputTextString hasSuffix:@".jpeg"]==YES) {//test to see if the file name includes .jpg or .jpeg
					return kTextValidationErrorNone;//No Error
				}
				else {//No periods and no image suffixs are used
					return kTextValidationErrorNoPeriodImageSuffix;//No period or image suffix
				}

			}
			else if (periodRangeInteger ==1){//One period Used

				if ([inputTextString hasSuffix:@"jpg"]==YES || [inputTextString hasSuffix:@"jpeg"]==YES) {//test to see if the file name includes jpg or jpeg

					if ([inputTextString hasSuffix:@".jpg"]==YES || [inputTextString hasSuffix:@".jpeg"]==YES) {//Confirm that the filename has a period and the correct suffix
						return kTextValidationErrorNone;//No Error
					}
					else {//One period is used, however the appropriate image suffixes are not found (.jpgjpg or .jpgjpeg)
						return kTextValidationErrorIncorrectImageSuffix;//No period or image suffix
					}
				}

				else {
					return kTextValidationErrorNoImageSuffix;//No image suffix
				}

			}
		}
	}

	return kTextValidationErrorNone;
}

@end</code></div>
</pre>
<p><strong><span style="text-decoration: underline;">Directions For Use</span></strong></p>
<ol>
<li>Copy the included category files (TextValidationMethods.h and TextValidationMethods.m).</li>
<li>Copy the NSString category .h and .m files into your project.</li>
<li>Add  <code>#import "TextValidationMethods.h"</code> to the top of the interface file that you will be using the validation methods in.</li>
<li>Within the method that you would like to test the validation call<code> someInteger = [textField.text validateTextEntry:textField.text]; </code></li>
<li>Use the integer value from the validation call to write a switch argument to account for all of the potential error codes.</li>
</ol>
<p>I would appreciate any helpful input or additions to this post.<br />
Thanks,<br />
Mike</p>
]]></content:encoded>
			<wfw:commentRss>http://whitepigeondesign.com/2010/09/27/text-validation-category/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

