How we can make Cocoa a little less verbose and a little more type safe.

When I’ve started working with Cocoa in later in 2001 I was coming from some experience in Java and a little less of pure C. Cocoa was simply amazing (check out this cool old article from Ars Technica) and the difference with the old Mac Toolbox was huge.
A brave new world was coming and I was pretty exciting of all opportunities which a complete full-featured framework like that could offer to me.
Lots of years are passed since these days, the old NeXT heritage was taken from iOS with UIKit and we lived the mobile revolution also and especially thanks to a complete solution which really helped to create an fertile environment for what we call The App Economy (which, of course, was started on macOS).

With Swift it was like stepping back in time and live the same experience another time; even thanks to this new opportunity, UIKit (and to a lesser extent AppKit) is experiencing a smooth transition to a new life (while my dream is all about a new rewritten framework, I can understand the reason behind the choice of a smooth transition of the Foundation inside the Swift Standard Library).
So, while we’re still fighting with this transition we can make our life easier anyway.

NSAttributedString  is one of the things I’ve started to hate in a post-Swift world; creating, combining and applying styles to a string, then render it it’s not a difficult task, but it’s boring, verbose and so damn inelegant.
It’s like playing withAuto Layout via code until not so long ago; we can deserve a better experience, especially now we are using Swift: we can make it type-safe, easy and coincise to use.

So, starting from this experience I’ve created a small library, called SwiftRichString (an original name, don’t you think so?).

Type Safety

The first issue I wanted to solve is regards type-safe; Swift implements type safety, which basically means that you can’t use a variable inappropriately for the terms of its type; letting the development environment enforce type safety is the safest way of handling these problems.
NSAttributedStrings  uses NSDictionary  to set attributes for text; attributes identifiers (as strings) are passed along with their values.
Like that:

In order to make it safer I’ve introduced the concept of Style . You can create a Style  with a name (we will discuss about it later) and assign attributes using a traditional creational pattern:

Even font attribute is type safe; you can create a UIFont  object in a type-safe manner by specifing one of the fonts which iOS made available. FontAttribute  can also be extended and you can add your own font names (or if you are lazy you can instantiate a font in an old fashion way by specifing a literal). By looking inside the library you will found some other special structures like StrikeAttribute , ShadowAttribute  or UnderlineAttribute ; all of them are used to make things cleaner and faster to use (take a look at the doc for a complete list).

The ideal scenario for Style  is to create a set of styles you will use along your code of your next application.

There is only one special Style  which is called .default. Default style is applied in first place regardeless the order in which it’s passed to styles parameter of a functions. This ensure you can have a base common style for your string and add one or more attributes over it easily.

If you don’t need to use tagged string in your code you can create Style  objects without giving to them a name; simply use it inside set()  functions.

Painless attributed string creation and management

Creating NSAttributedString , combine them and apply style is tedious and verbose; tons of boring code to make a pretty easy task.
Let me show to you a very simple example:

We can do better; let me show it:
set()  functions allows you add attributes to an existing String  or append attributed directly to an NSAttributedString  instances seamlessy.
There are several set()  variants which allows you to set attributes for entire string or a specific range and there is also support for pattern matching via regular expression.
So let me show to you some examples:
Clearly if you are already working with Attributed String instances you don’t need to re-create them over and over again as you want only append new content.
In this example we will append a rendered string to an existing instance:
Sometimes you may want to replace any existing attributes or remove some of them from an attributed string:

Render content from tag based source

Sometimes you may need to load a formatted text from a file, an url or some other datasource; basically this is very similar of what already happend with a browser which render an HTML file.
Clearly NSAttributedStrings  supports HTML rendering but sometimes it may like shotting with a cannon and frankly it’s not really fun to play with CSS directly in iOS.

The idea is to keep the concept of tagged content by making a lightweight string scanner with full unicode support which can parse and render a string with given attributes.
This is what MarkupString  does; just load and parse a source string (once parsed it keep parsing data internally) then allows you to apply styles using .render() functions.

That’s a simple example:

Parsing is pretty fast and you will get your cool string easily; since then you can still get the plain content of the attributed string or work with it as you need.

Tagged strings can be created also using special accessory functions called .tagged()  which accepts a Style ’s name (as String ) or an object:


So I hope you have found this article interesting; as usual I’ve released this library on GitHub as SwiftRichString. You are able to use it in your commercial or open source products without limitations (just a credit text in your copyright notices).
I’ll be happy to receive from you PRs, Issues or suggestion for future improvements; see you on GitHub and happy styling!