Skip to content

Entries with the swift tag

Pull request Potential fix for invalidation crashes on composed-swift/ComposedUI

As mentioned in and there are some scenarios where the collection view’s data is out-of-sync with the data in composed.

As mentioned in calling layoutIfNeeded can trigger the data to be in sync again. In this I have added it to mappingWillBeginUpdating(_:) which appears to solve the problem.

It might be needed in replace(sectionProvider:) (because reloadData is called) and/or mappingDidInvalidate(_:) (for the same reason) but I’m still investigating.

I have validated this fix against and it fixes the crash. still needs to be investigated and may require layoutIfNeeded to be called in mappingDidInvalidate. Marking as a draft until this is checked.

Supporting Multiple Swift Package Versions Without Breaking Compatibility

The Xcode 12 beta includes Swift 5.3 but drops support for iOS 8.x. This means that Swift packages that support iOS 8 will cause a warning:

The iOS deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.0.99.

It's not possible to remove this warning within a project that depends on a Swift package with a deployment target of iOS 8, but it is possible to fix this in the dependency without removing support for iOS 8 for older versions of Swift. There are multiple way this can be accomplished.

Keep Reading

Pull request Rewrite delegates to take perform update closures on composed-swift/Composed

This is a major API change so is in a v2 branch. If we agree on a direction we could start adding PRs in to this branch.

This change would enable multiple changes to be applied at once, e.g. by requiring balanced calls to mappingWillBeginUpdating and mappingDidEndUpdating and only performing the updates when an equal number of mappingDidEndUpdating calls have been made. This could be a small performance improvement but would also improve animations.

By adding the performUpdate closure the changes to the model layer can be applied only when the consumer is expecting them, e.g. for UICollectionView this would be inside performBatchUpdates and would fix the existing crashes that occur when performing a change when there are pending layout changes.

Some tests and types have been commented out since this is more of a starting point for a discussion around the API than it is a solid implementation.

This is the closest I can see the API being (although it's still a breaking change) but maybe a bigger change would be better.

The biggest PITA is that the sections need to keep track of "current" data (e.g. what's being displayed by a collection view) and the "pending" data (e.g. what's about to be applied). I don't think this adds any memory overhead but it does add much more to the knowledge required when implementing a section.

Pull request Sort symlinks in order required for unzip on weichsel/ZIPFoundation

Changes proposed in this PR

  • Fix extraction order of symlinks

Tests performed

  • Existing tests
  • Extracting the AltServer download from

Further info for the reviewer

This needs more tests to ensure full coverage, but also to prove that this was previously broken and is now fixed.

The added function is public because I'm using it to extract a subset of the entries in the archive that contains symlinks.

Open Issues

#185, possibly #62.

Pull request ComposedSectionProvider fixes on composed-swift/Composed

These were quite hard to track down since the errors that would occur would often be visual and not a crash, although in some scenarios it did seem to trigger a crash.

I think this highlights the need for a much larger test suite.


It also made me question the insert(_:at:) functions because it's not really clear what the index is. Should it insert it at the index in the context of the sections and providers (as it does now), or just sections?

For example, with:

  • Section A
  • Section Provider
    • Section B
    • Section C
  • Section D
  • Section E

If I insert a section at index 3 should it look like:

  • Section A
  • Section Provider
    • Section B
    • Section C
  • New Section
  • Section D
  • Section E


  • Section A
  • Section Provider
    • Section B
    • Section C
  • Section D
  • New Section
  • Section E

Pull request Fix crash when performing update while animating on composed-swift/ComposedUI

The completion block is called when the animation has completed, but at the end of the updates block the data has already been updated (from the perspective of the UICollectionView).

Not calling reset() and setting defersUpdate = false could cause crashes e.g. due to changes being applied multiple times.

The best way to recreate this is to have a series of updates occur very close to each other but with the "Slow Animation" setting enabled in the simulator.

This change might also apply to table views, I have not checked.

The crash would often be along the lines of "Tried to delete section at index 11 but there were only 11 sections" or would occur in elementsProvider(for:) with the error "No UI configuration available for section 11" when performing a non-data change e.g. a reload of a section

Pull request Allow multiple cell types per section on composed-swift/ComposedUI

Sometimes it's useful to have multiple different cell types within a single section, for example to use sticky headers or to reduce to need for many layers of composition (which can be tricky to get animation right for).

This isn't a breaking change for consumers.

I think some of the naming should be improved if this were to be merged.

Draft because I want feedback on the impact of the feature itself rather than specifically the code.

Pull request Add HashableByKeyPath and Persist on SwiftPackageIndex/PackageList

The package(s) being submitted are:


I have either:

  • [x] Run swift ./validate.swift.

Or, checked that:

  • [ ] The package repositories are publicly accessible.
  • [ ] The packages all contain a Package.swift file in the root folder.
  • [ ] The packages are written in Swift 4.0 or later.
  • [ ] The packages all contain at least one product (either library or executable).
  • [ ] The packages all have at least one release tagged as a semantic version.
  • [ ] The packages all output valid JSON from swift package dump-package with the latest Swift toolchain.
  • [ ] The package URLs are all fully specified including https and the .git extension.
  • [ ] The packages all compile without errors.

Pull request Use SAMPLE_CODE_DISAMBIGUATOR for easier running on composed-swift/Composed-Demo

Config from was used to make it easier to people checking out the repo to run the sample code. Only the team needs to be changed with this config.

Pull request Check for `CollectionCoordinator` rather than self on composed-swift/ComposedUI

Using embedded collection views with each one using a CollectionCoordinator would cause an infinite loop in responds(to:).

Maybe it's better to check in responds(to:)? I don't know if there are other scenarios this could happen in.

Pull request Add GitHub actions on composed-swift/Composed

This is a copy/paste from, with a couple of small tweaks:

  • Only tests iOS; macOS, tvOS, and watchOS were removed
  • Coverage is not uploaded to Codecov; I don't have permission to add the project
  • Xcode 11.5 is used; this is the latest stable version
  • v2 of the cache action is used; this is the latest stable version

It will do the following:

  • Perform a release when a tag starting with v is pushed
    • v0* or v*- (e.g. v1.1.0-rc1) will be marked as pre-release
  • Build and upload docs to the gh-pages branch as part of releases
  • Run tests against iOS when a commit is pushed

Note that the cache is not as useful as it could be right now; Swift likes to rebuild things based on inodes so the cache is largely (maybe entirely) discarded, but will be useful in a future Swift release.

You'll need to create an orphaned gh-pages branch for the docs since I don't have permissions. I don't think it needs an initial commit, although maybe you can't push an empty branch? I've never tried.

Pull request Set `updateDelegate` when a provider invalidates on composed-swift/Composed

Basic Sections were not propagating updates if added via a call to invalidateAll. This is to address #2.

The issue can be recreated by using a SegmentedSectionProvider when switching to a segment that contains a Section (SectionProvider works I think)

This commit alone is likely not enough to fix this issue; updateDelegate should probably be set to nil for removed Sections, and should probably be set in more places.

My Swift Package Manager Release Workflow

I am currently maintaining numerous Swift Packages that don't receive a constant flow of updates, but do receive updates when new Swift updates come out, or as I think of useful additions.

To ensure that I can make some of these less frequent updates without too much friction and with confidence in their correctness I rely heavily on GitHub Actions, which I'll go over in this blog post.

Keep Reading

Capturing More Than `self`

A common pattern when using closures in Swift is to add [weak self] in the captures list to hold a weak reference to self and avoid a retain cycle. This is then often followed by the following:

guard let self = self else { return }

But I often forget that capture lists can capture other variables in the current scope, so I thought I'd highlight some other use cases.

Keep Reading

HashableByKeyPath framework release 1.0.0

Today I have released the 1.0.0 version of a Swift package that aids with adding Equatable and Hashable conformance by using KeyPaths.

The package is available on GitHub.

I created the Swift Playground that sparked this concept in December 2018, so this concept has been rattling around in my brain for a couple of years. The API has changed a lot since the original concept, but the core has stayed the same: a protocol that requires a single function to be implemented that uses KeyPaths to synthesise Equatable and/or Hashable conformance.

Keep Reading

Partial framework release 1.0.0

Today marks 1 year since I released a blog post demonstrating an implementation of Partial in Swift, and it also marks the release of the 1.0.0 version of a Swift package for Partial.

The package is available on GitHub and supports SwiftPM, Carthage, and CocoaPods.

This blog post will go over some of the changes that have been made since the original blog post, my rationale when making certain decisions, and how I have thought about maintenance. If you want to try out Partial and see how it can be used head over to the GitHub page.

Keep Reading

Partial in Swift

Structs are incredibly useful in Swift, especially when representing static read-only data. However, the values of a struct often come from multiple sources, such as view controllers, network requests, and files on disk, which can make the creation of these structs cumbersome.

There are numerous methods to work around this, but each have their downsides. One of these methods is to change the struct to a class and update the properties to vars, but this removes the advantages of read-only structs. Another is to make a "builder" object, but the API of this object must be kept in-sync with the object is wraps.

Partial eliminates these problems by providing a type-safe API for building structs by utilising generics and KeyPaths. Although I learned of the concept of Partial through TypeScript – which [provides Partial as a built-in type][1] – the Swift implementation supports many more use cases.

Keep Reading