iosstringswiftnsnumberformatterstringwithformat

In Swift, how to insert formatted Int value into String?


This seems like a super basic question, but I just can't seem to find the answer anywhere :-( I am able to do this in Objective C, but I am getting stuck in Swift.

What I need to do:

  1. Take an Integer value
  2. Format it into a localized string
  3. Inject the value into another string using the stringWithFormat equivalent method (since the other string is localized as well, which is not shown in simplified examples below)

How it's easily done in Objective C -- this works:

    // points is of type NSNumber *

    NSNumberFormatter *formatter = [NSNumberFormatter new];
    formatter.locale             = [NSLocale currentLocale];
    formatter.numberStyle        = NSNumberFormatterDecimalStyle;

    NSString *ptsString = [formatter stringFromNumber:points];
    NSString *message   = [NSString stringWithFormat:@"You've earned %@ points", ptsString];

My best attempt at doing this in Swift -- compiler error on last line:

    // points is of type Int

    let formatter         = NSNumberFormatter()
    formatter.locale      = NSLocale.currentLocale()
    formatter.numberStyle = NSNumberFormatterStyle.DecimalStyle

    let ptsString = formatter.stringFromNumber(points)!
    let message   = String(format: "You've earned %@ points", arguments: ptsString)

I'm getting the following error in Xcode on that last line:

"Cannot convert value of type 'String' to expected argument type '[CVarArgType]'"

(In my actual code, the message into which I want to insert the points value is itself localized as well, but I have simplified this example, as I'm getting the exact same error in both cases.)

What am I missing here..?

Thanks so much for any help,

Erik


Solution

  • You need to wrap the arguments in a collection. Like this:

    let message   = String(format: "You've earned %@ points", arguments: [ptsString])
    

    You can also use this method:

    let message   = "You've earned \(ptsString) points"
    

    Additionally you can create an extension method to do this:

    extension String {
        func format(_ parameters: CVarArg...) -> String {
            return String(format: self, arguments: parameters)
        }
    }
    

    Now you can do this:

    let message = "You've earned %@ points".format("test")
    let message2params = "You've earned %@ points %@".format("test1", "test2")