Dunfey · Hotel WWDC as data, est. 1983
Front desk everything
Years
Topics

2020 Accessibility & Inclusion

WWDC20 · 15 min · Accessibility & Inclusion

Formatters: Make data human-friendly

Save yourself time and frustration: When you display data in your app — including dates, times, measurements, names, lists, numbers, or strings — learn how to format it correctly and provide a great experience. We’ll walk you through the Formatter APIs as well as how SwiftUI works with stringsdict, and show you how they can help do the heavy lifting of formatting data. Learn about best practices and how to avoid common mistakes.

Watch at developer.apple.com ↗

Transcript all transcripts

Code shown on screen · 10 snippets

Dates and times swift · at 2:25 ↗
// Dates and Times

// Date with Day/Month/Year and Time
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .short
dateFormatter.string(from: Date())

// Day of Week + Date + Month
let dateFormatter = DateFormatter()
dateFormatter.setLocalizedDateFormatFromTemplate
    ("MMMMdEEEE")
dateFormatter.string(from: Date())

// Abbreviated Day of Week
let dateFormatter = DateFormatter()
dateFormatter.setLocalizedDateFormatFromTemplate
    ("ccccc")
dateFormatter.string(from: Date())
Date components formatter swift · at 5:56 ↗
// Dates and Times

// Date and Time Components
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .abbreviated
let components = DateComponents(hour: 2, minute: 26)
formatter.string(from: components)

// Date and Time Intervals
let formatter = DateIntervalFormatter()
formatter.dateTemplate = "dMMM"
formatter.string(from: startDate, to: endDate)

// Relative Dates and Times
let formatter = RelativeDateTimeFormatter()
formatter.dateTimeStyle = .named
formatter.localizedString(from: DateComponents(day: -1))
Measurements swift · at 6:29 ↗
// Measurements

// Temperature
let formatter = MeasurementFormatter()
let temperature = Measurement<UnitTemperature>
    (value: 16, unit: .celsius)
formatter.numberFormatter.maximumFractionDigits = 0
formatter.string(from: temperature)

// Speed
let speed = Measurement<UnitSpeed>
    (value: 14, unit: .kilometersPerHour)
formatter.string(from: speed)

// Pressure
let pressure = Measurement<UnitPressure>
    (value: 1.01885, unit: .bars)
formatter.string(from: pressure)
Names swift · at 7:49 ↗
// Names

let formatter = PersonNameComponentsFormatter()
var nameComponents = PersonNameComponents()
nameComponents.familyName = "Iwasaki"
nameComponents.givenName = "Akiya"
nameComponents.nickname = "Aki-chan"

// Full Name
formatter.string(from: nameComponents)

// Short Name: Respects User Preferences
formatter.style = .short
formatter.string(from: nameComponents)

// Abbreviated Name
formatter.style = .abbreviated
formatter.string(from: nameComponents)
Abbreviated name (monogram) swift · at 8:31 ↗
// Abbreviated Name: Monogram
formatter.style = .abbreviated
let monogram = formatter.string(from: nameComponents)
if (monogram.count <= 2) {
    // Use Monogram
}
else {
    // Use Icon
}
Name formatter swift · at 9:23 ↗
// Names

let formatter = PersonNameComponentsFormatter()
var nameComponents = PersonNameComponents()
nameComponents.familyName = "岩崎"
nameComponents.givenName = "晃也"
nameComponents.nickname = "あきちゃん"

// Full Name
formatter.string(from: nameComponents)

// Short Name: Respects User Preferences
formatter.style = .short
formatter.string(from: nameComponents)

// Abbreviated Name
formatter.style = .abbreviated
formatter.string(from: nameComponents)
Lists swift · at 10:15 ↗
// Lists

// English Localization

let items = [ "English", "French", "Spanish" ] ListFormatter.localizedString(byJoining: items)

let items = [ "English", "Spanish" ] ListFormatter.localizedString(byJoining: items)

let items = [ "Spanish", "English" ] ListFormatter.localizedString(byJoining: items)

// Spanish Localization

let items = [ "Inglés", "Español" ] ListFormatter.localizedString(byJoining: items)

let items = [ "Español", "Inglés" ] ListFormatter.localizedString(byJoining: items)
Numbers swift · at 12:01 ↗
// Numbers

let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.string(from: 32.768) // French (France)

let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.string(from: 32.768) // Arabic (Egypt)

formatter.percentSymbol

formatter.decimalSeparator
Numbers formatter swift · at 12:33 ↗
// Numbers

let formatter = NumberFormatter()
formatter.numberStyle = .percent
formatter.string(from: 0.71) // English (US)

let formatter = NumberFormatter()
formatter.numberStyle = .percent
formatter.string(from: 0.71) // Turkish (Turkey)
Strings swift · at 13:24 ↗
// Strings

var body: some View {
    Text("\(photosCount) Photos Selected")
}

Resources