Re: NSNumberFormatter not working for me ?
Re: NSNumberFormatter not working for me ?
- Subject: Re: NSNumberFormatter not working for me ?
- From: Bill Hernandez <email@hidden>
- Date: Wed, 14 Apr 2010 14:45:04 -0500
On Apr 14, 2010, at 1:04 PM, Murat Konar wrote:
> Actually, setting the formatter behavior does work (it does allow you to use setFormat: to set a format string). The remaining problem is that I don't think NSNumberFormatter allows the arbitray digit-by-digit formatting of numbers that you expect.
>
> _murat
murat,
Thank You for your effort...
The result that setting :
[NSNumberFormatter setDefaultFormatterBehavior:NSNumberFormatterBehavior10_0];
is shown on the next line, hardly what one would expect ?
> (1234567890) -
I've worked with lots of number formatters over the years, and that is what they do, format numbers into strings, any kind of string...
I looked at the header file for NSNumberFormatter, and there seem to be 9,000,000+ methods, it is amazing. Buried in there, there has to be a simple way to format a string, that I am overlooking ?
If you look the simple formatter I wrote up last night, it will format a string digits any way imaginable.
I just ran the little test app I created last night and you can see the results below :
I use 'strippedNumber', because by the time I call this routine all the junk non-digits have been stripped out...
Bill Hernandez
Plano, Texas
I created a simple NSTextView that the output gets sent to:
IBOutlet NSTextView *mainTextView;
CALLED :
NSString *phoneNumber;
phoneNumber = [BHUtility bhFormatNumberString:strippedNumber withFormat:format];
[4751]
strippedNumber = @"1234567890"
format = @"(###) ###-####"
result = @"(123) 456-7890"
[4752]
strippedNumber = @"1234567890"
format = @"###.###.####"
result = @"123.456.7890"
[4753]
strippedNumber = @"1234567890"
format = @"<[###.###.####]>"
result = @"<[123.456.7890]>"
[4754]
strippedNumber = @"12345678909889"
format = @"(###) ###-#### [extension ####]"
result = @"(123) 456-7890 [extension 9889]"
[4755]
strippedNumber = @"12345678909889"
format = @"Weekends : (###) ###-#### [extension ####]"
result = @"Weekends : (123) 456-7890 [extension 9889]"
[4756]
strippedNumber = @"12345678909889"
format = @"Social Security : ###-##-###"
result = @"Social Security : 123-45-678"
You can see on the line above, that if the user enters more digits, than the format requires, the method simply skips the rest. This could be good and bad, but you can trap for that ahead of time...
I would think the Apple Engineers could have come up with one more method, and had 9,000,001 in the class as a last resort. I bet the answer is in that class, I just can't find it, and I don't know enough Cocoa to come out of the rain. I am sure an answer will turn up...
I also understand that I don't have big time error checking. and for me, this only has to work in a very limited scope, and does not need to be as robust as what comes from the factory. All that having been said, the work-around works really slick...
I am sure that I am just overlooking something really simple, but I can't figure out what it is...
// +---------+---------+---------+---------+---------+---------+---------+---------+
// BHUtility.h
// Formatter
//
// Created by Bill Hernandez on 4/13/2010.
// +---------+---------+---------+---------+---------+---------+---------+---------+
#import <Cocoa/Cocoa.h>
#import "RegexKitLite.h" // Not required for this demo, you can comment it out
@interface BHUtility : NSObject
{
}
// +---------+---------+---------+---------+---------+---------+---------+---------+
// [4827] ( BEGIN ) Working with Strings
// +---------+---------+---------+---------+---------+---------+---------+---------+
/*
* THIS METHOD DOES NOT WORK, NOTICE IT HAS BEEN RENAMED AS UNUSABLE (FOR NOW)
*
* I left it here in case NSNumberFormatter and setFormat ever work in this area
* I couldn't figure out how to make it work, so I came up with a great work-around
* at least in my opinion, doesn't sound very humble, I apologize for that...
*
* But in reality, it is a heck of a lot easier than using NSNumberFormatter, and
* that's a fact...
*/
+ (NSString *)unusable_bhFormatNumberString:(NSString *)aNumberString
withFormat:(NSString *)aFormat;
// +---------+---------+---------+---------+---------+---------+---------+---------+
/*
* THIS IS THE MAIN NUMBER FORMATTER
*
* A less cryptic Objective CLike method, does the same as below,
* this is more for the mere mortal Objective C afficionado...
*/
+ (NSString *)bhFormatNumberString:(NSString *)aNumberString
withFormat:(NSString *)aFormat;
// +---------+---------+---------+---------+---------+---------+---------+---------+
/*
* A more cryptic CLike method, does the same as above, but
* is easier to read for the C afficionado...
*
* for the people that don't like long variable names, I failed in a way though,
* since I didn't use any bufptr(s), even so it's a little less descriptive
*/
+ (NSString *)bhFormatNumberStringButMoreCLike:(NSString *)aNumberString
withFormat:(NSString *)aFormat;
// +---------+---------+---------+---------+---------+---------+---------+---------+
@end
// +---------+---------+---------+---------+---------+---------+---------+---------+
// BHUtility.m
// Formatter
//
// Created by Bill Hernandez on 4/13/2010.
// +---------+---------+---------+---------+---------+---------+---------+---------+
#import "BHUtility.h"
@implementation BHUtility
// +---------+---------+---------+---------+---------+---------+---------+---------+
/*
* THIS METHOD DOES NOT WORK, NOTICE IT HAS BEEN RENAMED AS UNUSABLE (FOR NOW)
*
* I left it here in case NSNumberFormatter and setFormat ever work in this area
* I couldn't figure out how to make it work, so I came up with a great work-around
* at least in my opinion, doesn't sound very humble, I apologize for that...
*
* But in reality, it is a heck of a lot easier than using NSNumberFormatter, and
* that's a fact...
*/
+ (NSString *)unusable_bhFormatNumberString:(NSString *)aNumberString
withFormat:(NSString *)aFormat
{
// THIS METHOD DOES NOT WORK, WITH OR WITHOUT THE NEXT LINE
// YIELDS INCORRECT RESULTS : @"(1234567890) -"
[NSNumberFormatter setDefaultFormatterBehavior:NSNumberFormatterBehavior10_0];
NSNumberFormatter *numberFormatter = [[[NSNumberFormatter alloc] init] autorelease];
// NSFormatter *numberFormatter = [[[NSNumberFormatter alloc] init] autorelease];
[numberFormatter setFormat:aFormat]; // specify just positive values format
NSUInteger theInt = [aNumberString intValue];
NSNumber *theNum = [NSNumber numberWithInt:theInt];
NSString *theString = (NSString *)[numberFormatter stringFromNumber:theNum];
NSLog(@"[4625] theString = %@", theString);
return theString;
// +---------+---------+---------+---------+---------+---------+---------+---------+
}
// +---------+---------+---------+---------+---------+---------+---------+---------+
/*
* THIS IS THE MAIN NUMBER FORMATTER
*
* A less cryptic Objective CLike method, does the same as below,
* this is more for the mere mortal Objective C afficionado...
*/
+ (NSString *)bhFormatNumberString:(NSString *)aNumberString
withFormat:(NSString *)aFormat
{
NSString *myFormatString = [[[NSString stringWithString:aFormat] copy] autorelease];
NSUInteger myFormatStringLength = [myFormatString length];
NSMutableString *returnString = [[[NSMutableString alloc] initWithCapacity:myFormatStringLength] autorelease];
NSUInteger i = 0; // i represents the myFormatString character position/counter through the loop
NSUInteger aNumberStringPosition = 0;
unichar myUniChar;
for ( i = 0; i < myFormatStringLength; i ++ )
{
myUniChar = [myFormatString characterAtIndex:i];
// NSLog (@"[4525] i = %i: myUniChar = %C\n", i, myUniChar);
if (myUniChar == '#')
{
// aNumberStringPosition += 1;
// previous line not needed, incremented on next line ( aNumberStringPosition++ )
myUniChar = [aNumberString characterAtIndex:aNumberStringPosition++];
}
[returnString appendFormat:@"%C",myUniChar];
}
NSLog(@"[4626] returnString = %@", returnString);
return returnString;
}
// +---------+---------+---------+---------+---------+---------+---------+---------+
// A more cryptic CLike method, does the same as above, but
// is easier to read for the C afficionado...
// +---------+---------+---------+---------+---------+---------+---------+---------+
+ (NSString *)bhFormatNumberStringButMoreCLike:(NSString *)aNumberString
withFormat:(NSString *)aFormat
{
// formatString
NSString * fs = [[[NSString stringWithString:aFormat] copy] autorelease];
NSUInteger fsLen = [ fs length];
// returnString
NSMutableString *rs = [[[NSMutableString alloc] initWithCapacity: fsLen] autorelease];
// Counters
NSUInteger i = 0; // i represents the fs character position/counter through the loop
NSUInteger nsCounter = 0;
unichar uc;
for ( i = 0; i < fsLen; i ++ )
{
uc = [ fs characterAtIndex:i];
if (uc == '#') { uc = [aNumberString characterAtIndex:nsCounter++]; }
[rs appendFormat:@"%C", uc];
}
NSLog(@"[4650] rs = %@", rs);
return rs;
}
// +---------+---------+---------+---------+---------+---------+---------+---------+
@end
// +---------+---------+---------+---------+---------+---------+---------+---------+
// BHFormatter.h
// Formatter
//
// Created by Bill Hernandez on 4/13/10.
// +---------+---------+---------+---------+---------+---------+---------+---------+
#import <Cocoa/Cocoa.h>
@interface BHFormatter : NSObject
{
IBOutlet NSTextView *mainTextView;
}
@property (nonatomic, retain) IBOutlet NSTextView *mainTextView;
@end
// +---------+---------+---------+---------+---------+---------+---------+---------+
// BHFormatter.m
// Formatter
//
// Created by Bill Hernandez on 4/13/2010.
// +---------+---------+---------+---------+---------+---------+---------+---------+
#import "BHFormatter.h"
#import "BHUtility.h"
@implementation BHFormatter
@synthesize mainTextView;
// +---------+---------+---------+---------+---------+---------+---------+---------+
- (void)awakeFromNib
{
// I have already run a routine to strip all non digits by this time
NSString *strippedNumber = @"1234567890";
NSString *phoneNumber;
BOOL useFormatter = YES;
if(useFormatter)
{
NSString *result;
NSString *format;
[mainTextView insertText:@"\nCALLED :\nNSString *phoneNumber;\nphoneNumber = [BHUtility bhFormatNumberString:strippedNumber withFormat:format];\n\n"];
format = @"(###) ###-####";
phoneNumber = [BHUtility bhFormatNumberString:strippedNumber withFormat:format];
result = [NSString stringWithFormat:@"[4751]\nstrippedNumber = @\"%@\"\nformat = @\"%@\"\nresult = @\"%@\"\n\n", strippedNumber, format, phoneNumber];
[mainTextView insertText:result];
format = @"###.###.####";
phoneNumber = [BHUtility bhFormatNumberString:strippedNumber withFormat:format];
result = [NSString stringWithFormat:@"[4752]\nstrippedNumber = @\"%@\"\nformat = @\"%@\"\nresult = @\"%@\"\n\n", strippedNumber, format, phoneNumber];
[mainTextView insertText:result];
format = @"<[###.###.####]>";
phoneNumber = [BHUtility bhFormatNumberString:strippedNumber withFormat:format];
result = [NSString stringWithFormat:@"[4753]\nstrippedNumber = @\"%@\"\nformat = @\"%@\"\nresult = @\"%@\"\n\n", strippedNumber, format, phoneNumber];
[mainTextView insertText:result];
strippedNumber = @"12345678909889"; // notice this is 14 digits long now
if([strippedNumber length] == 14)
{
format = @"(###) ###-#### [extension ####]";
phoneNumber = [BHUtility bhFormatNumberString:strippedNumber withFormat:format];
result = [NSString stringWithFormat:@"[4754]\nstrippedNumber = @\"%@\"\nformat = @\"%@\"\nresult = @\"%@\"\n\n", strippedNumber, format, phoneNumber];
[mainTextView insertText:result];
format = @"Weekends : (###) ###-#### [extension ####]";
phoneNumber = [BHUtility bhFormatNumberString:strippedNumber withFormat:format];
result = [NSString stringWithFormat:@"[4755]\nstrippedNumber = @\"%@\"\nformat = @\"%@\"\nresult = @\"%@\"\n\n", strippedNumber, format, phoneNumber];
[mainTextView insertText:result];
format = @"Social Security : ###-##-###";
phoneNumber = [BHUtility bhFormatNumberString:strippedNumber withFormat:format];
result = [NSString stringWithFormat:@"[4756]\nstrippedNumber = @\"%@\"\nformat = @\"%@\"\nresult = @\"%@\"\n\n", strippedNumber, format, phoneNumber];
[mainTextView insertText:result];
}
else
{
phoneNumber = strippedNumber;
}
}
else
{
// THIS IS NOT VERY FLEXIBLE
if([strippedNumber length] == 10)
{
NSString *areacode = [strippedNumber substringWithRange:NSMakeRange(0, 3)];
NSString *exchange = [strippedNumber substringWithRange:NSMakeRange(3, 3)];
NSString *number = [strippedNumber substringWithRange:NSMakeRange(6, 4)];
phoneNumber = [NSString stringWithFormat:@"(%@) %@-%@", areacode, exchange, number];
}
else
{
phoneNumber = strippedNumber;
}
}
// NSLog(@"[4626] phoneNumber = %@", phoneNumber);
}
// +---------+---------+---------+---------+---------+---------+---------+---------+
@end
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden