[RIBs] Update: I’m investigating Swift 6.2 concurrency isolation in RIBs
Prepping a framework for Swift Concurrency is not as trivial as it might seem. It’s hard to strike a balance between the new features and breaking changes.
Recently, I’ve been working on RIBs modernization and specifically on Swift 6.2 support in RIBs. There was a issue raised in the RIBs repo https://github.com/uber/RIBs-iOS/issues/43 asking about some of the warnings associated with Main actor-isolated property ‘listener’ cannot be used to satisfy nonisolated protocol requirement or similar warning.
This compiler warning (or compiler error, depending on how severe you set your settings) occurs when the framework is used in a Swift 6.2 project where the default concurrency isolation has changed. Essentially, now, if you do not explicitly specify otherwise, if your code is called from the main thread, from things like UIKit’s view controllers or from SwiftUI, you will get a bunch of warnings that you shouldn’t be doing so.
RIBs is a comprehensive architecture and framework and it addresses or touches all the high level aspects and layers of your application.
There are a lot of parts to it, but at the end of the day, things that need to be on the main thread are those that directly touch UI. Basically it’s the view layer composed of the view objects (UIViews, SwiftUI views, UIViewControllers, etc.) and presenters (ViewController in most cases or a standalone Presenter object implementing Presentable interface) + some aspects of Routing/Routers that touch the view for navigation (specifically ViewableRouter and not the Router).
Now, the theory is that we can just mark the things we need to be on the main thread with @MainActor and that’s it, where everything would just magically compile and give you appropriate compiler time warnings. But in reality, it is of course much more complicated and nuanced than that, especially with a framework that has high adoption and usage and is mission critical. To add Swift 6.2 concurrency isolation support, we want to make the minimum amount of changes and hopefully not introduce any breaking changes or compiler warnings (or a minimum amount of those) to the users of the framework as the migration could be a nightmare.
So, this is why I’ve been heads down figuring out how stricter Swift 6.2 compiler time rules for concurrency actually work in practice and what implications they have for RIBs framework and codebases that use it.
So far, marking things explicitly, where needed with nonisolated and @MainActor seems to be working… but I need to do more thorough testing. I’m in the beginning of my research so I don’t have all the answers yet but I’ll keep everyone posted on the findings.