Recent articles
Jump to a random postWhat does “atomic” mean in programming?
Published on: January 6, 2021When you're learning about databases or multithreaded programming, it's likely that you'll come across the term "atomic" at some point. Usually you'll hear the term in the context of an operation. For example, an atomic read / write operation. Or atomic access to a property. But what does this mean? Generally, you can summarize atomic as "one at a time". For example, when accessing or mutating a property is atomic, it means that only one read or write operation can be performed at a time. If you have a program that reads a property atomically, this means that the property...
Read more...10 things iOS developers should focus on in 2021
Published on: January 4, 2021I know. This is a clickbaity title. And yes, I know that this list is not relevant for everybody. I know that not every iOS developer has to learn everything on this list. That said, this list is a list of technologies and skills that I think are either already important, or becoming increasingly important this year. It's a list of technologies and skills that I have learned, plan to learn, or would like to learn this year. It's also a list that hopefully inspires you to broaden your horizons, and learn new things. Or maybe this list inspires you...
Read more...Observing the result of saving a background managed object context with Combine
Published on: December 7, 2020I love posts where I get to put write about two of my favorite frameworks at the moment; Combine and Core Data. When you're working with Core Data, it's common to perform save operations asynchronously using a background context. You could even perform an asynchronous save on the main managed object context. Consider the following method that I added to an object that I wrote called StorageProvider: public extension StorageProvider { func addTask(name: String, description: String, nextDueDate: Date, frequency: Int, frequencyType: HouseHoldTask.FrequencyType) { persistentContainer.performBackgroundTask { context in let task = HouseHoldTask(context: context) task.name = name task.taskDescription = description task.nextDueDate =...
Read more...Responding to changes in a managed object context
Published on: November 23, 2020Working with multiple managed object contexts will often involve responding to changes that were made in one context to update another context. You might not even want to update another context but reload your UI or perform some other kind of update. Maybe you want to do this when a specific context updates, or maybe you want to run some code when any context updates. In this week's post I will show you how you can listen for changed in managed object contexts, and how you can best use them. I will also show you a convenient way to extract...
Read more...Building a concurrency-proof token refresh flow in Combine
Published on: November 9, 2020Refreshing access tokens is a common task for many apps that use OAuth or other authentication mechanisms. No matter what your authentication mechanism is, your tokens will expire (eventually) and you'll need to refresh them using a refresh token. Frameworks like RxSwift and Combine provide convenient ways to build pipelines that perform transformation after transformation on a succesful network response, allowing you to grab Data, manipulate and transform it to an instance of a model object or anything else. Programming the not-so-happy path where you need to refresh a token is not as simple. Especially because in an ideal world...
Read more...Building a simple remote configuration loader for your apps
Published on: October 26, 2020Remote configuration is a common practice in almost every app I have worked on. Sometimes these configurations can be large and the implications of a configuration change can be far-reaching while other times a configuration is used to change the number of items shown in a list, or to enable or disable certain features. You can even use remote configuration to set up your networking layer. For example by setting certain headers on a request, providing endpoints for your remote data, and more. In this week's post I will not go into detail about every possible use case that you...
Read more...Formatting dates in the user’s locale using DateFormatter in Swift
Published on: October 15, 2020Working with dates is hard, there is no doubt about that. And formatting dates properly for every user of your app is no easier (if you want to do everything manually). Luckily, the system can help us. For example, in the US one would write "October 15" while in The Netherlands we write 15 oktober. Note that the order of the date and the month is different, the spelling of the month is different and the capitalization is different too. The DateFormatter in iOS will handle a lot of this for you. For example, if you'd use the following code...
Read more...Observing changes to managed objects across contexts with Combine
Published on: October 12, 2020A common pattern in Core Data is to fetch objects and show them in your UI using one managed object context, and then use another context to update, insert or delete managed objects. There are several ways for you to update your UI in response to these changes, for example by using an NSFetchedResultsController. I wrote about doing this in a SwiftUI app in an earlier post. In this week's post I will show you a useful technique that allows you to observe specific managed objects across different contexts so you can easily update your UI when, for example, that...
Read more...Understanding the differences between your Core Data model and managed objects
Published on: October 5, 2020You may have noticed that when Xcode generates your NSManagedObject classes based on your Core Data model file, most of your managed object's properties are optional. Even if you've made them required in the model editor, Xcode will generate a managed object where most properties are optional. In this article we'll explore this phenomenon, and why it happens. Exploring generated NSManagedObject subclasses When you build a project that uses Xcode's automatic code generation for Core Data models, your NSManagedObject subclasses are generated when you build your project. These classes are written your project's Derived Data folder and you shouldn't modify...
Read more...Understanding how DispatchQueue.sync can cause deadlocks
Published on: September 21, 2020As a developer, you'll come across the term "deadlock" sooner or later. When you do, it's usually pretty clear that a deadlock is bad (the name alone implies this) and if you've experienced one in your code, you'll know that your application crashes with EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) when a deadlock occurs. A few weeks ago, I wrote about dispatching code synchronously and asyncronously. Several people pointed out that that post does not mention deadlocks. Instead of making that post longer and more complicated, I decided to make this week's post all about deadlocks and understanding what they are. If you're...
Read more...