contributors |
---|
zntfdr |
In this session the AppStoreConnect.app team shares how they manage complexity in their revamped app.
Traditional Data Source Approach:
- Implemented in
UlCollectionViewController
- Doesn't encourage code reuse for similar sections
- Either:
- One gigantic controller
- One controller per content type
Aggregate Data Source:
- implement data sources as separate objects
- enables code reuse
- single view controller
Aggregate data source enables you to avoid implementing the data source in UlCollectionViewController
.
This architecture is composed by four classes/objects:
-
AAPLDataSource
- The base data source class, this is where we implementUICollectionViewDataSource
-
AAPLSegmentedDataSource
- Can have multiple children/sections, only one active at a time -
AAPLComposedDataSource
- Multiple children/sections, all active at once, manage the translations between internal index paths and external index paths -
AAPLBasicDataSource
- One section, items are stored in anNSArray
(for simple, table-like, representations)
In App store connect, the product detail page is a AAPLSegmentedDataSource
class, which has four segments (details, episodes, reviews, trends), which correspond to the four items in the segmented control UI component.
The info for each segment come from a different data source:
The Details segment has a separate AAPLComposedDataSource
that provides data for its sections:
- status
- information
- description
Each section (status, information, description) has its own data source.
The Episodes segment has a simple AAPLBasicDataSource
that provides the list data.
The Reviews segment has another AAPLComposedDataSource
that provides data for its sections:
- ratings
- reviews
Lastly, the Trends segment uses a custom data source derived directly from AAPLDataSource
.
As we have multiple sources for our data, the view controller tells the data source when it's time to load, but then it's the source that is responsible to do the actual data loading.
For example, a AAPLSegmentedDataSource
will only load the selected data source, while a AAPLComposedDataSource
will tell all of its children to load.
To manage the loading process, AppStoreConnect.app uses a AAPLLoadableContentStateMachine
class, here are all the states:
Aggregate Data Sources:
- Reduces view controller complexity
- Promotes code reuse
- Isolates task specific logic
- Enables unified loading indicator
Before building your layout, make sure to have gathered all the necessary details such as:
-
What information do we need?
- Per section?
- Per header and footer?
-
Where does it go?
Examples:
-
Section Metrics:
rowHeight
separatorColor
andseparatorInsets
backgroundColor
selectedBackgroundColor
numberOfColumns
showsColumnSeparator
-
Header and Footer Metrics:
height
backgroundColor
padding
In AppStoreConnect.app they also some global headers, for these they use NSIndexPath with just a single index (no sections), i.e., [NSIndexPath indexPathWithIndex:0];
- If data source changed ➡️ snapshot data source
- If collection view width changed or data source changed ➡️ regenerate layout attributes & special layout attributes
- If collection view origin changed ➡️ update special layout attributes
prepareLayout
prepareForCollectionViewUpdates:
targetContentOffsetForProposedContentOffset:
initialLayoutAttributes*
finalLayoutAttributes*