Adding slugification and style-based tags to SwiftUI

Aug 19, 2022 · Follow on Twitter and Mastodon swiftuiopen-sourcetagging

As I’m rewriting an old app from scratch, I’m adding a bunch of features to it. One such feature is content tagging. For reusability, I’ve put all tag-specific logic in a new library called TagKit. Let’s take a look!

TagKit logotype

How to slugify strings

One common way to handle tags is to slugify their names, which is to removing unsupported characters from a string and replacing whitespace with a separator.

You can see slugified strings in action in many web urls (for instance this one), where the page date and title is often slugified to create a unique valid url that also describes the content.

I wrote about slugifying strings in this blog post earlier this year. I use the same logic in TagKit, but made it a little more configurable.

In TagKit, the Slugifiable protocol describes a slugifyable type:

public protocol Slugifiable {

    var slugifiableValue: String { get }
}

String implements this protocol by default, by returning itself as the slugifiable value.

Once a type implements Slugifiable, it can be slugified with the slugified() function:

let string = "Hello, world!"
let slug = string.slugified() // Returns "hello-world"

You can also provide a custom SlugConfiguration to customize the slugified result:

let string = "Hello, world!"
let config = SlugConfiguration(
    separator: "+",
    allowedCharacters: NSCharacterSet(charactersIn: "hewo")
)
let slug = string.slugified(configuration: config) // Returns "he+wo"

You probably won’t need to use these functions directly, nor customize the configuration, but you can.

Taggable types

With slugified strings in place, we can start looking at tagging, which can be used to group, filter etc.

In TagKit, the Taggable protocol describes a taggable type:

public protocol Taggable {

    var tags: [String] { get set }
}

Once a type implements Taggable, it can make use of all the functionality the protocol provides, such as hasTags, hasTag(...), addTag(...), removeTag(...), toggleTag(...), etc.

Collections that contain Taggable types also get some additional functionality as well.

This means that you can now let your domain model and observable types implement Taggable and automatically get access to a bunch of logic.

Views

TagKit has a few views to make it easier to work with tags. For instance, TagList and TagEditList let you list and edit tags, TagCapsule renders a styled tag and TagTextField slugifies text as you type.

An animated gif of an app that uses TagKit

The demo above shows very plain tag capsules, but you can style these capsules in any way you like, or even replace them with your own custom views.

Conclusion

TagKit is small library, but I really like how creating these small, focused packages makes it easy to reuse functionality and share what you create. If you try it out, I’d love to hear what you think.

Discussions & More

Please share any ideas, feedback or comments you may have in the Disqus section below, or by replying on Twitter or Mastodon..

If you found this text interesting, make sure to follow me on Twitter and Mastodon for more content like this, and to be notified when new content is published.

If you like & want to support my work, please consider sponsoring me on GitHub Sponsors.