Special characters like emoji, accents, and symbols in your strings are easier to get than you think. This week, we’ll talk about how using Unicode characters in Swift String
s. Open the exercise file and you’ll find a project which we’ll use for this. I just hooked up a label to make a big display of what I want to show.
Hit Control-Command-Spacebar to get the character viewer. If you get a compact one like this, click the upper right corner icon to expand it.

When expanded, Click the settings gear in the corner . Select customize list.

There a big list of items.

You can select languages, I’ll select the Enclosed Characters for example.
Go down to the bottom and open Code tables then add Unicode. Click Done.

Select Unicode in the character viewer.

The Unicode set gives you the power to add a lot to your strings. This table lists all the Unicode symbols, and activates Unicode labeling of symbols in the character viewer. In the search bar of the character viewer, find a doughnut. You see a Unicode identifier after it.

You can use these Unicode characters in your app. You’ll see the doughnut is U+1f369.
I can add the doughnut to my code as an escape sequence in the string of \u{}
yummy = "\u{1f369}"
run my app, And I get a doughnut.

If I need an accented character, I can use a Unicode character. In the search window, I’ll search for n. In the related characters, I’ll find an ñ.

Click that

It has a unicode of U+00f1
, so I can do this:
var yummy = "Bu\u{00f1}elos"
That’s not very flexible for multiple accent combinations. Instead of using the single character, you can use extended grapheme clusters, which combines two characters.
Head to the Unicode section of the Character viewer. Find the n. which has a value of U+006e
.

There a special set for combining characters with diacritical marks starting at U+0300
.

The combining tilde is at U+0303
. I can change my string to this:
yummy = "Bu\u{006e}\u{0303}elos"
Run this.

The combining Unicode doesn’t need the Unicode base by the way, You can do this with an n
too:
yummy = "Bun\u{0303}elos"
Also gets

Diacritical marks can be anywhere in the character space. I’ll head over to the Combining Diacritical Marks for Symbols.Click a few and you’ll see in the preview their location referenced by some guidelines.
Some are above, some below and some in the middle. Comment out the yummy assignments we have. I’ll demonstrate the positions with this string:
var yummy = "D\u{1f369}ugh\u{20d7}n\u{20ed}uts"
Run this and see all the fun. .

There’s one thing you have to be careful of here. Extended grapheme clusters are counted as a single character in a character count. Change the code to
label.text = yummy + String(format:" %i",yummy.count)
and run

Yields 9, ignoring the arrows. This makes sense if you are counting full characters, but it runs into problems for memory allocation. If you are bridging between NSString
and Swift’s String
type, the allocation is different due to the extended grapheme clusters. This is why Swift strings aren’t true arrays with an integer index like C-strings. The clusters make counts impossible. I can’t do this to get the third character.
let char = yummy[3]
I’ll get an error

I can’t just use an integer subscript. Next week, I’ll show you how to handle character access and manipulation in strings.
The Whole Code
Here’s teh code for this project. You can also download it here from GitHub
// // A Demo for iOS Development Tips Weekly // by Steven Lipton (C)2018, All rights reserved // For videos go to http://bit.ly/TipsLinkedInLearning // For code go to http://bit.ly/AppPieGithub //🍩 import UIKit // an extra not found in the video: // it doesn't hurt to make the characters constants or enums for more readable code. let upperArrow = "\u{20d7}" let lowerArrow = "\u{20ed}" let doughnut = "\u{1f369}" class ViewController: UIViewController { var yummy = "D\u{1f369}ugh\u{20d7}n\u{20ed}uts" @IBOutlet weak var label: UILabel! override func viewDidLoad() { super.viewDidLoad() yummy = "\u{1f369}" yummy = "Bun\u{0303}elos" yummy = "D" + doughnut + "ugh" + upperArrow + "n" + lowerArrow + "uts" label.text = yummy + String(format:" %i",yummy.count) } }
Leave a Reply