Day 80 - 100 Days of Swift
Project 24 (part 1)
Day 80 is the first part of the twenty-fourth project. It is a technique project where you look at some of the ins and outs of Swift Strings. You look at the fact that they are not simply arrays of primitive char
s like in many other languages. You look at some potentially useful extensions and techniques for working with Swift Strings. And you have a very quick look at using NSAttributedString
to format Strings in different ways.
First, he talks about how a String
in Swift is not simply an array of primitive characters. So while you can do this:
1
2
3
4
5
let name = "John"
for letter in name {
print("Give me a \(letter)")
}
You cannot do this:
1
print(name[3])
In Swift, you would have to do this:
1
print(name[name.index(name.startIndex, offsetBy: 3)]
You could write an extension to add subscript-ability to Strings, but it gets to be pretty inefficient pretty quickly, so there are other ways of dealing with the common String problems in Swift. For instance, you should always use .isEmpty
instead of checking if the count
is 0:
1
2
3
4
5
// do this
if someString.isEmpty { // do stuff
// not this
if someString.count == 0 { // do stuff
Next he looks at a couple of extensions you could write using the built in functionality on String
. You could write these functions that will delete a prefix or suffix, if they exist:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
extension String {
/// remove a prefix if it exists
func deletingPrefix(_ prefix: String) -> String {
guard self.hasPrefix(prefix) else { return self }
return String(self.dropFirst(prefix.count))
}
/// remove a suffix if it exists
func deletingSuffix(_ suffix: String) -> String {
guard self.hasSuffix(suffix) else { return self }
return String(self.dropLast(suffix.count))
}
}
print("12345".deletingPrefix("123")) // prints 45
print("12345".deletingPrefix("358")) // prints 12345
print("12345".deletingSuffix("345")) // prints 12
Or you could write an extension that capitalizes the first letter of a string, instead of the first letter of every word:
1
2
3
4
5
6
7
8
9
10
11
12
extension String {
/// capitalize the first letter
var capitalizedFirst: String {
guard let firstLetter = self.first else { return self }
return firstLetter.uppercased() + self.dropFirst()
}
}
print("it sure looks like rain".capitalized)
// prints "It Sure Looks Like Rain"
print("it sure looks like rain".capitalizedFirst)
// prints "It sure looks like rain"
And you could write an extension that would check whether a String
contains any of the strings in a given array. But, there is a simpler way to do it using contains(where:)
:
1
2
3
4
5
let input = "Swift is like Objective-C without the C"
let languages = ["Ruby", "Python", "Swift"]
print(languages.contains(where: input.contains))
// prints true
This will loop through each of the values in languages
and check to see whether input
contains that value.
Finally, you look at using NSAttributedString
to give some attributes to some or all of a String
:

And that’s it for today. I’m hoping we get more into the attributed string thing tomorrow though, because it looks pretty cumbersome so far. There has to be easier ways of dealing with formatting at scale. Or at least some patterns people have adopted. But I guess we’ll see tomorrow.
You can find my version of this playground at the end of day 80 on Github here.