37

Just converted a project to Swift 3 and cant figure out the following error.

public func currencyString(_ decimals: Int) -> String {

    let formatter = NumberFormatter()
    formatter.numberStyle = .currency
    formatter.maximumFractionDigits = decimals
    return formatter.string(from: NSNumber(self))!
}

the return line is showing an error "Argument labels '(_:)' do not match any available overloads"

Any idea what needs to change to resolve this

Mike U
  • 2,901
  • 10
  • 32
  • 44

5 Answers5

56

You can do it this way:

public func currencyString(_ decimals: Int) -> String {

    let formatter = NumberFormatter()
    formatter.numberStyle = .currency
    formatter.maximumFractionDigits = decimals
    return formatter.string(from: NSNumber(value: decimals))!
}

Because if you check NSNumber you will get predefined init like:

public init(value: Int)
Dharmesh Kheni
  • 71,228
  • 33
  • 160
  • 165
10

To clarify the confusion as to what the error is,

NSNumber is calling NSNumber.init( value: X ) method to instantiate a NSNumber object.

"Argument labels '(_:)' do not match any available overloads"

The code produces the error because NSNumber is not a type rather it is a class with members. "NSNumber(...)" instantiates a class object to contain the 'value' of (1.0 / 1.29).

This is not a type conversion or cast like in C/C++. where you are trying to cast the type to allow the compiler to do its job.

float y = 1.3;
int x = int( y );

NSNumber is not a type like int, float, char

The error comes into play because there are several ways to call NSNumber.init( value: type )

Swift is requiring that you specifically say that you want the 'value' member of the NSNumber to contain the value x.

  let localRate = NSNumber( 1.0 / 1.29)
  var y = NSNumber( 0 )
  var b = NSNumber( false )



   let localRate = NSNumber(value: 1.0 / 1.29)
   var y = NSNumber( value: 0 )
   var b = NSNumber( value: false )

The confusion might be coming into play because this works.

w = String( "4" )

The class String does not require the argument label, while NSNumber does require an argument label of 'value:'

Perhaps this is due to how IOS treats NSNumber as coming from legacy?

Vanderdecken
  • 195
  • 1
  • 9
2

What about this?

override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationController?.navigationBar.backIndicatorImage = UIImage(named: "backButton")
        self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "backButton")
        self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", barButtonSystemItem: UIBarButtonItemStyle.Plain, target: nil, action: nil)
}
Kyll
  • 7,036
  • 7
  • 41
  • 64
  • 6
    While this code snippet may solve the question, [including an explanation](http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – Kyll Jan 14 '17 at 21:34
  • I don't get it. – The Hacking Gamer Jan 14 '17 at 21:36
  • Don't get what? Editing, answer quality, ..? – Kyll Jan 14 '17 at 21:39
  • 1
    Please explain how the example provided helps to answer the concern in the original question. – Joshua Briefman Jan 14 '17 at 22:19
0

Swift 3.0.1

public func currencyString(_ decimals: Int) -> String {
    let numberFormatter = NumberFormatter()
    numberFormatter.numberStyle = .currency
    numberFormatter.formatterBehavior = .default
    let priceString = numberFormatter.string(from: NSNumber(value:product.introPrice))
    return priceString!
}

Difference between syntex

// Old code
formatter.string(from: NSNumber(product.introPrice))!

// swift 3.0.1
formatter.string(from: NSNumber(value:product.introPrice)
Community
  • 1
  • 1
Vivek
  • 4,916
  • 35
  • 40
0

While the accepted answer shows how NSNumber initializer should be called correctly, it is good to know that there is no reason to convert Swift numbers to NSNumber if we use the string(for:) method instead of string(from:).

return formatter.string(for: self)!
Sulthan
  • 128,090
  • 22
  • 218
  • 270