Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reader: Fix select interests unregistered cell #23158

Merged
merged 1 commit into from
May 8, 2024

Conversation

dvdchr
Copy link
Contributor

@dvdchr dvdchr commented May 6, 2024

Fixes #22932

Potentially fixes an issue where an unregistered collection view cell is returned from the collectionView:cellForItemAtIndexPath:.

The crash is caused by the collection asking for an invalid index path, which is already guarded against and returns an empty UICollectionViewCell. However, this crashed because the cell is not registered... 😅 I believe the root cause of this is the invalid index path, which is likely to be a race condition due to updating the interests variable while the collection view is updating its cells.

To fix/mitigate this, I've:

  1. Dispatched the logic that updates interests AND reloads the collection view to the main thread. See Reader: Fix select interests unregistered cell #23158 (comment)
  2. Registered an empty UICollectionViewCell so that if the race condition is still happening, it doesn't immediately crash. It should be fine to show an empty cell since we should display a NoResults screen.

To test

Note that I wasn't able to reproduce the crash, but these are the reproduction steps based on the logs:

  • Prepare an account where you'd see the Select Interests screen when you go to Reader tab > Discover stream.
  • Launch the Jetpack app.
  • Go to the Reader tab > Discover stream.
  • After the select interests screen is shown, tap the Search icon.
  • Minimize the app.
  • Turn on airplane mode.
  • Open the app again.
  • Tap back.
  • 🔎 Verify that the app does not crash.

Regression Notes

  1. Potential unintended areas of impact
    Should be none.

  2. What I did to test those areas of impact (or what existing automated tests I relied on)
    Manually tested the changes.

  3. What automated tests I added (or what prevented me from doing so)
    N/A.

PR submission checklist:

  • I have completed the Regression Notes.
  • I have considered adding unit tests for my changes.
  • I have considered adding accessibility improvements for my changes.
  • I have considered if this change warrants user-facing release notes and have added them to RELEASE-NOTES.txt if necessary.

Testing checklist:

  • WordPress.com sites and self-hosted Jetpack sites.
  • Portrait and landscape orientations.
  • Light and dark modes.
  • Fonts: Larger, smaller and bold text.
  • High contrast.
  • VoiceOver.
  • Languages with large words or with letters/accents not frequently used in English.
  • Right-to-left languages. (Even if translation isn’t complete, formatting should still respect the right-to-left layout)
  • iPhone and iPad.
  • Multi-tasking: Split view and Slide over. (iPad)

@wpmobilebot
Copy link
Contributor

wpmobilebot commented May 6, 2024

WordPress Alpha📲 You can test the changes from this Pull Request in WordPress Alpha by scanning the QR code below to install the corresponding build.
App NameWordPress Alpha WordPress Alpha
ConfigurationRelease-Alpha
Build Numberpr23158-f560543
Version24.8
Bundle IDorg.wordpress.alpha
Commitf560543
App Center BuildWPiOS - One-Offs #9834
Automatticians: You can use our internal self-serve MC tool to give yourself access to App Center if needed.

@wpmobilebot
Copy link
Contributor

wpmobilebot commented May 6, 2024

Jetpack Alpha📲 You can test the changes from this Pull Request in Jetpack Alpha by scanning the QR code below to install the corresponding build.
App NameJetpack Alpha Jetpack Alpha
ConfigurationRelease-Alpha
Build Numberpr23158-f560543
Version24.8
Bundle IDcom.jetpack.alpha
Commitf560543
App Center Buildjetpack-installable-builds #8882
Automatticians: You can use our internal self-serve MC tool to give yourself access to App Center if needed.

Copy link
Contributor

@wargcm wargcm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comments I left were minor and not blocking this PR. I'm fine with leaving in the @MainActor's if you want to keep them.

LGTM! 🎉

@@ -63,35 +63,41 @@ class ReaderInterestsDataSource {
}

/// Fetches the interests from the topic service
public func reload() {
public func reload(completion: (() -> Void)? = nil) {
interestsService.fetchInterests(success: { [weak self] interests in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought all our API calls already call their success and failure blocks on the main thread, so I wonder if adding @MainActor changes anything.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. You're right, the API already dispatches the completion blocks to the main thread. My assumption is that the interests variable got updated while the collection view is calling cellForItemAtIndexPath for the indexes before it got updated, which led to the guard condition.

However, even if I'm dispatching it again to the main thread—and, even if it works—it doesn't guarantee that the indexes will be correct when cellForItemAtIndexPath is called, since we don't know if the collection view still holds onto the "old" numberOfItemsInSection value.

Perhaps the best way is to move the implementation to a UICollectionViewDiffableDataSource... For now, I'll revert the dispatches to main queue and will just keep the empty cell registration.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in f560543.

@@ -383,6 +385,7 @@ extension ReaderSelectInterestsViewController: UICollectionViewDelegateFlowLayou

// MARK: - ReaderInterestsDataDelegate
extension ReaderSelectInterestsViewController: ReaderInterestsDataDelegate {
@MainActor
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kind of the same comment here, I would think that calling reloadData on a background thread would've caused a warning/crash. So my guess is this was already being called on the main thread.

Copy link
Contributor Author

@dvdchr dvdchr May 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in #23158 (comment). Thanks!

@dvdchr dvdchr force-pushed the issue/22932-select-interests-fallback-cell branch from 59be791 to f560543 Compare May 8, 2024 10:13
@dvdchr dvdchr merged commit 8ae9c91 into trunk May 8, 2024
24 checks passed
@dvdchr dvdchr deleted the issue/22932-select-interests-fallback-cell branch May 8, 2024 10:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants