Bad practice: not using PersonNameComponentsFormatter


You’re more of a video kind of person? I’ve got you covered! Here’s a video with the same content than this article 🍿


Can you guess what’s the problem with this code?

If you live in a western country, there’s a good chance this code seems perfectly reasonable: we format the fullName of the User by using String interpolation.

However, while most western countries indeed format a fullName by writing the givenName first and the familyName second, not all countries follow this convention!

For instance, Koreans write the familyName first and the givenName second.

And as you can imagine, if your app doesn’t follow this local convention, it will feel weird and out-of-place with a part of your audience!

Fortunately, iOS has a built-in way to solve this problem!

For this, we’re going to use a class called PersonNameComponentsFormatter.

PersonNameComponentsFormatter works in a similar way to other formatters like NumberFormatter or DateFormatter: you give it raw data and it formats it according to the user’s Locale.

So I’m going to update the implementation of the property fullName to use a PersonNameComponentsFormatter rather than String interpolation.

As you can see, the new implementation yields the same result than the previous one:

That’s normal because my Locale is currently set to French, and this is indeed how a fullName would be displayed in France.

But if I update the Locale to be that of Korea, you can see that the behavior of the formatter is now matching that of the new Locale: the fullName is now formatted with the familyName first, and the givenName second.

That’s all for this article, I hope you’ve enjoyed discovering how PersonNameComponentsFormatter works!

Here’s the code if you want to experiment with it:

import Foundation

struct User {
    let givenName: String
    let familyName: String
}

let personNameFormatter = PersonNameComponentsFormatter()

extension User {
    var fullName: String {
        var components = PersonNameComponents()
        components.givenName = givenName
        components.familyName = familyName
        return personNameFormatter.string(from: components)
    }
}

let user = User(
    givenName: "Vincent",
    familyName: "Pradeilles"
)

user.fullName // Vincent Pradeilles

let koreanLocale = Locale(identifier: "ko_KR")
personNameFormatter.locale = koreanLocale

user.fullName // Pradeilles Vincent
Previous
Previous

Swift has more formatters than you think! 🤯

Next
Next

Here are 8 tips to design a great paywall 🤑