Recent articles
Jump to a random postWWDC Notes: Bring Core Data concurrency to Swift and SwiftUI
Published on: June 10, 2021Persistence everywhere Core Data takes care of many complexities to persist data. It converts in-memory graph to persisted data and takes care of all kinds of complex tasks like memory management. Core Data works on all platforms, and it’s great in Swift. Apple’s been working to make Core Data better with Swift over the years. Core Data has always cared about running code concurrently. Swift concurrency Sample app The sample app loads data from the background and persist it. Eventually it updates the view context. Insertion is done with bgctx.performAndWait() and a batch insert. performAndWait will block the calling thread...
Read more...WWDC Notes: Discover concurrency in SwiftUI
Published on: June 9, 2021When performing slow work, you might dispatch off of the main queue. Updating an observable object off of the main queue could result in this updating colliding with a “tick” of the run loop. This means that SwiftUI receive an objectWillChange, and attempt to redraw UI before the underlying value is updated. This will lead to SwiftUI thinking that your model is in one state, but it’s in the next. SwiftUI needs to have objectWillChange->stateChange->runloop tick in this exact order. Running your update on the main actor (or main queue pre async/await) will ensure that the state change is completed...
Read more...WWDC Notes: Meet AsyncSequence
Published on: June 9, 2021Map, filter, reduce, dropFirst all work in async sequences: for try await someThing in async.dropFirst() { } For example. AsyncSequence suspends on each element and receives values asynchronously from the iterator. AsyncSequences either complete with success or stop when an error is thrown. Implementing an AsyncSequence follows all the rules that a normal sequence follows. Its next() returns nil when it’s completed for example. An async iterator also consumes its underlying collection. Things like break and continue work in async sequences too. You can cancel an iteration by holding on to its Task.Handle when you wrap it in async: let...
Read more...WWDC Notes: What’s new in SwiftUI
Published on: June 9, 2021A good way to get started with SwiftUI is to use it for new features. SwiftUI can be mixed in with UIKit and AppKit code. It also allows you to expand into new platforms, like macOS, with little to no work. Essentially, try to do new work with SwiftUI whenever you can. Better lists SwiftUI can load images async with the new AsyncImage. This takes a URL and shows a placeholder by default. You can pass a closure to configure the loaded image with modifier, and to set a custom placeholder. There’s a new refreshable modifier. This modifier takes a...
Read more...WWDC Notes: Protect mutable state with Swift actors
Published on: June 8, 2021Data races make concurrency hard. They occur when two threads access the same data and at least one of them is a write. It’s trivial to write a data race, but it’s really hard to debug. Data races aren’t always clear, aren’t always reproducible, and might not always manifest in the same way. Shared mutable state is needed for a data race to occur. Value types don’t suffer from data races due to the way they work; they’re copied. When you pass an array around, copies are created. This is due to array’s value semantics. Even an object that’s a...
Read more...WWDC Notes: Explore structured concurrency in Swift
Published on: June 8, 2021Structured programming uses a static scope. This makes it very easy to reason about code and its flow. Essentially making it trivial to understand what your code does by reading it from top to bottom. Asynchronous and concurrent code do not follow this structured way of programming; it can’t be read from top to bottom. Asynchronous functions don’t return values because the values aren’t ready at the end of the function scope. This means that the function will communicate results back through a closure at a later time. It also means that we don’t use structured programming for error handling...
Read more...WWDC Notes: Meet async await in Swift
Published on: June 8, 2021There are tons of async await compatible functions built-in into the SDK. Often with an async version and completion handler based function. Sync code blocks threads, async code doesn’t When writing async code with completion handlers you unblock threads but it’s easy to not call your completion handlers. For example when you use a guard let and only return in the else clause. Swift can’t enforce this in the compiler which can lead to subtle bugs. You can’t throw errors from completion handlers. We usually use Result for this. This adds “ceremony” to our code which isn’t ideal. Futures can...
Read more...Thoughts on Combine in an async/await world
Published on: June 8, 2021When Apple announced their own Functional Reactive Programming framework at WWDC 2019 I was super excited. Finally, a simplified, easy to use framework that we could use to dip our toes in FRP. What made it even better is that SwiftUI makes heavy use of Combine, which means that Apple had to buy in to the technology themselves. This made it seem unlikely that Apple would abandon the technology any time soon. Then WWDC 2020 came around and there weren’t any meaningful changes to Combine. It was hardly even mentioned in the sessions. To me, this was a signal that...
Read more...The iOS Developer’s guide to WWDC 2024
Published on: May 31, 2021This post was originally published in 2021 and has been touched up for 2024 WWDC is always an exciting time for iOS engineers. It's the one week a year where we're all newcomers to a whole range of features and APIs that Apple has just unleashed upon the world through their latest Xcode, macOS, iOS, tvOS, iPadOS, visionOS, and watchOS betas. The entire community comes out of hiding and we all come together to share thoughts, experiences, opinions, and findings. For a whole week, Apple releases dozens of sessions on different topics, and we all scramble to watch them as...
Read more...What’s the difference between a singleton and a shared instance in Swift?
Published on: April 19, 2021A common pattern on iOS, and in Swift, is to define an instance of an object that you can access from any place in your app. Common examples are URLSession.shared, FileManager.default, and UserDefaults.standard. These objects can all be considered shared instances, or globally available instances. Defining a shared instance is commonly done as follows: struct DataProvider { static let shared = DataProvider() // useful properties and methods } It's common for developers to call this a singleton, or a singleton instance. The singleton pattern is a pattern that allows developers to specify an object that can only ever have one...
Read more...