Expand All Room Types in Swift

Let's say that I have something like this:

extension NSNumber{
    func toLocalCurrency(fractDigits:Int = 2)->String{
        let formatter = NSNumberFormatter()
        formatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle
        let userSettings:UserInfo? = UserInfo.first(sortDescriptors: nil, context: AERecord.defaultContext) as? UserInfo
        if let code = userSettings?.currency.name_short {
            formatter.currencyCode = code
        }
        formatter.maximumFractionDigits = fractDigits
        return formatter.stringFromNumber(self)!
    }
    func toLocalCurrencyWithoutFractionDigits()->String{
        return self.toLocalCurrency(fractDigits: 0)
    }
}

I want this to be supported as many types of swift / mac number as possible, for example. CGFLoat NSNumber Int Float etc. But I don’t want to repeat myself (copy paste and expand everything) or quit everywhere, I want to use this function.

I tried to extend protocols like FloatLiteralType / Convertible, but also needed casting. This “should” is possible to expand the basic types in a more convenient way.

I also thought about global functions, but they are less clear and feel more hacked.

Is there a good way to achieve this fast?

+5
source share
2 answers

, Sogmeister Swift 2.0 .

:

// the solution right now is to implement it twice, I'll explain why
extension IntegerType {

    func toLocalCurrency(fractDigits:Int = 2) -> String {

        let formatter = NSNumberFormatter()
        formatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle

        /* ... */

        formatter.maximumFractionDigits = fractDigits
        return formatter.stringFromNumber(self as! NSNumber)! // probably like this
    }

    func toLocalCurrencyWithoutFractionDigits() -> String {

        return self.toLocalCurrency(0)
    }
}

extension FloatingPointType {
    // second implementation goes here
}

// some example
let someUInt = UInt(12340)

someUInt.toLocalCurrency() // returns "12.340,00 €" for me

:

, MyProtocol , IntegerType FloatingPointType. Swift 2.0 (. ). , , . , .

protocol MyProtocol {}

extension MyProtocol {

    func toLocalCurrency(fractDigits:Int = 2) -> String {

        let formatter = NSNumberFormatter()
        formatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle

        /* ... */

        formatter.maximumFractionDigits = fractDigits
        guard let newNumber = self as? NSNumber else { fatalError("this type is not convertable to NSNumber") }
        return formatter.stringFromNumber(newNumber)!
    }

    func toLocalCurrencyWithoutFractionDigits() -> String {

        return self.toLocalCurrency(0)
    }
}

/* extend your number types you need */
extension Int : MyProtocol {} 
extension Double : MyProtocol {} // done
+8

, :

protocol FormattableNumeric {}
extension FormattableNumeric {
    var localized: String {
        guard let number = self as? NSNumber else { return "NaN" }
        return number.description(withLocale: Locale.current)
    }
}
extension Int: FormattableNumeric {}
extension UInt: FormattableNumeric {}
extension Float: FormattableNumeric {}
extension Double: FormattableNumeric {}
// etc.

:

1000.localized // "1,000"
12_345_678.localized // "12,345,678"
(1_000_000 * Double.pi).localized // "3,141,592.65358979"

, NumberFormatter :

return NumberFormatter.localizedString(from: number, number: .decimal)
0

All Articles