This project is a sample app to practice with Swift Concurrency actors having to serialize the high-frequency access of multiple producers (Async Sequences) into a shared resource container.
Several producers are trying to add pixels (position and color) into a 2D grid.
- These producers conform to AsyncSequence.
- There"s an image serializer, an actor, that synchronizes access to the 2D image since all producers are concurrent. Coordinating everything is the PaintingProcess class, which creates an async cancellable execution context. Inside, there"s a task group with all producers as subtasks.
- Whenever the presenter"s array of colors changes, only the appropriate views will be re-computed. However, this is not enough to prevent a poor refresh performance. See the next point.
- Since the producers are yielding values frequently, their corresponding updates to the UI will keep the main thread too busy, affecting the scrolling performance. The solution is to throttle these updates to a rate that allows the main thread to still take on other events from the RunLoop, like scrolling events.
- In order to provide preview-specific presenters, there"s a GridViewPresenter that all presenters would conform to, but it has associated types because it inherits from ObservableObject. The solution I went for was to create an AnyGridViewPresenter type eraser.
- iOS 15 material blurred backgrounds.
- Support for Light and Dark modes.
- Dependency injection using Resolver.