Monday Feb 27, 2023
There are some episode spoilers contained in this announcement!
We’ve been teasing navigation tools for the Composable Architecture for a long time, and been working on the tools for even longer, but it is finally time to get a preview of what is coming to the library.
The tools being previewed today include what has been covered in our navigation
series so far
(episodes #222,
#223,
#224), as well as a few tools that will be coming in
the next few episodes. In particular, this includes the tools for dealing with alerts,
confirmation dialogs, sheets, popovers, fullscreen covers, pre-iOS 16 navigation links, and
navigationDestination
. Notably, this beta does not currently provide the tools for the
iOS 16 NavigationStack
, but that will be coming soon.
All of these changes are mostly backwards compatible with the most recent version of TCA (version 0.51.0 right now), which means you can point any existing project to the beta branch to get a preview of what the tools have to offer. If you experience any compiler errors please let us know.
We aren’t going to give a detailed overview of the tools in this announcement and how we motivated and designed them (that’s what the episodes are for 😀), but most of the case studies and demos in the repo have been updated to use the new tools and there is an extensive test suite. There hasn’t been much documentation written yet, but that will be coming soon as the episode series plays out.
Here is a very quick overview of what you can look forward to:
When a parent feature needs to navigate to a child feature you will enhance its domain
using the new @PresentationState
property wrapper and PresentationAction
wrapper type:
struct Parent: ReducerProtocol {
struct State {
@PresentationState var child: Child.State?
…
}
enum Action {
case child(PresentationAction<Child.Action>)
…
}
…
}
Then you will make use of the new, special ifLet
reducer operator that can single out
the presentation state and action and run the child feature on that state when it is
active:
var body: some ReducerProtocolOf<Self> {
Reduce {
…
}
.ifLet(\.$child, action: /Action.child) {
Child()
}
}
That is all that is needed as far as the domain and reducer is concerned. The ifLet
operator has been with the library since the beginning, but is now enhanced with super
powers, including automatically cancelling child effects when the child is dismissed,
and a lot more.
There is one last thing you need to do, and that’s in the view. There are special
overloads of all the SwiftUI navigation APIs (such as .alert
, .sheet
, .popover
,
.navigationDestination
etc.) that take a store instead of a binding. If you provide a
store focused on presentation state and actions, it will take care of the rest. For
example, if the child feature is shown in a sheet, you will do the following:
struct ParentView: View {
let store: StoreOf<Parent>
var body: some View {
List {
…
}
.sheet(
store: self.store.scope(state: \.$child, action: Parent.Action.child)
) { store in
ChildView(store: store)
}
}
}
And that is basically it. There’s still a lot more to the tools and things to learn, but we will leave it at that and we encourage you to explore the branch when you get a chance.
As you may have heard
recently we
have a 1.0 preview available to everyone who wants a peek at what APIs will be renamed and
removed for the 1.0 release. Currently that branch is targeting main
, but soon it will
target this navigation-beta
branch, which means you can simultaneously see how to
modernize your codebase for the 1.0 and check out the new navigation tools.
To give the beta a shot, update your SPM dependencies to point to the navigation-beta
branch:
.package(
url: "https://github.com/pointfreeco/swift-composable-architecture",
branch: "navigation-beta"
),
This branch also includes updated demo applications using these APIs, so check them out if you’re curious!
We really think these tools will make TCA even more fun and easier to use! If you take things for a spin, please let us know (via Twitter, Mastodon or GitHub discussions) if you have any questions, comments, concerns, or suggestions!
Monday Feb 13, 2023
We are very excited to officially share a preview of what 1.0 will bring to the Composable Architecture. We want to be clear upfront that there are no episode or library spoilers in this post, and we are not yet announcing a beta for the navigation tools even though we have started that series. That beta will come in a few weeks.
The 1.0 of the library is something we outlined 4 months ago, and we are now officially starting the process. In a nutshell, 1.0 does not add any actual new features to the library but instead finally cleans up cruft that has accumulated over the years, such as removing most of the 1,100 lines of deprecations and finally renaming ReducerProtocol
to Reducer
.
We want to reiterate: 1.0 of the Composable Architecture is not a grand rethinking of the library or a feature-rich release. It is merely a breaking change to get rid of tools that have been long deprecated (some of them have been deprecated for years) and to give other tools their proper names.
So then, what is the 1.0 “preview”? It is a branch that you can target today if you want to get a head start on preparing for 1.0.
The branch we are releasing is prerelease/1.0
. It is a mostly backwards-compatible version of the library that we will keep up-to-date with the latest release from main
, but it makes a few important breaking changes:
For reducers:
Reducer
now refers to the reducer protocol, not the struct that is generic over state, action and environment.ReducerProtocol = Reducer
has been added.So, this change is only a breaking change if you are still using the old Reducer
type alias that refers to the AnyReducer
struct. If you are on the ReducerProtocol
, which has been out for 4 months, then you should be good to go. Or, if you have updated your uses of Reducer
to AnyReducer
, you should only have deprecation warnings.
For effects:
Effect
type now has one single generic for Output
. The Failure
generic has been removed.EffectTask = Effect
has been added.So, this change is only a breaking change if you still refer to the old Effect
type alias. If you are using the EffectTask
type, which has been suggested for over 4 months, then you should be good to go.
Even though there are some breaking changes, the fixes are usually quite simple. For example:
If you are still using the old Reducer
struct type alias, you can simply rename it to AnyReducer
. E.g:
-Reducer<MyState, MyAction, MyEnvironment>
+AnyReducer<MyState, MyAction, MyEnvironment>
If you are using the Effect
type with two generics, you can simply rename them to EffectPublisher
. Or, better yet, if the Effect
type with two generics has a failure type of Never
, you can simply rename it to EffectTask
and remove the failure generic entirely. E.g.:
// For effects that can fail:
-Effect<MyAction, Error>
+EffectPublisher<MyAction, Error>
// For effects that cannot fail:
-Effect<MyAction, Never>
+EffectTask<MyAction>
If your project has already prepared for the two breaking changes mentioned above, you may benefit from targeting the prerelease/1.0
branch. That is:
Reducer
type, and have either migrated all of your project’s reducers to take advantage of the ReducerProtocol
, or you have at the very least renamed all instances of Reducer
to AnyReducer
.Effect
type, and have renamed all instances to EffectTask
or EffectPublisher
(ideally preferring EffectTask
when the failure type is Never
).By targeting prerelease/1.0
you will get a hard-deprecated view of all APIs that have been soft-deprecated over the past months. If you have no deprecations, you are in good shape for 1.0. If you have deprecations, this means you can begin to incrementally chip away at them to prepare for 1.0’s release in the coming months.
Unless you are fully committed to living on the edge and working with beta software, we do not recommend fully adopting the prerelease/1.0
branch, nor do we recommend adopting the Reducer
and Effect
renames that come along with it. If you are committed, though, we value your feedback! Please discuss any issues that crop up in these forums, and we’ll do our best to make the experience and smooth as possible for a beta.
For those that do adopt the prerelease/1.0
branch, we also do not recommend literally tracking prerelease/1.0
, as that will continually track every single change to the branch. Instead, we recommend pinning to an exact Git SHA, and updating this SHA when you are prepared for the changes that come along with it.
In the near future, as we get closer to the official 1.0 release, we may introduce additional branches that you can target to help you update your codebase to be 1.0 compliant. For example, we will have a branch to track all forthcoming “0.x” releases, which will include all of the new navigation tools, but will also be 100% backwards-compatible with the library today.
The navigation tools that we have just begun covering are coming soon, but not right now. We will be opening a public beta in the coming weeks just as we did with async/await effects and the Reducer
protocol. This will give you a chance to play around with the tools before their final release and provide feedback.
Our plan is for the navigation beta to work both with main
, which means it will be 100% backwards compatible with your project today, and also work with prerelease/1.0
. There will be more information on that soon!
Please give the prerelease/1.0
branch a spin and let us know what your feedback is. Consider the branch a “beta”: it may have mistakes, deprecations may behave in strange ways, etc. If you encounter any issues, let us know!
We are excited to finally bring the Composable Architecture to 1.0, though, and we have more big announcements coming soon.
Monday Feb 6, 2023
Last week we hosted our first ever livestream. In an hour and a half we discussed some
of the tools that our Dependencies
library comes with that we didn’t have time to discuss in episodes, and we live refactored
our open-source Standups to use the new iOS 16
NavigationStack
. We also answered 18 viewer questions, and just have 94 more left in the
queue. 😅
We are now hosting that recorded livestream on our site, and it is available free for everyone to watch. We have taken the time to clean things up a bit and make it more digestibile for viewing in a non-live manner, including:
Future livestreams will be for subscribers-only, so if you found this video interesting, be sure to subscribe today!
Sunday Jan 29, 2023
We launched Point-Free 5 years ago today! There's still so much more we want to do, but we'll start with two things that many people have asked for: livestreams and a community Slack!
Friday Jan 27, 2023
A call to action: how would *you* rebuild Apple's "Scrumdinger" application? We've shown our take on modern SwiftUI, but we would love to see how you tackle the same problems. Don't like to use a observable objects for each screen? Prefer to use @StateObject instead of @ObservedObject? Want to use an architectural pattern such as VIPER? Have a different way of handling dependencies? Please show us!
Friday Jan 27, 2023
We show how the investments we made in the first 4 parts of this series of posts pays off when it comes to testing. Each decision helps make it possible to write incredibly nuanced tests that exercise many different user flows in the application.
Thursday Jan 26, 2023
Learn about what dependencies are and why they wreak so much havoc in a code base, and then see what can be done to take back control over dependencies rather than let them control you.
Wednesday Jan 25, 2023
Learn how to best leverage optionals and enums when modeling state-driven navigation in SwiftUI.
Tuesday Jan 24, 2023
Learn how to make lists of data in your SwiftUI applications safer and more performant by scrapping plain arrays and embracing "identified arrays".
Monday Jan 23, 2023
We are celebrating the conclusion of our 7-part series on Modern SwiftUI by releasing a blog post every day this week, detailing an area of SwiftUI development that can be modernized. We begin by exploring ways to facilitate parent-child communication in SwiftUI in a safe and ergonomic manner.
Monday Jan 9, 2023
We are open sourcing a new dependency management system for Swift. Take control of your dependencies, don't let them control you.
Monday Dec 19, 2022
Point-Free year in review: 45 episodes, 150K visitors, dozens of open source releases, and more!
Thursday Dec 8, 2022
In time for Advent of Code, a new release of swift-parsing brings several quality-of-life improvements to Swift 5.7 users.
Monday Nov 21, 2022
Navigation in SwiftUI can be complex, but it doesn't have to be that way. We are releasing a new version of our SwiftUI Navigation library that makes it easier to use NavigationStack, alerts, confirmation dialogs, and even fixes a few bugs in SwiftUI.
Monday Oct 31, 2022
Exhaustive testing is one of the most powerful features of the Composable Architecture, but it can also be cumbersome for large, highly composed features. Join us for an overview of the "why" and "how" of exhaustive testing, as well as when it breaks down, and how non-exhaustive testing can help.
Monday Oct 24, 2022
Today we are open sourcing swift-clocks, a collection of tools that make working with Swift concurrency more testable and more versatile.
Monday Oct 10, 2022
Today we are releasing the biggest update to the Composable Architecture ever, completely reimagining how features are built with the library.
Thursday Sep 8, 2022
The latest release of the Composable Architecture brings a number of performance improvements to its tools, and best of all, most of the changes came from collaboration with people in the TCA community! 🤗
Monday Aug 8, 2022
Today we are releasing the biggest update to the Composable Architecture since it's first release over 2 years ago. The library has all new concurrency tools allowing you to construct complex effects using structured concurrency, tie effect lifetimes to view lifetimes, and we accomplish all of this while keeping your code 100% testable. We think it might even be the best way to test concurrent code in SwiftUI applications. 😇
Tuesday Jul 12, 2022
Learn how to use Swift 5.7's new existential type super powers to encode and decode type-erased values.
Wednesday Jun 29, 2022
We've added a new tool to our XCTest Dynamic Overlay library, which makes it easier to construct stronger dependencies for tests.
Monday May 2, 2022
Introducing new routing libraries that make client-side and server-side routing easy with more type safety and less fuss.
Monday Apr 11, 2022
A new release of swift-parsing brings printing capabilities to your parsers for transforming structured data back into unstructured data.
Monday Feb 14, 2022
A new release of swift-parsing that brings delightful and informative error messaging to parser failures.
Wednesday Feb 9, 2022
Today we are releasing 0.6.0 of our swift-parsing library that changes its backtracking behavior.
Monday Jan 24, 2022
Today we are releasing 0.5.0 of our swift-parsing library, which leverages result builders for creating complex parsers with a minimal amount of syntactic noise. Learn how in this week's blog post, and give the library a spin today!
Monday Jan 3, 2022
Runtime warnings in libraries are a great way to notify your users that something unexpected has happened, or that an API is being used in an incorrect manner. In this post we give an overview of some techniques that can be employed easily today, as well as discuss a technique for surfacing runtime warnings that is both very visible and unobtrusive.
Wednesday Dec 22, 2021
Point-Free year in review: 42 episodes, 72k visitors, 5 new open source projects, and more!
Tuesday Nov 16, 2021
Today we are open sourcing SwiftUI Navigation, a collection of tools for making SwiftUI navigation simpler, more ergonomic and more precise.
Tuesday Oct 26, 2021
Today we are excited to announce that you can now gift a Point-Free subscription to your friends, colleagues and loved ones.
Wednesday Sep 15, 2021
We're celebrating the release of Xcode 13 by making all of our WWDC 2021 videos free! Explore SwiftUI's new refreshable and FocusState APIs, both in the context of vanilla SwiftUI and the Composable Architecture, and learn how to build a map-powered application from scratch using the new searchable API.
Monday Sep 6, 2021
Today we are improving the Composable Architecture's first-party support for SwiftUI bindings with a safer, even conciser syntax.
Monday Aug 23, 2021
Today we are open sourcing Custom Dump, a collection of tools for debugging, diffing, and testing your application's data structures.
Wednesday Jul 14, 2021
The past 3 weeks we've shipped updates to 3 of our libraries, focused on improving the performance of your Composable Architecture applications, and more!
Monday Jul 12, 2021
Today we are open sourcing Identified Collections, a library of data structures for working with collections of identifiable elements in a performant way.
Monday Jun 14, 2021
We are adding new tools for handling enum state in the Composable Architecture, with a focus on safety and performance.
Wednesday May 12, 2021
This past month we released four completely free videos dedicated to diving into the real-world Swift code base of an iOS game we recently launched and open sourced: isowords.
Monday Mar 22, 2021
We're open sourcing a library that makes it easier to be more exhaustive in writing tests.
Wednesday Mar 17, 2021
We're open sourcing the entire code base to our newly released iOS word game, isowords!
Wednesday Mar 17, 2021
We are excited to release isowords to the App Store, a new word search game for your phone. Download today!
Monday Mar 8, 2021
Composable Architecture 0.16.0 comes with significant improvements to its testing capabilities for tracking down effect-related failures.
Monday Feb 1, 2021
Today we are releasing first-party support for concisely handling form data in the Composable Architecture.
Wednesday Dec 23, 2020
The Composable Architecture, dependency management, parsers, Combine schedulers and more! Join us for a review of everything we accomplished in 2020!
Monday Dec 21, 2020
Today we are open sourcing Parsing, a library for turning nebulous data into well-structured data, with a focus on composition, performance, and generality.
Tuesday Jun 30, 2020
Today we are releasing a new version of the Composable Architecture with helpers that make working with SwiftUI alerts and action sheets a breeze.
Monday Jun 22, 2020
We are releasing our second mini-library for the Composable Architecture, which makes it easy to use Core Motion.
Monday Jun 15, 2020
Today we are open-sourcing CombineSchedulers, a library that introduces a few schedulers that makes working with Combine more testable and more versatile.
Wednesday May 27, 2020
Today we are releasing first-party support for instrumenting features built in the Composable Architecture.
Wednesday May 20, 2020
We are releasing a mini-library that makes it easy to use Core Location inside the Composable Architecture.
Tuesday May 12, 2020
Regional discounts takes 50% off a monthly or yearly personal subscription to anyone whose credit card is issued from a particular list of countries.
Monday May 4, 2020
Today we are releasing the Composable Architecture as an open-source library. It is a way to build applications in a consistent and understandable way, with composition, testing and ergonomics in mind.
Wednesday Mar 11, 2020
After over two years and nearly 100 episodes we are finally launching episode collections on Point-Free!
Friday Feb 21, 2020
Today we're excited to announce support for referral bonuses! When friends and colleagues of yours subscribe to Point-Free with your referral link, both of you will get one month free.
Tuesday Feb 4, 2020
Today we are open sourcing CasePaths, a library that introduces the power and ergonomics of key paths to enums!
Monday Dec 30, 2019
Random number generators, parsers, SwiftUI, composable architecture and more! Join us for a review of everything we accomplished in 2019!
Monday Dec 23, 2019
Snapshot testing gives us broad test coverage on our SwiftUI views with very little up front work.
Wednesday Nov 20, 2019
Two free videos exploring Apple's new Combine framework, its core components, and how to integrate it in your code.
Thursday Nov 7, 2019
How to enrich snapshot testing strategies with additional behavior using higher-order constructions.
Tuesday Jul 30, 2019
Xcode 11 beta 5 has brought lots of changes to SwiftUI, and we'd like to take a moment to provide corrections to our episodes based on these changes.
Thursday May 9, 2019
Point-Free now supports enterprise subscriptions, making it easier than ever to manage a team subscription for larger organizations! For a fixed yearly rate, everyone with an email from your company's domain will get instant access to everything Point-Free has to offer. Contact us for more info!
Monday Apr 29, 2019
We wanted to make Swift enum data access as ergonomic as struct data access, so today we are open sourcing a code generation tool to do just that!
Monday Mar 18, 2019
Today we are open sourcing Gen: a lightweight wrapper around Swift's randomness API's that makes randomness more composable, transformable and controllable!
Tuesday Jan 8, 2019
Announcing swift-html 0.2.0: support for CocoaPods, Carthage, SnapshotTesting, and more!
Wednesday Dec 19, 2018
41 episodes, 19 hours of video, 25 blog posts, 8 open source libraries, 3.8K stars, 36K visitors, and we’re just getting started?
Monday Dec 3, 2018
Today we are open sourcing SnapshotTesting 1.0: a modern, composable snapshot testing library built entirely in Swift!
Monday Oct 29, 2018
We've seen that contramap is a powerful operation, but the name isn't fantastic. We propose a much more intuitive name for this operation, and in doing so make our code much easier to read.
Tuesday Oct 9, 2018
APIs that interact with the outside world are unpredictable and make it difficult to test and simulate code paths in our apps. Existing solutions to this problem are verbose and complicated, so let's explore a simpler solution by embracing singletons and global mutation, and rejecting protocol-oriented programming and dependency injection.
Monday Oct 8, 2018
Follow along with the newest Point-Free episodes using your favorite podcast app. We now support podcast-friendly RSS feeds for viewing all of our videos.
Thursday Sep 20, 2018
Let's create a random Zalgo text generator using the simple Gen type we defined in this week's episode!
Thursday Sep 13, 2018
Today we're releasing a Kitura plug-in for rendering type-safe HTML. It provides a Swift compile-time API to HTML that prevents many of the runtime errors and vulnerabilities of traditional templated HTML rendering.
Thursday Sep 13, 2018
Today we're releasing a Vapor plug-in for rendering type-safe HTML. It provides a Swift compile-time API to HTML that prevents many of the runtime errors and vulnerabilities of traditional templated HTML rendering.
Wednesday Sep 12, 2018
Today we are open sourcing a new library for building HTML documents in Swift. It's extensible, transformable, type-safe, and provides many benefits over templating languages.
Friday Aug 17, 2018
Today we are releasing Overture 0.3.0 with a bunch of useful zip functions.
Friday Aug 17, 2018
Today we are open sourcing Validated, a tiny functional Swift library for handling multiple errors: functionality that you don't get from throwing functions and the Result type.
Thursday Aug 16, 2018
Today we solve the exercises to the third and final part of our introductory series on zip.
Wednesday Aug 15, 2018
Today we solve the exercises to the second part of our introductory series on zip.
Tuesday Aug 14, 2018
Today we solve the exercises to the first part of our introductory series on zip.
Monday Aug 6, 2018
Get 50% off your Point-Free subscription with proof of enrollment at a university or coding school.
Monday Jul 30, 2018
This week marks 6 months since our launch, and we’re making one of our most popular episodes free to the public!
Monday Jul 2, 2018
What happens when we combine Swift's conditional conformance with codability?
Monday Jun 25, 2018
Today we are open sourcing NonEmpty, a Swift library for modeling non-empty collection types. This small library can help make your code safer and more expressive with very little work.
Monday Jun 18, 2018
Let's create a type-safe interface for dealing with seconds and milliseconds in our programs. We'll use the `Tagged` type, which allows us to construct all new types in a lightweight way.
Wednesday May 30, 2018
We are making one of our early episodes, “UIKit Styling with Functions”, free to everyone today! It’s a seminal episode that sets the foundation for some later work in the Point-Free series.
Tuesday May 15, 2018
Announcing Overture 0.2.0! This release is all about setters: functions that allow us to build complex transformations out of smaller units.
Monday May 7, 2018
This week we solve the exercises from our episode on contravariance, because there were _a lot_ of them!
Monday Apr 23, 2018
Let’s look at a real world use for algebraic data types. We will refactor a data type that is used in the code on this very site so that the invalid states are unrepresentable by the compiler.
Monday Apr 23, 2018
Today we are excited to announcement launch of Point-Free Pointers, a blog to supplement our video series for all the content we couldn’t fit in. Expect to find regularly postings here that dive even deeper into functional programming, showing real world use cases and more!