Skip to content

Commit

Permalink
Merge branch 'upstream/master' into feature/support-for-context-menu
Browse files Browse the repository at this point in the history
# Conflicts:
#	CHANGELOG.md
  • Loading branch information
jeromeboursier committed Sep 2, 2021
2 parents e662826 + a1036e0 commit 3b2f186
Show file tree
Hide file tree
Showing 374 changed files with 8,961 additions and 5,250 deletions.
233 changes: 233 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
name: "IGListKit CI"

on:
push:
branches:
- master
pull_request:
branches:
- '*'

jobs:
macOS:
name: Unit Test macOS
runs-on: macos-11
env:
DEVELOPER_DIR: /Applications/Xcode_12.5.1.app
WORKSPACE_NAME: IGListKit.xcworkspace
SCHEME_NAME: IGListKit-macOS
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Cache RubyGems
uses: actions/cache@v2
with:
path: vendor/bundle
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-gems-
- name: Install ruby gems.
run: bundle install

- name: Run unit tests for macOS
run: |
set -o pipefail
xcodebuild build build-for-testing -workspace "${{ env.WORKSPACE_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -destination "platform=macOS" -configuration Debug ONLY_ACTIVE_ARCH=NO CODE_SIGNING_REQUIRED=NO GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES GCC_GENERATE_TEST_COVERAGE_FILES=YES ONLY_ACTIVE_ARCH=YES | bundle exec xcpretty -c
xcodebuild analyze test-without-building -workspace "${{ env.WORKSPACE_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -destination "platform=macOS" -configuration Debug ONLY_ACTIVE_ARCH=NO CODE_SIGNING_REQUIRED=NO GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES GCC_GENERATE_TEST_COVERAGE_FILES=YES ONLY_ACTIVE_ARCH=YES | bundle exec xcpretty -c
iOS:
name: Unit Test iOS
runs-on: macos-11
env:
DEVELOPER_DIR: /Applications/Xcode_12.5.1.app
WORKSPACE_NAME: IGListKit.xcworkspace
SCHEME_NAME: IGListKit
strategy:
matrix:
destination: ["name=iPhone 12 Pro"]
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Cache RubyGems
uses: actions/cache@v2
with:
path: vendor/bundle
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-gems-
- name: Install ruby gems.
run: bundle install

- name: iOS - ${{ matrix.destination }}
run: |
set -o pipefail
xcodebuild build build-for-testing -workspace "${{ env.WORKSPACE_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -destination "${{ matrix.destination }}" -configuration Debug ONLY_ACTIVE_ARCH=NO CODE_SIGNING_REQUIRED=NO GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES GCC_GENERATE_TEST_COVERAGE_FILES=YES ONLY_ACTIVE_ARCH=YES | bundle exec xcpretty -c
xcodebuild analyze test-without-building -workspace "${{ env.WORKSPACE_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -destination "${{ matrix.destination }}" -configuration Debug ONLY_ACTIVE_ARCH=NO CODE_SIGNING_REQUIRED=NO GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES GCC_GENERATE_TEST_COVERAGE_FILES=YES ONLY_ACTIVE_ARCH=YES | bundle exec xcpretty -c
Cocoapods:
name: Cocoapods Lint
runs-on: macos-11
env:
DEVELOPER_DIR: /Applications/Xcode_12.5.1.app
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Cache RubyGems
uses: actions/cache@v2
with:
path: vendor/bundle
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-gems-
- name: Install ruby gems.
run: bundle install

- name: Run IGListDiffKit podspec lint
run: bundle exec pod lib lint IGListDiffKit.podspec --allow-warnings

- name: Run IGListKit podspec lint
run: bundle exec pod lib lint IGListKit.podspec --allow-warnings "--include-podspecs=IGListDiffKit.podspec"

- name: Run IGListSwiftKit podspec lint
run: bundle exec pod lib lint IGListSwiftKit.podspec --allow-warnings "--include-podspecs=*.podspec"

SPM-layout-generator:
name: Verify generate_spm_sources_layout.sh is not broken
runs-on: macos-11
env:
DEVELOPER_DIR: /Applications/Xcode_12.5.1.app
WORKSPACE_NAME: IGListKit.xcworkspace
PROJECT_NAME: IGListKit.xcodeproj
IOS_DESTINATION: "name=iPhone 12 Pro"
SPM_IG_LIST_DIFF_KIT_PUBLIC_HEADERS_PATH: "spm/Sources/IGListDiffKit/include"
SPM_IG_LIST_DIFF_KIT_SOURCES_PATH: "spm/Sources/IGListDiffKit"
SPM_IG_LIST_KIT_PUBLIC_HEADERS_PATH: "spm/Sources/IGListKit/include"
SPM_IG_LIST_KIT_SOURCES_PATH: "spm/Sources/IGListKit"
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Manually clean SPM Sources folder
run: |
rm -rf "${{ env.SPM_IG_LIST_DIFF_KIT_PUBLIC_HEADERS_PATH }}/*.*"
rm -rf "${{ env.SPM_IG_LIST_DIFF_KIT_SOURCES_PATH }}/*.*"
rm -rf "${{ env.SPM_IG_LIST_KIT_PUBLIC_HEADERS_PATH }}/*.*"
rm -rf "${{ env.SPM_IG_LIST_KIT_SOURCES_PATH }}/*.*"
- name: Regenerate SPM layout
run: sh scripts/generate_spm_sources_layout.sh

- name: Clean project's ${{ env.PROJECT_NAME }} and ${{ env.WORKSPACE_NAME }}
run: |
rm -rf "${{ env.WORKSPACE_NAME }}"
rm -rf "${{ env.PROJECT_NAME }}"
- name: Verify IGListKit can be build using Package.swift which was generated by 'scripts/generate_spm_sources_layout.sh'
run: xcodebuild -scheme "IGListKit" build -destination "${{ env.IOS_DESTINATION }}" | xcpretty

SPM-build-from-Package:
name: Verify SPM build by invoking `xcodebuild` on Package.swift
runs-on: macos-11
env:
DEVELOPER_DIR: /Applications/Xcode_12.5.1.app
WORKSPACE_NAME: IGListKit.xcworkspace
PROJECT_NAME: IGListKit.xcodeproj
IOS_DESTINATION: "name=iPhone 12 Pro"
strategy:
matrix:
schemeName: ["IGListDiffKit",
"IGListKit",
"IGListSwiftKit"]
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Clean project's ${{ env.PROJECT_NAME }} and ${{ env.WORKSPACE_NAME }}
run: |
rm -rf "${{ env.WORKSPACE_NAME }}"
rm -rf "${{ env.PROJECT_NAME }}"
- name: Run ${{ matrix.schemeName}} using Package.swift
run: xcodebuild -scheme "${{ matrix.schemeName}}" build -destination "${{ env.IOS_DESTINATION }}" | xcpretty

Carthage-XCFramework:
name: Verify Carthage build XCFramework
runs-on: macos-11
env:
DEVELOPER_DIR: /Applications/Xcode_12.5.1.app
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Carthage build framework
run: carthage build --no-skip-current --use-xcframeworks

Carthage-Legacy-Lipo-Binaries:
name: Verify Carthage build lipo binaries
runs-on: macos-11
env:
DEVELOPER_DIR: /Applications/Xcode_11.7.app
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Carthage build framework
run: carthage build --no-skip-current

Build-Examples:
name: Build Examples and UI tests.
runs-on: macos-10.15
env:
DEVELOPER_DIR: /Applications/Xcode_12.4.app
IOS_EXAMPLE_WORKSPACE: Examples/Examples-iOS/IGListKitExamples.xcworkspace
TVOS_EXAMPLE_WORKSPACE: Examples/Examples-tvOS/IGListKitExamples.xcworkspace
MACOS_EXAMPLE_WORKSPACE: Examples/Examples-macOS/IGListKitExamples.xcworkspace
EXAMPLE_SCHEME: IGListKitExamples
strategy:
matrix:
iosDestination: ["name=iPhone 12 Pro"]
tvOSDestination: ["name=Apple TV 4K"]
macOSDestination: ["platform=macOS"]
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Cache RubyGems
uses: actions/cache@v2
with:
path: vendor/bundle
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-gems-
- name: Install ruby gems.
run: bundle install

- name: Prepare local pods
run: bash scripts/setup.sh

