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 to SKCDataSourcePrefetchingForwardProtocol that handle the actual prefetch work.
  • observerItems: Objects conforming to SKCDataSourcePrefetchingObserverProtocol that 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): Triggers prefetchItemsAt and cancelPrefetchingForItemsAt on its prefetchDataSource.
  • 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 invokes prefetch(at:) on individual sections.
  • Section (e.g., SKCSingleTypeSection): Implements SKCViewDataSourcePrefetchingProtocol to 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 = true in 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.swift and conforms to UICollectionViewDataSourcePrefetching.
  • 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 SKCDataSourcePrefetching handler during setup.
  • Sections opt-in by setting prefetch.isEnable = true and implementing prefetch(at:) and cancelPrefetching(at:) from SKCViewDataSourcePrefetchingProtocol.
  • 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →