FormatStyle
A type that converts a given data type into a representation in another type, such as a string.
Declaration
protocol FormatStyle<FormatInput, FormatOutput> : Decodable, Encodable, HashableOverview
Types conforming to the FormatStyle protocol take their input type and produce formatted instances of their output type. The formatting process accounts for locale-specific conventions, like grouping and separators for numbers, and presentation of units for measurements. The format styles Foundation provides produce their output as String or AttributedString instances. You can also create custom styles that format their output as any type, like XML or JSON Data or an image.
There are two basic approaches to using a FormatStyle:
Create an instance of a type that conforms to FormatStyle and apply it to one or more instances of the input type, by calling the style’s format(_:) method. Use this when you want to customize a style once and apply it repeatedly to many instances.
Pass an instance of a type that conforms to FormatStyle to the data type’s
formatted(_:)method, which takes the style as a parameter. Use this for one-off formatting scenarios, or when you want to apply different format styles to the same data value. For the simplest cases, most types that support formatting also have a no-argumentformatted()method that applies a locale-appropriate default format style.
Foundation provides format styles for integers (IntegerFormatStyle), floating-point numbers (FloatingPointFormatStyle), decimals (Decimal.FormatStyle), measurements (Measurement.FormatStyle), arrays (ListFormatStyle), and more. The “Conforming types” section below shows all the format styles available from Foundation and any system frameworks that implement the FormatStyle protocol. The numeric format styles also provide supporting format styles to format currency and percent values, like IntegerFormatStyle.Currency and Decimal.FormatStyle.Percent.
Modifying a format style
Format styles include modifier methods that return a new format style with an adjusted behavior. The following example creates an IntegerFormatStyle, then applies modifiers to round values down to the nearest 1,000 and applies formatting appropriate to the fr_FR locale:
let style = IntegerFormatStyle<Int>()
.rounded(rule: .down, increment: 1000)
.locale(Locale(identifier: "fr_FR"))
let rounded = 123456789.formatted(style) // "123 456 000"Foundation caches identical instances of a customized format style, so you don’t need to pass format style instances around unrelated parts of your app’s source code.
Accessing static instances
Types that conform to FormatStyle typically extend the base protocol with type properties or type methods to provide convenience instances. These are available for use in a data type’s formatted(_:) method when the format style’s input type matches the data type. For example, the various numeric format styles define number properties with generic constraints to match the different numeric types (Double, Int, Float16, and so on).
To see how this works, consider this example of a default formatter for an Int value. Because 123456789 is a BinaryInteger, its formatted(_:) method accepts an IntegerFormatStyle parameter. The following example shows the style’s default behavior in the en_US locale.
let formatted = 123456789.formatted(IntegerFormatStyle()) // "123,456,789"IntegerFormatStyle extends FormatStyle with multiple type properties called number, each of which is an IntegerFormatStyle instance; these properties differ by which BinaryInteger-conforming type they take as input. Since one of these statically-defined properties (number) takes Int as its input, you can use this type property instead of instantiating a new format style instance. Using dot notation to access this property on the inferred FormatStyle makes the call point much easier to read, as seen here:
let formatted = 123456789.formatted( .number) // "123,456,789"Furthermore, since you can customize these statically-accessed format style instances, you can rewrite the example from the previous section without instantiating a new IntegerFormatStyle, like this:
let rounded = 123456789.formatted( .number
.rounded(rule: .down, increment: 1000)
.locale(Locale(identifier: "fr_FR"))) // "123 456 000"Parsing with a format style
To perform the opposite conversion — from formatted output type to input data type — some format styles provide a corresponding ParseStrategy type. These format styles typically expose an instance of this type as a variable, called parseStrategy.
You can use a ParseStrategy one of two ways:
Initialize the data type by calling an initializer of that type that takes a formatted instance and a parse strategy as parameters. For example, you can create a Decimal from a formatted string with the initializer init(_:format:lenient:).
Create a parse strategy and call its parse(_:) method on one or more formatted instances.
Topics
Performing formatting
Setting style Locale
Applying numeric styles for integers
Applying numeric styles for floating-point values
Applying numeric styles for decimals
Applying percentage styles for integers
Applying percentage styles for floating-point values
Applying percentage styles for decimals
Applying date and time styles
dateTimeDate.FormatStyleDate.ISO8601FormatStyleverbatim(_:locale:timeZone:calendar:)Date.VerbatimFormatStyleintervalDate.IntervalFormatStylerelative(presentation:unitsStyle:)Date.RelativeFormatStylecomponents(style:fields:)Date.ComponentsFormatStyle
Applying duration styles
timeDurationDate.ComponentsFormatStyletime(pattern:)units(allowed:width:maximumUnitCount:zeroValueUnits:valueLength:fractionalPart:)units(allowed:width:maximumUnitCount:zeroValueUnits:valueLengthLimits:fractionalPart:)
Applying currency styles
Applying measurement styles
measurement(width:usage:numberFormatStyle:)measurement(width:usage:hidesScaleName:numberFormatStyle:)
Applying person name styles
Applying list styles
Applying byte-count styles
byteCount(style:allowedUnits:spellsOutZero:includesActualByteCount:)ByteCountFormatStylebyteCount(style:allowedUnits:spellsOutZero:includesActualByteCount:)Measurement.FormatStyle.ByteCount