Swift

Modern logging with the OSLog framework in Swift

Published on: June 7, 2024

We all know that print is the most ubiquitous and useful debugging tool in a developer’s toolbox. Sure, we have breakpoints too but what’s the fun in that? Sprinkling some prints throughout our codebase to debug a problem is way more fun! And of course when we print more than we can handle we just add some useful prefixes to our messages and we’re good to go again. What if i told that you can do way better with just a few lines of code. You can send your prints to more places, give them a priority, and more. Of...

Read more...

Deciding between a for loop or forEach in swift

Published on: April 23, 2024

Swift offers multiple ways to iterate over a collection of items. In this post we’ll compare a normal for loop to calling forEach on a collection. Both for x in collection and collection.forEach { x in } allow you to iterate over elements in a collection called collection. But what are their differences? Does one outperform the other? Is one better than the other? We’ll find out in this post. Using a regular for loop I’ve written about for loops in Swift before so if you want an in-depth look, take a look at this post. A regular for loop...

Read more...

Dispatching to the Main thread with MainActor in Swift

Published on: April 23, 2024

Swift 5.5 introduced loads of new concurrency related features. One of these features is the MainActor annotation that we can apply to classes, functions, and properties. In this post you’ll learn several techniques that you can use to dispatch your code to the main thread from within Swift Concurrency’s tasks or by applying the main actor annotation. If you’d like to take a deep dive into learning how you can figure out whether your code runs on the main actor I highly recommend reading this post which explores Swift Concurrency’s isolation features. Alternatively, if you’re interested in a deep dive...

Read more...

How to use experimental Swift versions and features in Xcode?

Published on: April 18, 2024

If you’re keen on reading about what’s new in Swift or learn about all the cool things that are coming up, you’re probably following several folks in the iOS community that keep track and tell you about all the new things. But what if you read about an upcoming Swift feature that you’d like to try out? Do you have to wait for it to become available in a new Xcode release? Sometimes the answer is Yes, you’ll have to wait. But more often than not a Swift evolution proposal will have a header that looks a bit like this:...

Read more...

Using closures for dependencies instead of protocols

Published on: April 2, 2024

It’s common for developers to leverage protocols as a means to model and abstract dependencies. Usually this works perfectly well and there’s really no reason to try and pretend that there’s any issue with this approach that warrants an immediate switch to something else. However, protocols are not the only way that we can model dependencies. Often, you’ll have a protocol that holds a handful of methods and properties that dependents might need to access. Sometimes, your protocol is injected into multiple dependents and they don’t all need access to all properties that you’ve added to your protocol. Also, when...

Read more...

Everything you need to know about Swift 5.10

Published on: March 7, 2024

The long awaited iOS 17.4 and iPadOS 17.4 have just been released which means that we could slowly but surely start seeing alternative app stores to appear if you’re an EU iOS user. Alongside the 17.4 releases Apple has made Xcode 15.3 and Swift 5.10 available. There’s not a huge number of proposals included in Swift 5.10 but that doesn’t make this release less significant. With Swift 5.10, Apple has managed to close some large gaps that existed in Swift Concurrency’s data safety features. In short, this means that the compiler will be able to catch more possible thread safety...

Read more...

Designing APIs with typed throws in Swift

Published on: February 22, 2024

When Swift 2.0 added the throws keyword to the language, folks were somewhat divided on its usefulness. Some people preferred designing their APIs with an (at the time) unofficial implementation of the Result type because that worked with both regular and callback based functions. However, the language feature got adopted and a new complaint came up regularly. The way throws in Swift was designed didn’t allow developers to specify the types of errors that a function could throw. In every do {} catch {} block we write we have to assume and account for any object that conforms to the...

Read more...

How to determine where tasks and async functions run in Swift?

Published on: February 16, 2024

Swift’s current concurrency model leverages tasks to encapsulate the asynchronous work that you’d like to perform. I wrote about the different kinds of tasks we have in Swift in the past. You can take a look at that post here. In this post, I’d like to explore the rules that Swift applies when it determines where your tasks and functions run. More specifically, I’d like to explore how we can determine whether a task or function will run on the main actor or not. We’ll start this post by very briefly looking at tasks and how we can determine where...

Read more...

Getting started with @Observable in SwiftUI

Published on: February 6, 2024

With iOS 17, we’ve gained a new way to provide observable data to our SwiftUI views. Until iOS 17, we’d use either an ObservableObject with @StateObject, @ObservedObject, or @EnvironmentObject whenever we had a reference type that we wanted to observe in one of our SwiftUI views. For lots of apps this worked absolutely fine, but these objects have a dependency on the Combine framework (which in my opinion isn’t a big deal), and they made it really hard for developers to limit which properties a view would observe. In iOS 17, we gained the new @Observable macro. I wrote about...

Read more...

Writing code that makes mistakes harder

Published on: January 25, 2024

As we work on projects, we usually add more code than we remove. At least that’s how things are at the beginning of our project. While our project grows, the needs of the codebase change, and we start refactoring things. One thing that’s often quite hard to get exactly right when coding is the kinds of abstractions and design patterns we actually need. In this post, I would like to explore a mechanism that I like to leverage to make sure my code is robust without actually worrying too much about abstractions and design patterns in the first place. We’ll...

Read more...