How to convert an NSString into an NSNumber

425,781

Solution 1

Use an NSNumberFormatter:

NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
f.numberStyle = NSNumberFormatterDecimalStyle;
NSNumber *myNumber = [f numberFromString:@"42"];

If the string is not a valid number, then myNumber will be nil. If it is a valid number, then you now have all of the NSNumber goodness to figure out what kind of number it actually is.

Solution 2

You can use -[NSString integerValue], -[NSString floatValue], etc. However, the correct (locale-sensitive, etc.) way to do this is to use -[NSNumberFormatter numberFromString:] which will give you an NSNumber converted from the appropriate locale and given the settings of the NSNumberFormatter (including whether it will allow floating point values).

Solution 3

Objective-C

(Note: this method doesn't play nice with difference locales, but is slightly faster than a NSNumberFormatter)

NSNumber *num1 = @([@"42" intValue]);
NSNumber *num2 = @([@"42.42" floatValue]);

Swift

Simple but dirty way

// Swift 1.2
if let intValue = "42".toInt() {
    let number1 = NSNumber(integer:intValue)
}

// Swift 2.0
let number2 = Int("42')

// Swift 3.0
NSDecimalNumber(string: "42.42") 

// Using NSNumber
let number3 = NSNumber(float:("42.42" as NSString).floatValue)

The extension-way This is better, really, because it'll play nicely with locales and decimals.

extension String {
    
    var numberValue:NSNumber? {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        return formatter.number(from: self)
    }
}

Now you can simply do:

let someFloat = "42.42".numberValue
let someInt = "42".numberValue

Solution 4

For strings starting with integers, e.g., @"123", @"456 ft", @"7.89", etc., use -[NSString integerValue].

So, @([@"12.8 lbs" integerValue]) is like doing [NSNumber numberWithInteger:12].

Solution 5

You can also do this:

NSNumber *number = @([dictionary[@"id"] intValue]]);

Have fun!

Share:
425,781
Enyra
Author by

Enyra

Updated on August 21, 2021

Comments

  • Enyra
    Enyra over 2 years

    How can I convert a NSString containing a number of any primitive data type (e.g. int, float, char, unsigned int, etc.)? The problem is, I don't know which number type the string will contain at runtime.

    I have an idea how to do it, but I'm not sure if this works with any type, also unsigned and floating point values:

    long long scannedNumber;
    NSScanner *scanner = [NSScanner scannerWithString:aString];
    [scanner scanLongLong:&scannedNumber]; 
    NSNumber *number = [NSNumber numberWithLongLong: scannedNumber];
    

    Thanks for the help.

  • hansvb
    hansvb over 12 years
    +q Depending on the situation, non-locale-sensitive might actually be the correct way.
  • Besi
    Besi about 12 years
    I had to convert @"2000" to an int and [@"2000" integerValue] worked nicely and is a little simpler for my case.
  • acecapades
    acecapades over 11 years
    this doesn't work for me. I'm developing for 5.0 with xcode 4.3.2. any ideas why?
  • pille
    pille over 11 years
    For people where it doesn't seem to work: Check if it's related to your locale. The NSNumberFormatter (as far as I know) by default uses the US locale, i.e. expects the decimal separator to be the "." character. If you use "," to separate the fraction, you may need to tell the formatter to use your current locale: [f setLocale:[NSLocale currentLocale]];
  • Dave DeLong
    Dave DeLong over 11 years
    @pille by default the locale is the +currentLocale, but you're correct; one must always consider the locale when dealing with converting stuff to-and-from human-readable form.
  • Tom Andersen
    Tom Andersen almost 11 years
    There are also huge performance differences among these methods.
  • androider
    androider about 10 years
    I prefer this based on profiling when I was parsing a large amount of string values. Using this syntax rather then an NSNumberFormatter led to significant reduction in time spent parsing the string to NSNumber. And yes the NSNumberFormatter was cached and reused.
  • learner
    learner over 9 years
    this does not work with ARC: it won't convert NSInteger to NSNumber. I have to further use [NSNumber numberWithInteger ...]
  • Chris
    Chris over 9 years
    this literal syntax didn't exist when this question was asked. I'd say this is the correct answer nowadays though.
  • Kevin R
    Kevin R over 9 years
    I agree, but do note that some other countries use the , and . the other way around (eg 42.000,42. Something floatValue probably does not account for?
  • FabKremer
    FabKremer about 9 years
    This doesn't convert the NSInteger to a NSNumber. It converts it to a double.
  • Stoff81
    Stoff81 almost 9 years
    This is the nicest solution on here, however I have just run a test and you will lose unsigned precision so WATCH OUT!!!
  • allaire
    allaire almost 9 years
    Where did you find that it was currentLocale by default? I can confirm that numberFromString is using dot notation even on a French phone where comma is used. I can confirm that by default, when you output a number, it uses the current locale by default
  • aroth
    aroth about 8 years
    What @Thilo said. "Correct" and "locale-sensitive" are not synonyms. The correct thing to do actually depends upon how the number got into the string in the first place. If you read it from user input, then local-sensitive is what you want. From any other source (i.e. you put it there programmatically, you're consuming it as part of the response from some external API, etc.) local-sensitive is not appropriate and could even give incorrect results.
  • GeneCode
    GeneCode over 7 years
    But what if the string can contain either int or float?
  • Chuck Krutsinger
    Chuck Krutsinger over 6 years
    In my use case, I needed to get an NSNumber dictionary key from an NSString, so @([@"42" intValue]) worked perfectly. Not worried about Locale.
  • Motti Shneor
    Motti Shneor over 3 years
    have you read the question? you're to provide an NSNumber instance (an Objective-C object) not an int primitive.