Say I've downloaded this list of data from an API:
[
"Anita",
"Jean",
"Peter"
]
I'd like to list this data in a natural sentece format. For example, in US English, this string should be displayed to the user:
Anita, Jean, and Peter
However, if the user is Swedish for example, they should see this string:
Anita, Jean och Peter
Notice that the Oxford comma is missing, and Swedish uses a different word for "and", which is what a Swedish user would expect to see. How can I format this data in a natural-language way that would respect the user's locality? There can be a variable amount of data, not necessarily just 3 items. My instinct is to subclass Formatter
/NSFormatter
, but I'd like to build this in a way I can easily expand it to support languages that I don't speak, so I'm wondering if there's an iOS-standard or 3rd party formatter that I haven't been able to find in my searches
Starting with iOS 13, Foundation has a ListFormatter
type. According to your needs, you can use it in different ways to get a textual representation of your array.
The simplest way to use ListFormatter
is to use its static localizedString(byJoining:)
method. The following Swift 5.1 / iOS 13 Playground sample code shows how to implement this method in order to convert your array into a localized string representation:
import Foundation
let array = [
"Anita",
"Jean",
"Peter"
]
let string = ListFormatter.localizedString(byJoining: array)
print(string) // prints: Anita, Jean, and Peter (for en_US locale)
As an alternative to localizedString(byJoining:)
, you can create an instance of ListFormatter
and use string(from:)
method. This can be useful if you need to specify a locale for your textual representation:
import Foundation
let array = [
"Anita",
"Jean",
"Peter"
]
let listFormatter = ListFormatter()
listFormatter.locale = Locale(identifier: "fr_FR") // set only if necessary
let string = listFormatter.string(from: array)
print(String(describing: string)) // prints: Optional("Anita, Jean et Peter")
If needed, you can also set the itemFormatter
property of your ListFormatter
instance with a specialized formatter type:
import Foundation
let array = [
55,
112,
8
]
let locale = Locale(identifier: "es_ES") // set only if necessary
let numberFormatter = NumberFormatter()
numberFormatter.locale = locale
numberFormatter.numberStyle = NumberFormatter.Style.spellOut
let listFormatter = ListFormatter()
listFormatter.locale = locale
listFormatter.itemFormatter = numberFormatter
let string = listFormatter.string(from: array)
print(String(describing: string)) // prints: Optional("cincuenta y cinco, ciento doce y ocho")