Swift
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...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...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...Dispatching async or sync? The differences explained
Published on: August 31, 2020When writing iOS apps, we regularly run into code that is asynchronous. Sometimes you know you're writing something that will run asynchronously and other times you're passing a completion handler to code that may or may not run asynchronously on a different dispatch queue. If you're familiar with using DispatchQueue.main, you have probably written code like this: DispatchQueue.main.async { // do something } And while writing this, you may have encountered a second method on DispatchQueue.main called sync. In this week's post I will explain the difference between sync and async, and you will learn when you might want to...
Read more...Understanding Swift’s OptionSet
Published on: August 18, 2020Every once in a while I look at a feature in Swift and I fall down a rabbit hole to explore it so I can eventually write about it. The OptionSet protocol is one of these Swift features. If you've ever written an animation and passed it a list of options like this, you have already used OptionSet: UIView.animate( withDuration: 0.6, delay: 0, options: [.allowUserInteraction, .curveEaseIn], animations: { myView.layer.opacity = 0 }, completion: { _ in }) You may not have realized that you weren't passing an array to the options parameter, and that's not surprising. After all, the options...
Read more...Using Codable with Core Data and NSManagedObject
Published on: August 3, 2020If you've ever wanted to decode a bunch of JSON data into NSManagedObject instances you've probably noticed that this isn't a straightforward exercise. With plain structs, you can conform your struct to Codable and you convert the struct from and to JSON data automatically. For an NSManagedObject subclass it's not that easy. If your Core Data data model is configured to automatically generate your entity class definitions for you (which is the default), you may have tried to write the following code to conform your managed object to Decodable: extension MyManagedObject: Decodable { } If you do this, the compiler...
Read more...Setting up a Core Data store for unit tests
Published on: July 27, 2020Unit testing is an important skill in the toolbox of any engineer. Knowing how to write a reliable, robust test suite helps you write reliable and robust code. If you've followed my introduction to unit testing part one and part two, or if you're experienced with unit testing you know that your tests should run isolated from any other tests. You also know that you should make sure that your test relies on as few external dependencies as possible. When you want to test your Core Data code, it might not be immediately obvious how you can test your Core...
Read more...How to change a UICollectionViewListCell’s separator inset
Published on: June 25, 2020In WWDC2020's session Lists in UICollectionView a slide is shown where a UICollectionViewListCell's separator inset is updated by assigning a new leading anchor to separatorLayoutGuide.leadingAnchor. Unfortunately, this doesn't work in when you try to do it. To set the separator inset for a UICollectionViewListCell you can update the leading anchor constraint by overriding updateConstraints in a UICollectionViewListCell subclass. Setting the anchor in init will cause the system to override your custom anchor leaving you with the default inset. override func updateConstraints() { super.updateConstraints() separatorLayoutGuide.leadingAnchor.constraint(equalTo: someOtherView.leadingAnchor, constant: 10).isActive = true } You can set the leadingAnchor constraint just like you would...
Read more...How to add a custom accessory to a UICollectionViewListCell?
Published on: June 24, 2020Apple provides several accessory types that you can use to apply certain affordances to a UICollectionViewListCell. However, sometimes these options don't suit your needs and you're looking for something more customizable. To add a custom accessory to a list cell instead of a standard one, you use the .custom accessory type. The initializer for this accessory takes a UICellAccessory.CustomViewConfiguration that describes how your accessory should look and where it's positioned. Let's dive right in with an example: // create the accessory configuration let customAccessory = UICellAccessory.CustomViewConfiguration( customView: UIImageView(image: UIImage(systemName: "paperplane")), placement: .leading(displayed: .always)) // add the accessory to the cell...
Read more...How to add accessories to a UICollectionViewListCell?
Published on: June 24, 2020In iOS 14 Apple added the ability for developers to create collection views that look and feel like table views, except they are far, far more powerful. To do this, Apple introduced a new UICollectionViewCell subclass called UICollectionViewListCell. This new cell class allows us to implement several tableviewcell-like principles, including accessories. Adding accessories to a cell is done by assigning an array of UICellAccessory items to a UICollectionViewListCell's accessories property. For example, to make a UICollectionViewListCell show a disclosure indicator that makes it clear to a user that they will see more content if they tapp a cell, you would...
Read more...