- name: Build iOS Example - ${{ matrix.iosDestination }}
run: |
set -o pipefail
xcodebuild build -workspace "${{ env.IOS_EXAMPLE_WORKSPACE }}" -scheme "${{ env.EXAMPLE_SCHEME }}" -destination "${{ matrix.iosDestination }}" ONLY_ACTIVE_ARCH=NO CODE_SIGNING_REQUIRED=NO | bundle exec xcpretty -c
- name: Run iOS Example's UI Tests - ${{ matrix.iosDestination }}
run: |
set -o pipefail
xcodebuild build test -workspace "${{ env.IOS_EXAMPLE_WORKSPACE }}" -scheme "${{ env.EXAMPLE_SCHEME }}" -destination "${{ matrix.iosDestination }}" -configuration Debug ONLY_ACTIVE_ARCH=NO CODE_SIGNING_REQUIRED=NO | bundle exec xcpretty -c
- name: Build tvOS Example - ${{ matrix.tvOSDestination }}
run: |
set -o pipefail
xcodebuild build -workspace "${{ env.TVOS_EXAMPLE_WORKSPACE }}" -scheme "${{ env.EXAMPLE_SCHEME }}" -destination "${{ matrix.tvOSDestination }}" ONLY_ACTIVE_ARCH=NO CODE_SIGNING_REQUIRED=NO | bundle exec xcpretty -c
- name: Build macOS Example - ${{ matrix.macOSDestination }}
run: |
set -o pipefail
xcodebuild build -workspace "${{ env.MACOS_EXAMPLE_WORKSPACE }}" -scheme "${{ env.EXAMPLE_SCHEME }}" -destination "${{ matrix.macOSDestination }}" ONLY_ACTIVE_ARCH=NO CODE_SIGNING_REQUIRED=NO | bundle exec xcpretty -c
94 changes: 92 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,106 @@
The changelog for `IGListKit`. Also see the [releases](https://github.com/instagram/IGListKit/releases) on GitHub.


4.1.0 (upcoming release)
5.0.0 (upcoming release)
-----
### Breaking Changes

- Removed unneeded diffing functions `IGListDiffExperiment(...)` and `IGListDiffPathsExperiment(...)`. [Maxime Ollivier](https://github.com/maxolls) (tbd)

- `ListSectionController.collectionContext` and `ListGenericSectionController.object` are now implicitly-unwrapped optionals in Swift. [Nate Stedman](https://github.com/natestedman) (tbd)

- The argument of `IGListGenericSectionController`'s `-didUpdateToObject:` is now generic, not `id`. [Nate Stedman](https://github.com/natestedman) (tbd)

- Updated `IGListUpdatingDelegate`, including a new method to safely perform `[IGListAdapter setDataSource:]` and changes to `-performUpdateWithCollectionViewBlock` that allows section-controllers to be created before the diffing (and therefore use a more accurate `toObjects` array) [Maxime Ollivier](https://github.com/maxolls) (tbd)

```objc
// OLD
- (void)performUpdateWithCollectionViewBlock:(IGListCollectionViewBlock)collectionViewBlock
fromObjects:(nullable NSArray<id <IGListDiffable>> *)fromObjects
toObjectsBlock:(nullable IGListToObjectBlock)toObjectsBlock
animated:(BOOL)animated
objectTransitionBlock:(IGListObjectTransitionBlock)objectTransitionBlock
completion:(nullable IGListUpdatingCompletion)completion;

// NEW
- (void)performUpdateWithCollectionViewBlock:(IGListCollectionViewBlock)collectionViewBlock
animated:(BOOL)animated
sectionDataBlock:(IGListTransitionDataBlock)sectionDataBlock
applySectionDataBlock:(IGListTransitionDataApplyBlock)applySectionDataBlock
completion:(nullable IGListUpdatingCompletion)completion;

// NEW
- (void)performDataSourceChange:(IGListDataSourceChangeBlock)block;
```

- Removed `allowsBackgroundReloading` from `IGListAdapterUpdater` because it's causing performance issues and other bugs. [Maxime Ollivier](https://github.com/maxolls) (tbd)

- Introducing `allowsBackgroundDiffing` on `IGListAdapterUpdater`! This property lets the updater perform the diffing on a background thread. Originally introduced by Ryan Nystrom a while back. [Maxime Ollivier](https://github.com/maxolls) (tbd)

- Updated `scrollToObject:` method in `IGListAdapter` to include a new parameter `additionalOffset` to handle shifting the final scroll position by some vertical or horizontal offset depending on the scroll direction. This allows the object to be shown at the correct position when it is scrolled to in a list with sticky headers.

```objc
// OLD
- (void)scrollToObject:(id)object
supplementaryKinds:(nullable NSArray<NSString *> *)supplementaryKinds
scrollDirection:(UICollectionViewScrollDirection)scrollDirection
scrollPosition:(UICollectionViewScrollPosition)scrollPosition
animated:(BOOL)animated;

// NEW
- (void)scrollToObject:(id)object
supplementaryKinds:(nullable NSArray<NSString *> *)supplementaryKinds
scrollDirection:(UICollectionViewScrollDirection)scrollDirection
scrollPosition:(UICollectionViewScrollPosition)scrollPosition
additionalOffset:(CGPoint)additionalOffset
animated:(BOOL)animated;
```

### Enhancements

- Added `shouldSelectItemAtIndex:` to `IGListSectionController` . [dirtmelon](https://github.com/dirtmelon)

- Added [Mac Catalyst](https://developer.apple.com/mac-catalyst/) support. [Petro Rovenskyy](https://github.com/3a4oT/)

- Introduce `IGListSwiftKit`, with Swift refinements for `dequeueReusableCellOfClass` methods. [Koen Punt](https://github.com/koenpunt) [(#1388)](https://github.com/Instagram/IGListKit/pull/1388).

- Added `APPLICATION_EXTENSION_API_ONLY` support for `IGListDiffKit` [Peter Meyers](https://github.com/pm-dev) [(#1422)](https://github.com/Instagram/IGListKit/pull/1422)

- Added support for iOS 13 Context Menus with `contextMenuConfigurationForItemAt` method. [Jérôme B.](https://github.com/jjbourdev) [(#1430)](https://github.com/Instagram/IGListKit/pull/1430).
- Improved performance by deferring requesting objects from the `IGListAdapterDataSource` until just before diffing is executed. If n updates are coalesced into one, this results in just a single request for objects from the data source. Shipped with experiment `IGListExperimentDeferredToObjectCreation` from Ryan Nystrom. [Maxime Ollivier](https://github.com/maxolls) (tbd)

- Improved performance by using `reloadData` when there are too many diffing updates. Shipped with experiment `IGListExperimentReloadDataFallback` from Ryan Nystrom. [Maxime Ollivier](https://github.com/maxolls) (tbd)

- Small performance improvement by replacing `NSSet` with `NSArray` during the data update to avoid unnecessary hashing, especially when dealing with lots of large objects with non trivial hashes. [Maxime Ollivier](https://github.com/maxolls) (tbd)

- Lazy initialize the `-emptyViewForListAdapter:` [Maxime Ollivier](https://github.com/maxolls) (tbd)

- Updated `IGListAdapterUpdater` to be safer, more performant, and better organized! [Maxime Ollivier](https://github.com/maxolls) (tbd)
- Safely handles `[IGListAdapter setDataSource:]` by also invalidating the `UICollectionView` data.
- Safely handles `[IGListAdapter setCollectionView:]` by cancelling on-going transactions.
- Safely handles returning nil `IGListSectionController` from `IGListAdapterDataSource` by dumping objects that don't have a controller before the diffing.
- Checks that the `UICollectionView` section count matches the `IGListAdapter` before committing the update, otherwise fallback to a reload.
- Schedules an update block (`dispatch_async`) only when needed, instead of scheduling on every single call to `-performUpdateWithCollectionViewBlock`.
- Wraps each update in a `transaction` that can be easily cancelled.
- Uses methods instead of blocks to make the callstack easier to read in crash reports.
- Unblocks `IGListExperimentBackgroundDiffing`

- Added support for iOS 13 Context Menus with `contextMenuConfigurationForItemAt` method. [Jérôme B.](https://github.com/jeromeboursier) [(#1430)](https://github.com/Instagram/IGListKit/pull/1430).

### Fixes

- Repaired Swift Package Manager support. [Petro Rovenskyy](https://github.com/3a4oT/)

- `IGListCollectionViewLayout` should get the section/index counts via `UICollectionView` to stay in sync, instead of the `dataSource` [Maxime Ollivier](https://github.com/maxolls) (tbd)

- Remove `[collectionView layoutIfNeeded]` before scrolling in `[IGListAdapter scrollToObject...]` to avoid creating off-screen cells. [Maxime Ollivier](https://github.com/maxolls) (tbd)

- Remove `[collectionView layoutIfNeeded]` before updating in `[IGListAdapterUpdater performBatchUpdates...]` to fix occasional glitches. [Maxime Ollivier](https://github.com/maxolls) (tbd)

- Fixed `IGListAdapterUpdaterDelegate` by 1) calling `willReloadDataWithCollectionView` on fallback reloads and 2) making sure `willPerformBatchUpdatesWithCollectionView` is only called when performing a batch update. [Maxime Ollivier](https://github.com/maxolls) (tbd)

- Fixed missing update when calling `performUpdatesAnimated` multiple times quickly and using the `reloadDataFallback()`. [Maxime Ollivier](https://github.com/maxolls) (tbd)

- Request the `UICollectionView` until just-before we update. This way if the `UICollectionView` is changed between update-queue and execution, we guarantee the update is performed on the correct view. Ship with experiment `IGListExperimentGetCollectionViewAtUpdate` from Ryan Nystrom. [Maxime Ollivier](https://github.com/maxolls) (tbd)

4.0.0
-----
Expand Down

0 comments on commit 3b2f186

Please sign in to comment.