DEV Community

Daniel Cardona Rojas
Daniel Cardona Rojas

Posted on

4 2

Easy field masking in Swift

When working with forms its is very likely that you will need to do field masking.

In this short article I want to present a small and flexible library called Veil that allows us to do this very easily.

Veil is a pure swift library that is available through Swift Package Manager, it does not depend on UIKit and instead
is a pure string processing utility, so use on any platform with UIKit or SwiftUI.

If you're a iOS developer its very likely that you might have stumbled with this problem and might have tried solving this by implementing UITextFieldDelegate
shouldReplaceCharacters:in range method. This is usually a painful experience as dealing with ranges is all around not that comfortable.

Veil offers a very simple solution to masking which does not require the developer to implement UITextFieldDelegate, instead can be easily
used with target action pattern.

Examples

Referring the documentation of the official repository, we can see a common example of formatting date input
into mm/yy

let dateMask = Veil(pattern: "## / ##")
let result = dateMask.mask(input: "234")
// result = "23 / 4"
Enter fullscreen mode Exit fullscreen mode

So first we need to supply some masking pattern, Veil uses a default configuration (which can be replaced)
where # represent digits while * any character. Anything else within the pattern will be
inserted automatically into the resulting string, so typing "234" will yield "23 / 4" (including spaces).

Usage with UITextField

let dateMask = Veil(pattern: "## / ##")

@objc func textDidChange(_ sender: UITextField) {
    guard let currentText = sender.text else  {
        return
    }

    sender.text = dateMask.mask(input: currentText, exhaustive: false)
}
Enter fullscreen mode Exit fullscreen mode

How it works

Internally Veil parses the pattern string into an array of tokens where a Token is

enum Token {
    case digit, any
    case symbol(Character)
}
Enter fullscreen mode Exit fullscreen mode

So a pattern like "## / ##" will result in the array of tokens:

[.digit, .digit, .symbol(" "), .symbol("/"), .symbol(" "), .digit, .digit]
Enter fullscreen mode Exit fullscreen mode

It will walk through input string matching against the token pattern until either is exhausted.
This also implies you get automatic input blocking.

I encourage everyone to give this a try, and let me know you're thoughts.

Thanks!

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

Sentry mobile image

Mobile Vitals: A first step to Faster Apps

Slow startup times, UI hangs, and frozen frames frustrate users—but they’re also fixable. Mobile Vitals help you measure and understand these performance issues so you can optimize your app’s speed and responsiveness. Learn how to use them to reduce friction and improve user experience.

Read the guide

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay