SKCDataSourcePrefetchingForward in SectionKit: Routing UICollectionView Prefetch Events
SKCDataSourcePrefetchingForward is a concrete UICollectionViewDataSourcePrefetching implementation that routes iOS prefetch callbacks to SectionKit sections, enabling asynchronous data loading while maintaining clean separation between UIKit and your section logic.
Located in the linhay/sectionkit repository, SKCDataSourcePrefetchingForward acts as the central router that bridges UIKit's collection view prefetching system with SectionKit's section-based architecture. The class ensures that when a UICollectionView requests data ahead of time—such as images or remote JSON—your sections handle the workload without directly conforming to UIKit protocols.
What is SKCDataSourcePrefetchingForward?
SKCDataSourcePrefetchingForward is an NSObject subclass residing in [SKCDataSourcePrefetchingForward.swift](https://github.com/linhay/sectionkit/blob/main/Sources/SectionKit/CollectionBaseProtocol/SKCDataSourcePrefetching/SKCDataSourcePrefetchingForward.swift). It conforms to UICollectionViewDataSourcePrefetching and serves as a multicast router, forwarding prefetch requests to any number of registered handlers and observers.
The class maintains two internal arrays:
forwardItems: Objects conforming toSKCDataSourcePrefetchingForwardProtocolthat handle the actual prefetch work.observerItems: Objects conforming toSKCDataSourcePrefetchingObserverProtocolthat receive side-effect notifications (e.g., analytics) without blocking the forwarding chain.
Architectural Role in SectionKit
The prefetching architecture decouples the collection view from section implementations through four distinct layers:
- Collection View (
UICollectionView): TriggersprefetchItemsAtandcancelPrefetchingForItemsAton itsprefetchDataSource. - SKCDataSourcePrefetchingForward: Receives UIKit callbacks and dispatches them to registered forwards using a chain-of-responsibility pattern.
- SKCDataSourcePrefetching: A concrete forward handler (defined in
SKCViewDataSourcePrefetching.swift) that aggregates index paths by section and invokesprefetch(at:)on individual sections. - Section (e.g.,
SKCSingleTypeSection): ImplementsSKCViewDataSourcePrefetchingProtocolto perform actual data loading or cancellation.
SKCManager instantiates and wires these components together during setup, injecting the concrete prefetch handler into the forward.
How Prefetching Works Under the Hood
Registration in SKCManager
The wiring occurs inside SKCManager.setup(sectionView:). The manager creates a lazy SKCDataSourcePrefetchingForward instance and assigns it as the collection view's prefetchDataSource, then registers SectionKit's internal prefetch handler:
// SKCManager.swift
public private(set) lazy var prefetchForward = SKCDataSourcePrefetchingForward()
public lazy var prefetching = SKCDataSourcePrefetching(dataSource: publishers)
func setup(sectionView: UICollectionView) {
sectionView.prefetchDataSource = prefetchForward
prefetchForward.add(prefetching)
}
The Forwarding Chain
When UIKit calls prefetchItemsAt, the forward iterates its forwardItems in reverse order, querying each item via a find closure that returns an SKHandleResult. The first handler returning .handle stops the chain, preventing duplicate work:
// SKCDataSourcePrefetchingForward.swift
public func collectionView(_ collectionView: UICollectionView,
prefetchItemsAt indexPaths: [IndexPath]) {
let value = find { $0.collectionView(collectionView,
prefetchItemsAt: indexPaths) }
observe { $0.collectionView(collectionView,
prefetchItemsAt: indexPaths, value: value) }
}
After the forward completes, all observerItems receive the same index paths for logging or metrics.
Index Path Aggregation
Before reaching individual sections, [SKCViewDataSourcePrefetching.swift](https://github.com/linhay/sectionkit/blob/main/Sources/SectionKit/CollectionBaseProtocol/SKCDataSourcePrefetching/SKCViewDataSourcePrefetching.swift) groups index paths by their section component and converts them to row arrays:
private func prefetch(at indexPaths: [IndexPath]) {
guard isEnable else { return }
publishers.prefetchSubject.send(indexPaths)
var store = [Int: [Int]]()
for ip in indexPaths {
store[ip.section, default: []].append(ip.row)
}
for (section, rows) in store {
section(section)?.prefetch(at: rows)
}
}
This ensures that each SectionKit section receives a clean [Int] array representing the rows requiring prefetch, rather than raw IndexPath objects.
Implementing Prefetching in Custom Sections
To leverage SKCDataSourcePrefetchingForward, your section must implement SKCViewDataSourcePrefetchingProtocol. Below is a complete example using SKCSingleTypeSection:
import SectionKit
final class PhotoSection: SKCSingleTypeSection<PhotoModel> {
override init() {
super.init()
// Enable the SectionKit prefetch channel
prefetch.isEnable = true
}
// Called when cells are about to come on screen
override func prefetch(at rows: [Int]) {
let models = rows.map { item(at: $0) }
ImageCache.prefetch(models.map { $0.imageURL })
}
// Called when cells scroll away before loading completes
override func cancelPrefetching(at rows: [Int]) {
let models = rows.map { item(at: $0) }
ImageCache.cancelPrefetch(models.map { $0.imageURL })
}
}
// Usage in a view controller
let collectionView = UICollectionView(frame: view.bounds,
collectionViewLayout: layout)
let manager = SKCManager(sectionView: collectionView)
let photoSection = PhotoSection()
manager.append(photoSection)
// Prefetching is now automatic as the user scrolls
Key implementation details:
- Set
prefetch.isEnable = truein your section's initializer to opt into the forwarding system. - Override
prefetch(at:)to begin background fetching (images, JSON, etc.). - Override
cancelPrefetching(at:)to abort expensive operations for cells that scrolled off-screen.
When to Use SKCDataSourcePrefetchingForward
- Heavy media assets: Preload images or videos just before they enter the viewport to eliminate scroll stuttering.
- Paginated data sources: Fetch the next page of results while the user is scrolling toward the end of the current list.
- Network optimization: Cancel in-flight requests for content that is no longer visible, conserving bandwidth and battery.
Summary
- SKCDataSourcePrefetchingForward is located in
Sources/SectionKit/CollectionBaseProtocol/SKCDataSourcePrefetching/SKCDataSourcePrefetchingForward.swiftand conforms toUICollectionViewDataSourcePrefetching. - It decouples UIKit prefetch callbacks from SectionKit sections by maintaining a list of forward handlers and observers.
- SKCManager automatically instantiates the forward and registers the internal
SKCDataSourcePrefetchinghandler during setup. - Sections opt-in by setting
prefetch.isEnable = trueand implementingprefetch(at:)andcancelPrefetching(at:)fromSKCViewDataSourcePrefetchingProtocol. - The forward uses a chain-of-responsibility pattern (reverse iteration) to determine which handler processes the request, then broadcasts to all observers.
Frequently Asked Questions
What protocol does SKCDataSourcePrefetchingForward conform to?
SKCDataSourcePrefetchingForward conforms to UICollectionViewDataSourcePrefetching, the UIKit protocol that enables asynchronous data loading for collection views. This allows it to act as the prefetchDataSource for any UICollectionView instance managed by SectionKit.
How do I enable prefetching for a specific section?
Set prefetch.isEnable = true inside your section's initializer. Then implement prefetch(at:) and cancelPrefetching(at:) methods from SKCViewDataSourcePrefetchingProtocol to handle the actual data loading and cancellation logic. Without setting this flag, the forward ignores the section even if the methods are implemented.
Can I observe prefetch events without handling them?
Yes. Implement SKCDataSourcePrefetchingObserverProtocol and add your observer to the forward's observerItems array. Observers receive notification of all prefetch and cancellation events via the collectionView(_:prefetchItemsAt:value:) method, but they cannot block or alter the forwarding chain. This is ideal for analytics, logging, or debugging.
Where is the prefetch forward instantiated in SectionKit?
The forward is instantiated as a lazy property inside SKCManager. According to the source in SKCManager.swift, the manager creates prefetchForward on first access and wires it to the collection view during setup(sectionView:), assigning it to sectionView.prefetchDataSource and registering the internal SKCDataSourcePrefetching handler.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →