Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Format string with variadic arguments

I have extension for String

func localized(table: String? = nil, bundle: Bundle = .main, args: CVarArg...) -> String {
  return String(
    format: NSLocalizedString(
      self,
      tableName: table,
      bundle: bundle,
      value: self,
      comment: ""
    ),
    args
  )
}

Localizable.strings file:

"%d seconds ago" = "%d seconds ago";

Usage:

print("%d seconds ago".localized(args: 5))
print(String.localizedStringWithFormat("%d seconds ago", 5))

And result:

<some_random_number_here> seconds ago.
5 seconds ago.

Can someone explain me what do I do wrong?

like image 328
Alex Zaikin Avatar asked Dec 01 '16 15:12

Alex Zaikin


1 Answers

String has two similar initializers:

init(format: String, _ arguments: CVarArg...)
init(format: String, arguments: [CVarArg])

The first one takes a varying number of arguments, the second one an array with all arguments:

print(String(format: "x=%d, y=%d", 1, 2))
print(String(format: "x=%d, y=%d", arguments: [1, 2]))

In your localized method, args: CVarArg... is a variadic parameter and those are made available within the functions body as an array of the appropriated type, in this case [CVarArg]. Therefore it must be passed to String(format: arguments:):

func localized(table: String? = nil, bundle: Bundle = .main, args: CVarArg...) -> String {
  return String(
    format: NSLocalizedString(
      self,
      tableName: table,
      bundle: bundle,
      value: self,
      comment: ""
    ),
    arguments: args   // <--- HERE
  )
}

See also "Variadic Parameters" in the "Functions" chapter of the Swift reference.

like image 141
Martin R Avatar answered Sep 19 '22 05:09

Martin R