One of the most important roles of any software architecture is to make the relationships between the various objects and values within an application as clear and well-defined as possible.

This week, let's take a look at how we can do that by using Swift's powerful type system to set up locks and keys to get a stronger, compile-time guarantee that the intended flow of our app will remain intact at runtime.

A really elegant aspect of Swift's implementation of optionals, is that a large part of this feature is implemented using the type system - since all optional values are actually represented using an enum under the hood.

That gives us some interesting capabilities, since we can extend that enum to add our own convenience APIs and other kinds of functionality. This week, let's take a look at how to do just that.

Whether or not you believe that the iPad is the future of computing, it does bring a ton of interesting new features and capabilities to the table - especially with the latest release of the Pro version.

This week, let’s take a look at how we as third-party developers can take advantage of some of those capabilities to build interesting new features for our iOS apps.

A race condition is what happens when the expected completion order of a sequence of operations becomes unpredictable, causing our program logic to end up in an undefined state.

This week, let's take a look at a common scenario that can cause race conditions, possible ways to avoid them - and how we can make our code more robust and predictable in the process.

Since Swift was originally designed with a strong focus on compile time safety and static typing, it mostly lacks the sort of dynamic features commonly seen in more runtime-focused languages.

However, Swift keeps gaining more and more features that are more dynamic in nature - while still retaining its focus on type safe code. This week, let’s take a look at how key paths in Swift work, and some of the cool and powerful things they can let us do.

Protocols continue to be an integral part of Swift - both in terms of how the language itself is designed, and also in how the standard library is structured.

This week, let's take a look at how we can use protocols to create multiple levels of abstraction, and try out a few different techniques that let us start out with a more general protocol that we then increasingly specialize to become more and more specific to each use case.

A DSL, short for Domain Specific Language, can be explained as a special kind of API that focuses on providing a simple syntax that's tailored to working within a specific domain.

While DSLs are often written in more dynamic languages, such as Ruby - Swift's type inference and overloading capabilities also make it a really great language to build DSLs in - and this week, let's do just that!

Most modern apps require some form of networking - which means working with URLs in different shapes and forms. However, constructing URLs - especially dynamic ones based on user input - isn't always straight forward, and can lead to a wide range of bugs and problems if we're not careful.

This week, let's take a look at various techniques for working with URLs in Swift, how to make our URL construction code more robust, and how different kinds of URLs might warrant different approaches.

The way that an app’s data is used tends to vary quite a lot depending on what view the data is being displayed in - requiring custom data logic for each view.

View models attempt to make it easier to write and maintain such logic, by introducing dedicated types for it. This week, let’s take a look at a few different ways that various flavors of view models can be implemented in Swift.

Asynchronous code is essential to providing a good user experience, but can at times be really tricky to write, debug and especially test.

This week - let's explore how we can make our asynchronous tests much simpler, inspired by the async/await programming paradigm.

Lists and collections of items are arguably two of the most common types of UIs found in apps - rendered through a UITableView or a UICollectionView.

This week, let's take a look at how we can implement data sources for table- and collection views in a more reusable manner, and how doing so can let us make our list-based UI code more composable and easier to work with.

Separation of concerns is one of the most universally recognized programming principles - but in practice, it can be easier said than done, especially when it comes to UI development.

This week, let’s take a look at how we can use the presenter pattern to move some code normally contained within view controllers - specifically related to the presentation of additional UIs - into separate, dedicated types, to improve our separation of concerns.

This week, let's take a look at how we can be inspired by the functional programming world to improve the structure and robustness of our Swift code - this time focusing on using functions that return objects and values as early as possible.

With each new release, Swift keeps getting better and better at creating compiler-generated implementations of common boilerplate. One such new feature in Swift 4.2 is the new CaseIterable protocol - that enables us to tell the compiler to automatically synthesize an allCases collection for any RawRepresentable enum. This week, let's take a look at some examples of scenarios in which this new feature can come very much in handy.

Proper encapsulation of logic is one of the most important things when it comes to building well-architected apps and systems. By limiting access to a given value or object to those that really need it, we can create more well-defined relationships and reduce the amount of code paths that we need to test. This week - let's take a look at how we can improve encapsulation in our model layer, using model controllers.

Adding new features to an app or framework often involves adding new arguments to existing functions. While most such changes may seem trivial at first, if we're not careful, we could - over time - end up with functions that are a bit unclear and cumbersome to use. This week, let's take a look at how to deal with such functions, and how they often can be simplified by reducing the number of arguments they accept.

Type inference is a key feature of the Swift type system and plays a big part in the syntax of the language - making it less verbose by eliminating the need for manual type annotations where the compiler itself can infer the types of various values.

This week, let's take a look at how we can make Swift's Codable API a bit nicer and less verbose to use, by leveraging the power of type inference.

One thing that almost all apps and frameworks have in common is that they tend to grow in both size and complexity as time passes. As a project grows it becomes more and more important to maintain a solid and consistent structure, but at the same time it also becomes increasingly difficult to do so.

This week, let's take a look at some tips and tricks as to how we can improve the structure of our Swift projects in a few key ways.

Adding new features to existing code can be really challenging - especially if that code is heavily used throughout one or many projects. Backward compatibility can in many ways help us make such changes in a much smoother fashion, so this week, let's take a look at a few different techniques that can help us make changes to our code base fully backward compatible.

Unit testing can be a great tool in order to improve the quality of an app, and to enable the team working on it to iterate and release faster and more often. However, being able to use unit testing in a productive way also requires the various parts of an app to be written with testability in mind, which isn't always the case.

This week, let's take a look at a few different refactoring techniques that can help us make non-testable code much easier to test.