The EMAdaptorManager
is used to broker the communication between a UICollectionView
and an Endeca response object. The adaptor manager implements the delegate and datasource of a UICollectionView
. The delegate and datasource can be thought of as a series of requests for information from the collection view to the adaptor manager. The collection view relies on the adaptor manager to provide all necessary information for its construction and rendering. Internally, the adaptor manager handles this by using a collection of adaptors called adaptorSections
.
What is an Adaptor?
An adaptor is a class that manages a conversion from a specific content item to a collection view renderer. However, the results list content item has a different conversion process than the refinement menu content item, so it must have a different adaptor. The sets of code examples that follow help illustrate this process.
AdaptorManager Examples
In this example, the code itself is an AdaptorManager
. First, the collection view requests information about the DataSource
from the adaptor manager
. Specifically, the collectionView
requests the number of adaptor sections that should be prepared. The adaptor manager then returns the numbers of adaptor sections. This number equals the number of content items (@type objects
) in the Endeca Response Object, and is also the number of adaptor sections, since there is always one adaptor for each content item. Note that in the following code, the adapter sections are referenced as adaptorSections
.
The code for this request would look like this:
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { return self.adaptorSections.count; }
In the next code sample, for each adaptor section that the collectionView
has prepared, the adaptor manager needs to return the number of rows to prepare. The adaptor manager does not have this information, but the adaptor does, so the adaptor manager looks for the correct adaptor in its adaptor sections list to determine the numbers rows using numberOfItemsInContentItem
. For example, a price slider always has one row, and a refinement menu has a row for each refinement, and so on.
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return [((EMContentItemAdaptor *)[self.adaptorSections objectAtIndex:section]) numberOfItemsInContentItem]; }
At this point, the collection view has determined the number of adaptor sections and the number of items in each of those sections. In the next code example, the collection view needs to determine what should be rendered for each given index, that is, each adaptor section and row. The adaptor manager looks at its adaptor sections and finds the current index section. Once it finds the correct adaptor, it requests the renderer for that particular row:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { EMContentItemAdaptor *adaptor = [self adaptorForItemAtIndexPath:indexPath]; Class rendererClass = [adaptor rendererClassForIndex:indexPath.row]; NSString *cellIdentifier = [NSString stringWithFormat:@"%@", NSStringFromClass(rendererClass)]; [collectionView registerClass:rendererClass forCellWithReuseIdentifier:cellIdentifier]; EMContentItemRenderer *renderer = (EMContentItemRenderer *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath]; [adaptor usingRenderer:renderer forIndex:indexPath.row]; id obj = [adaptor objectToBeRenderedAtIndex:indexPath.row]; [renderer setObject:obj]; return renderer; }
Example Code Review
In these code examples, the collection view has made these three requests to the adaptor manager:
What is the number of adaptor sections in the collection view?
The adaptor manager returns the number of sections, one for each of the content items found when reviewing the Endeca response.
What is the number of rows in each adaptor section?
The adaptor manager uses the internal adaptors for this information. Each adaptor can determine the number of existing ‘rows’ for each content item. A results list returns a row for each product, for example, a price slider always has one row, a refinement menu has a row for each refinement, etc.
What should be drawn for each adapter section and row?
The adaptor manager can easily find a section, since it is an adaptor from
adaptorSections
. Once it determines the section object (the adaptor), it uses the adaptor to determine which renderer to use for each row. Specifically, the results list returns the correct List Renderers for each product.
Note: For more information about UICollectionView
and about data sources, see the Apple iOS developer documentation.