0

I would like to create a function that looks at a string, and if it's a decimal string, returns it as a currency-formatted string. The function below does that, however if I pass in a string that is already formatted, it will fail of course (it expects to see a string like '25' or '25.55' but not '$15.25'

Is there a way to modify my function below to add another if condition that says "if you've already been formatted as a currency string, or your string is not in the right format, return X" (maybe X will be 0, or maybe it will be self (the same string) i'm not sure yet).

func toCurrencyStringFromDecimalString() -> String
{
    var numberFormatter = NSNumberFormatter()
    numberFormatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle

    if (self.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet()).utf16Count == 0)
    {
        //If whitespace is passed in, just return 0.0 as default
        return numberFormatter.stringFromNumber(NSDecimalNumber(string: "0.0"))!
    }
    else if (IS_NOT_A_DECIMAL_OR_ALREADY_A_CURRENCY_STRING)
    {
        //So obviously this would go here to see if it's not a decimal (or already contains a current placeholder etc)
    }
    else
    {
        return numberFormatter.stringFromNumber(NSDecimalNumber(string: self))!
    }
}

Thank you for your help!

NullHypothesis
  • 4,286
  • 6
  • 37
  • 79

1 Answers1

3

Sounds like you need to use NSScanner.

According to the docs, the scanDecimal function of NSScanner:

Skips past excess digits in the case of overflow, so the receiver’s position is past the entire integer representation.

Invoke this method with NULL as value to simply scan past a decimal integer representation.

I've been mostly programming in Obj-C so my Swift is rubbish, but here's my attempt at translating the appropriate code for detecting numeric strings (as also demonstrated in this answer):

let scanner: NSScanner = NSScanner(string:self)
let isNumeric = scanner.scanDecimal(nil) && scanner.atEnd

If the string is not a decimal representation, isNumeric should return false.

Community
  • 1
  • 1
Lyndsey Scott
  • 37,080
  • 10
  • 92
  • 128
  • This was such a helpful, well put-together answer Lyndsey. thanks for your help in getting me through this. :) – NullHypothesis Oct 25 '14 at 18:21
  • 1
    It's easier (and IMO better) to use `nil` here instead of `UnsafeMutablePointer.null()`. Search for "Mutable Pointers" in the "Interacting with C APIs" page for an explanation. https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithCAPIs.html – Rob Napier Oct 25 '14 at 22:04
  • @RobNapier OK, cool. "nil" wasn't working at first, but works now. I'll make the update. Thanks! – Lyndsey Scott Oct 25 '14 at 22:07
  • 2
    Yeah; the APIs throwing all those "UnsafeMutablePointer" things around is kind of confusing. Most of the time you really should be passing `&x` to them, not generating unsafe pointers. Hopefully the headers and docs improve! – Rob Napier Oct 25 '14 at 22:08