Does Nsnumberformatter.Stringfromnumber Ever Return Nil

Does NSNumberFormatter.stringFromNumber ever return nil?

My best guess would be because of the legacy support. This is from the official documentation:

The behavior of an NSNumberFormatter object can conform either to the range of behaviors existing prior to OS X v10.4 or to the range of behavior since that release.
NSNumberFormatter Class Reference

Why does NumberFormatter's string(from:) return an optional?

There's an ancient (2002) response on the Apple mailing list which might partially answer your question:

The strange behavior isn't NSNumber -- NSNumber -stringValue seems to be returning results one would expect. It's NSNumberFormatter which is returning unusual results.

The abstract problem here is that NSNumberFormatter was originally written to handle money amounts for EOF, so it doesn't deal with unusual numbers well (or general purpose string formatting for that matter).

The more concrete problem is that when you ask an NSNumberFormatter for -stringForObjectValue:, if the object is not an NSDecimalNumber, it converts it to an NSDecimalNumber using
[NSDecimalNumber decimalNumberWithString:[objectValue stringValue]]
which is not going to handle unusual values well, in addition to potentially other issues. A further issue, though I don't know this is the case, is that I don't think there is an NSDecimal (the struct) representation of positive and negative infinity, as there is for NaN.

I don't actually understand that response enough to say that it's why an optional is returned, but I suspect it's related.

There's example code in the original question, but none of it returns a nil, it always gives a string.

NSNumberFormatter.numberFromString() returns nil for ar-SA locale

You can convert the number to "en" locale and after that you convert the resulting string to "ar_SA" locale. Apparently, the "ar_SA" locale does not recognize the "e" notation.

let format = NSNumberFormatter()
format.numberStyle = NSNumberFormatterStyle.DecimalStyle
format.locale = NSLocale(localeIdentifier: "en")
format.maximumFractionDigits = 16

var result = displayText.text!
guard let number = format.numberFromString(result), let string = format.stringFromNumber(number) else {
return
}

format.locale = NSLocale(localeIdentifier: "ar_SA")
guard let string2 = format.stringFromNumber(number) else {
return
}
result = string2

NSNumberFormatter numberFromString returns null

What is price? Assuming it's an ivar, do not access ivars directly. Always use accessors except in dealloc and init.

Assuming price is a string, why are you doing this:

[NSString stringWithFormat:@"%@", price]

If price is an NSNumber, then you can use it directly.

You're creating an NSNumber here, assigning it to amount, and then immediately throwing it away. You then over-release amount. So you should expect the above code to crash. (Because of a quirk in how NSNumber objects are managed, this crash will happen the next time you create an NSNumber for the integer 5.)

And getting all the way around to your actual question, the reason amount is nil is because "5" is not in the current currency format, so the number formatter rejected it. If you are in the US and set price to "$5.00" then it would work.


If you're really trying to convert a string to US$, then this is how to do it. Note that locale matters here. If you use the default locale, then in France "1.25" will be €1.25, which is not the same as $1.25.

You should always us NSDecimalNumber when holding currancy. Otherwise you're subject to binary/decimal rounding errors.

The following uses ARC.

NSString *amountString = @"5.25";
NSDecimalNumber *amountNumber = [NSDecimalNumber decimalNumberWithString:amountString];
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];

NSNumberFormatter *currencyStyle = [[NSNumberFormatter alloc] init];
[currencyStyle setNumberStyle:NSNumberFormatterCurrencyStyle];
[currencyStyle setLocale:locale];
NSString *currency = [currencyStyle stringFromNumber:amountNumber];

NSLog(@"%@", currency);

A more complete class for managing localized currency (RNMoney) is available in the example code for chapter 13 of iOS 5 Programming Pushing the Limits.



Related Topics



Leave a reply



Submit