Contents

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, Hashable

Overview

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-argument formatted() 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

Applying duration styles

Applying currency styles

Applying measurement styles

Applying person name styles

Applying list styles

Applying byte-count styles

Applying URL styles

Declaring input and output types

Type Properties

Type Methods

See Also

Data formatting in Swift