Skip to content

Commit

Permalink
Bugfix FXIOS-10485 Fix the crash on iOS 15 (#22961)
Browse files Browse the repository at this point in the history

---------

Co-authored-by: Sophie Amin <[email protected]>
  • Loading branch information
dataports and Sophie Amin authored Nov 10, 2024
1 parent a748e52 commit 2129764
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 24 deletions.
8 changes: 4 additions & 4 deletions firefox-ios/Client.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@
21E78A7028F9A8C500F8D687 /* MockUIDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21E78A6F28F9A8C500F8D687 /* MockUIDevice.swift */; };
21E78A7228F9A93100F8D687 /* UIDeviceInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21E78A7128F9A93100F8D687 /* UIDeviceInterface.swift */; };
21EA466A2B04130500AAAB2D /* TabsPanelState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21EA46692B04130500AAAB2D /* TabsPanelState.swift */; };
21ED80B32AF2E43A0065D4C7 /* TabDisplayViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21ED80B22AF2E43A0065D4C7 /* TabDisplayViewTests.swift */; };
21ED80B32AF2E43A0065D4C7 /* TabDisplayDiffableDataSourceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21ED80B22AF2E43A0065D4C7 /* TabDisplayDiffableDataSourceTests.swift */; };
21F2A2D22B0BC85200626AEC /* InactiveTabsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21F2A2D12B0BC85200626AEC /* InactiveTabsModel.swift */; };
21F2A2D42B0D194A00626AEC /* TabsPanelStateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21F2A2D32B0D194A00626AEC /* TabsPanelStateTests.swift */; };
21FA8FAE2AE856460013B815 /* TabsCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21FA8FAD2AE856460013B815 /* TabsCoordinatorTests.swift */; };
Expand Down Expand Up @@ -2639,7 +2639,7 @@
21E78A6F28F9A8C500F8D687 /* MockUIDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockUIDevice.swift; sourceTree = "<group>"; };
21E78A7128F9A93100F8D687 /* UIDeviceInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIDeviceInterface.swift; sourceTree = "<group>"; };
21EA46692B04130500AAAB2D /* TabsPanelState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsPanelState.swift; sourceTree = "<group>"; };
21ED80B22AF2E43A0065D4C7 /* TabDisplayViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabDisplayViewTests.swift; sourceTree = "<group>"; };
21ED80B22AF2E43A0065D4C7 /* TabDisplayDiffableDataSourceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabDisplayDiffableDataSourceTests.swift; sourceTree = "<group>"; };
21F2A2D12B0BC85200626AEC /* InactiveTabsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InactiveTabsModel.swift; sourceTree = "<group>"; };
21F2A2D32B0D194A00626AEC /* TabsPanelStateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsPanelStateTests.swift; sourceTree = "<group>"; };
21FA8FAD2AE856460013B815 /* TabsCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsCoordinatorTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -9941,7 +9941,7 @@
1D8487B52AD6038100F7527C /* RemoteTabPanelStateTests.swift */,
1D3C90872ACE1AF400304C87 /* RemoteTabPanelTests.swift */,
219935F02B07DFA200E5966F /* TabDisplayPanelTests.swift */,
21ED80B22AF2E43A0065D4C7 /* TabDisplayViewTests.swift */,
21ED80B22AF2E43A0065D4C7 /* TabDisplayDiffableDataSourceTests.swift */,
21F2A2D32B0D194A00626AEC /* TabsPanelStateTests.swift */,
21D8EA922ABE04F7003FF16E /* TabTrayViewControllerTests.swift */,
);
Expand Down Expand Up @@ -16754,7 +16754,7 @@
1DDE3DB52AC360EC0039363B /* TabCellTests.swift in Sources */,
8AFCE50729DE0CD500B1B253 /* LaunchCoordinatorTests.swift in Sources */,
961D6B832995AF84001B9CF1 /* GeneralizedImageFetcherTests.swift in Sources */,
21ED80B32AF2E43A0065D4C7 /* TabDisplayViewTests.swift in Sources */,
21ED80B32AF2E43A0065D4C7 /* TabDisplayDiffableDataSourceTests.swift in Sources */,
E1AEC177286E0CF500062E29 /* HistoryHighlightsViewModelTests.swift in Sources */,
2165B2C42860CB34004C0786 /* MockAdjustTelemetryData.swift in Sources */,
C29B64872AD69D0200F3244B /* QRCodeCoordinatorTests.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ typealias TabDisplayViewSection = TabDisplayDiffableDataSource.TabSection
typealias TabDisplayViewItem = TabDisplayDiffableDataSource.TabItem

final class TabDisplayDiffableDataSource: UICollectionViewDiffableDataSource<TabDisplayViewSection, TabDisplayViewItem> {
enum TabSection: Int, CaseIterable {
case inactiveTabs
enum TabSection: Hashable {
// Adding a UUID to the section allows us to trigger a reload on the header by updating the UUID
// (which creates a diff) while updating the snapshot. This avoids calling reloadSections on inactiveTabs
// when there are no inactiveTabs in the section, which triggers a crash on iOS 15.
case inactiveTabs(UUID)
case tabs
}

Expand All @@ -19,14 +22,12 @@ final class TabDisplayDiffableDataSource: UICollectionViewDiffableDataSource<Tab
func updateSnapshot(state: TabsPanelState) {
var snapshot = NSDiffableDataSourceSnapshot<TabDisplayViewSection, TabDisplayViewItem>()

snapshot.appendSections([.inactiveTabs, .tabs])

// reloading .inactiveTabs is necessary to animate the caret moving when we show or hide inactive tabs
snapshot.reloadSections([.inactiveTabs])
let inactiveTabsUUID = UUID()
snapshot.appendSections([.inactiveTabs(inactiveTabsUUID), .tabs])

if state.isInactiveTabsExpanded {
let inactiveTabs = state.inactiveTabs.map { TabDisplayViewItem.inactiveTab($0) }
snapshot.appendItems(inactiveTabs, toSection: .inactiveTabs)
snapshot.appendItems(inactiveTabs, toSection: .inactiveTabs(inactiveTabsUUID))
}

let tabs = state.tabs.map { TabDisplayViewItem.tab($0) }
Expand Down
24 changes: 12 additions & 12 deletions firefox-ios/Client/Frontend/Browser/Tabs/Views/TabDisplayView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,9 @@ class TabDisplayView: UIView,
dataSource?.supplementaryViewProvider = { [weak self] (collectionView, kind, indexPath) -> UICollectionReusableView? in
// swiftlint:enable line_length
let reusableView = UICollectionReusableView()
let section = self?.getTabDisplay(for: indexPath.section)
let section = self?.getSection(for: indexPath.section)

guard let self, section == .inactiveTabs else {
return nil
}
guard let self, section != .tabs else { return nil }

if kind == UICollectionView.elementKindSectionHeader,
let headerView = collectionView.dequeueReusableSupplementaryView(
Expand Down Expand Up @@ -248,16 +246,14 @@ class TabDisplayView: UIView,
return self.tabsSectionManager.layoutSection(layoutEnvironment)
}

let section = TabDisplayViewSection(rawValue: sectionIndex)
let section = getSection(for: sectionIndex)
switch section {
case .inactiveTabs:
return self.inactiveTabsSectionManager.layoutSection(
layoutEnvironment,
isExpanded: tabsState.isInactiveTabsExpanded)
case .tabs:
return self.tabsSectionManager.layoutSection(layoutEnvironment)
case .none:
return self.tabsSectionManager.layoutSection(layoutEnvironment)
}
}
return layout
Expand All @@ -268,10 +264,14 @@ class TabDisplayView: UIView,
collectionView.backgroundColor = theme.colors.layer3
}

private func getTabDisplay(for section: Int) -> TabDisplayViewSection {
guard !shouldHideInactiveTabs else { return .tabs }
private func getSection(for sectionIndex: Int) -> TabDisplayViewSection {
guard
let snapshot = dataSource?.snapshot(),
sectionIndex >= 0,
sectionIndex < snapshot.sectionIdentifiers.count
else { return TabDisplayViewSection.tabs }

return TabDisplayViewSection(rawValue: section) ?? .tabs
return snapshot.sectionIdentifiers[sectionIndex]
}

func deleteInactiveTab(for index: Int) {
Expand Down Expand Up @@ -307,7 +307,7 @@ class TabDisplayView: UIView,
func collectionView(_ collectionView: UICollectionView,
contextMenuConfigurationForItemAt indexPath: IndexPath,
point: CGPoint) -> UIContextMenuConfiguration? {
guard getTabDisplay(for: indexPath.section) == .tabs
guard getSection(for: indexPath.section) == .tabs
else { return nil }

let tabVC = TabPeekViewController(tab: tabsState.tabs[indexPath.row], windowUUID: windowUUID)
Expand Down Expand Up @@ -358,7 +358,7 @@ extension TabDisplayView: UICollectionViewDragDelegate, UICollectionViewDropDele
func collectionView(_ collectionView: UICollectionView,
itemsForBeginning session: UIDragSession,
at indexPath: IndexPath) -> [UIDragItem] {
guard getTabDisplay(for: indexPath.section) == .tabs else { return [] }
guard getSection(for: indexPath.section) == .tabs else { return [] }

let itemProvider = NSItemProvider()
let dragItem = UIDragItem(itemProvider: itemProvider)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Common
import XCTest

@testable import Client
final class TabDisplayViewTests: XCTestCase {
final class TabDisplayDiffableDataSourceTests: XCTestCase {
var diffableDataSource: TabDisplayDiffableDataSource?

override func setUp() {
Expand Down

0 comments on commit 2129764

Please sign in to comment.