Showing posts tagged mac

A phone number formatting category on NSString

Actually, all the credit goes to Ahmed Abdelkader for this code. All I did was stick it in an easy-to-use category.

This work is licensed under a Creative Commons Attribution 3.0 License which basically means you can use it free for any purpose as long as you give proper attribution.

NSString+PhoneNumberFormatting.m

//
//  NSString+PhoneNumberFormatting.m
//
//  Created by Mike Manzano on 7/28/11.
//
//	This work is licensed under a Creative Commons Attribution 3.0 License.
//
//	Adapted from work by Ahmed Abdelkader on 1/22/10, whose work is
//  licensed under a Creative Commons Attribution 3.0 License.
//	http://the-lost-beauty.blogspot.com/2010/01/locale-sensitive-phone-number.html

#import 

// Supported locales
extern NSString *xPhoneNumberLocale_US ;
extern NSString *xPhoneNumberLocale_UK ;
extern NSString *xPhoneNumberLocale_JP;

@interface NSString (PhoneNumberFormatting)
- (NSString *)formattedPhoneNumberForLocale:(NSString *)xPhoneNumberLocale ;
@end

NSString+PhoneNumberFormatting.m

//
//  NSString+PhoneNumberFormatting.m
//
//  Created by Mike Manzano on 7/28/11.
//
//	This work is licensed under a Creative Commons Attribution 3.0 License.
//
//	Adapted from work by Ahmed Abdelkader on 1/22/10, whose work is
//  licensed under a Creative Commons Attribution 3.0 License.
//	http://the-lost-beauty.blogspot.com/2010/01/locale-sensitive-phone-number.html


#import "NSString+PhoneNumberFormatting.h"

NSString *xPhoneNumberLocale_US = @"us" ;
NSString *xPhoneNumberLocale_UK = @"uk" ;
NSString *xPhoneNumberLocale_JP = @"jp" ;


@implementation NSString (PhoneNumberFormatting)

+ (NSDictionary *) sharedPhoneFormats
	{
	static NSDictionary *formats = nil ;
	
	static dispatch_once_t onceToken;
	dispatch_once(&onceToken, ^{
		NSArray *usPhoneFormats = [NSArray arrayWithObjects:
								   @"+1 (###) ###-####",
								   @"1 (###) ###-####",
								   @"011 $",
								   @"###-####",
								   @"(###) ###-####", nil];
		
		NSArray *ukPhoneFormats = [NSArray arrayWithObjects:
								   @"+44 ##########",
								   @"00 $",
								   @"0### - ### ####",
								   @"0## - #### ####",
								   @"0#### - ######", nil];
		
		NSArray *jpPhoneFormats = [NSArray arrayWithObjects:
								   @"+81 ############",
								   @"001 $",
								   @"(0#) #######",
								   @"(0#) #### ####", nil];
		
		formats = [[NSDictionary alloc] initWithObjectsAndKeys:
							 usPhoneFormats, xPhoneNumberLocale_US,
							 ukPhoneFormats, xPhoneNumberLocale_UK,
							 jpPhoneFormats, xPhoneNumberLocale_JP,
							 nil];
		});
	
	return formats ;
	}


- (BOOL)canBeInputByPhonePad:(char)c 
	{
	if(c == '+' || c == '*' || c == '#') return YES;
	if(c >= '0' && c <= '9') return YES;
	return NO;
	}

// Strips out invalid characters
- (NSString *)strip:(NSString *)phoneNumber 
	{
	NSMutableString *res = [[[NSMutableString alloc] init] autorelease];
	for(int i = 0; i < [phoneNumber length]; i++) 
		{
		char next = [phoneNumber characterAtIndex:i];
		if([self canBeInputByPhonePad:next])
			[res appendFormat:@"%c", next];
		}
	return res;
	}


- (NSString *)formattedPhoneNumberForLocale:(NSString *)xPhoneNumberLocale 
	{
	NSString *phoneNumber = self ;
	NSArray *localeFormats = [[NSString sharedPhoneFormats] objectForKey:xPhoneNumberLocale];
	if(localeFormats == nil) return phoneNumber;
	NSString *input = [self strip:phoneNumber];
	for(NSString *phoneFormat in localeFormats) 
		{
		int i = 0;
		NSMutableString *temp = [[[NSMutableString alloc] init] autorelease];
		for(int p = 0; temp != nil && i < [input length] && p < [phoneFormat length]; p++) 
			{
			char c = [phoneFormat characterAtIndex:p];
			BOOL required = [self canBeInputByPhonePad:c];
			char next = [input characterAtIndex:i];
			switch(c) 
				{
				case '$':
					p--;
					[temp appendFormat:@"%c", next]; i++;
					break;
				case '#':
					if(next < '0' || next > '9') 
						{
						temp = nil;
						break;
						}
					[temp appendFormat:@"%c", next]; i++;
					break;
				default:
					if(required) 
						{
						if(next != c) 
							{
							temp = nil;
							break;
							}
						[temp appendFormat:@"%c", next]; i++;
						} 
					else 
						{
						[temp appendFormat:@"%c", c];
						if(next == c) i++;
						}
				break;
				}
			} // build temp loop
		if(i == [input length]) 
			{
			return temp;
			}
		} // for each format
	return input;
	}
@end