mirror of
https://github.com/Instagram/IGListKit
synced 2026-05-24 09:48:21 +00:00
Handle nil section controllers from data source
Summary: Removing the assert and handling `nil` section controllers. This wont effect Swift code which demands a non-optional section controller, but Objective-C is more nuanced. There is evidence that some callers do not have a default state and are returning `nil`. Unfortunately this will [OOB here](https://github.com/Instagram/IGListKit/blob/master/Source/Internal/IGListSectionMap.m#L63) if using the original `objects` array provided by the data source. Instead we prune the array, only allowing in objects that have a matching section controller. Fixes t15773862 internally. - [x] All tests pass. Demo project builds and runs. - [x] I added tests, an experiment, or detailed why my change isn't tested. - [x] I added an entry to the `CHANGELOG.md` for any breaking changes, enhancements, or bug fixes. Closes https://github.com/Instagram/IGListKit/pull/488 Reviewed By: dshahidehpour Differential Revision: D4553886 Pulled By: rnystrom fbshipit-source-id: a473a99b5eb513e4b610019dba0394a014193fc4
This commit is contained in:
parent
a5a08d2e11
commit
9c37fbf8a4
4 changed files with 23 additions and 5 deletions
|
|
@ -30,6 +30,10 @@ This release closes the [3.0.0 milestone](https://github.com/Instagram/IGListKit
|
|||
|
||||
- You can now manually move items (cells) within a section controller, ex: `[self.collectionContext moveInSectionController:self fromIndex:0 toIndex:1]`. [Ryan Nystrom](https://github.com/rnystrom) [(#418)](https://github.com/Instagram/IGListKit/pull/418)
|
||||
|
||||
### Fixes
|
||||
|
||||
- Gracefully handle a `nil` section controller returned by an `IGListAdapterDataSource`. [Ryan Nystrom](https://github.com/rnystrom) [(tbd)](https://github.com/Instagram/IGListKit/pull/tbd)
|
||||
|
||||
2.2.0
|
||||
-----
|
||||
|
||||
|
|
|
|||
|
|
@ -476,7 +476,9 @@
|
|||
}
|
||||
#endif
|
||||
|
||||
NSMutableArray<IGListSectionController <IGListSectionType> *> *sectionControllers = [[NSMutableArray alloc] init];
|
||||
NSMutableArray<IGListSectionController <IGListSectionType> *> *sectionControllers = [NSMutableArray new];
|
||||
NSMutableArray *validObjects = [NSMutableArray new];
|
||||
|
||||
IGListSectionMap *map = self.sectionMap;
|
||||
|
||||
// collect items that have changed since the last update
|
||||
|
|
@ -498,8 +500,9 @@
|
|||
sectionController = [dataSource listAdapter:self sectionControllerForObject:object];
|
||||
}
|
||||
|
||||
IGAssert(sectionController != nil, @"Data source <%@> cannot return a nil section controller.", dataSource);
|
||||
if (sectionController == nil) {
|
||||
IGLKLog(@"WARNING: Ignoring nil section controller returned by data source %@ for object %@.",
|
||||
dataSource, object);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -516,12 +519,13 @@
|
|||
}
|
||||
|
||||
[sectionControllers addObject:sectionController];
|
||||
[validObjects addObject:object];
|
||||
}
|
||||
|
||||
// clear the view controller and collection context
|
||||
IGListSectionControllerPopThread();
|
||||
|
||||
[map updateWithObjects:objects sectionControllers:sectionControllers];
|
||||
[map updateWithObjects:validObjects sectionControllers:sectionControllers];
|
||||
|
||||
// now that the maps have been created and contexts are assigned, we consider the section controller "fully loaded"
|
||||
for (id object in updatedObjects) {
|
||||
|
|
|
|||
|
|
@ -1060,4 +1060,12 @@ XCTAssertEqual(CGPointEqualToPoint(point, p), YES); \
|
|||
[mockDelegate verify];
|
||||
}
|
||||
|
||||
- (void)test_whenDataSourceDoesntHandleObject_thatObjectIsDropped {
|
||||
// IGListTestAdapterDataSource does not handle NSStrings
|
||||
self.dataSource.objects = @[@1, @"dog", @2];
|
||||
[self.adapter reloadDataWithCompletion:nil];
|
||||
NSArray *expected = @[@1, @2];
|
||||
XCTAssertEqualObjects(self.adapter.objects, expected);
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -20,8 +20,10 @@
|
|||
}
|
||||
|
||||
- (IGListSectionController <IGListSectionType> *)listAdapter:(IGListAdapter *)listAdapter sectionControllerForObject:(id)object {
|
||||
IGListTestSection *list = [[IGListTestSection alloc] init];
|
||||
return list;
|
||||
if ([object isKindOfClass:[NSNumber class]]) {
|
||||
return [IGListTestSection new];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (nullable UIView *)emptyViewForListAdapter:(IGListAdapter *)listAdapter {
|
||||
|
|
|
|||
Loading…
Reference in a new issue