Skip to content

Commit

Permalink
Add ExpandingVC Timeout + Explicitly Call updateScrollViewHeight on m…
Browse files Browse the repository at this point in the history
…ain thread (#182)

* Changes

* verify dispatch main is still necessary

* address noah comments

* keep main thread dispatch for test

* just the timer logic

* address noah comments

* remove anchor changes when timer ends

* delete print
  • Loading branch information
NicoHinderling authored Sep 3, 2024
1 parent ad316ae commit 15737c9
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 6 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ DerivedData/
DemoApp/DemoApp.xcodeproj/xcuserdata/
.xcuserstate
PreviewsSupport/PreviewsSupport.xcframework/**/*.private.swiftinterface


DemoApp/DemoApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/
46 changes: 42 additions & 4 deletions Sources/SnapshotPreviewsCore/ExpandingViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,18 @@ public final class ExpandingViewController: UIHostingController<EmergeModifierVi
rootView.supportsExpansion
}

private let HeightExpansionTimeLimitInSeconds: Double = 30

private var didCall = false
var previousHeight: CGFloat?

var heightAnchor: NSLayoutConstraint?
private var widthAnchor: NSLayoutConstraint?

public var expansionSettled: ((EmergeRenderingMode?, Float?, Bool?) -> Void)? {
private var startTime: Date?
private var timer: Timer?

public var expansionSettled: ((EmergeRenderingMode?, Float?, Bool?, Error?) -> Void)? {
didSet { didCall = false }
}

Expand Down Expand Up @@ -69,19 +74,25 @@ public final class ExpandingViewController: UIHostingController<EmergeModifierVi
}
}

private func runCallback() {
private func runCallback(_ error: Error? = nil) {
guard !didCall else { return }

didCall = true
expansionSettled?(rootView.emergeRenderingMode, rootView.precision, rootView.accessibilityEnabled)
expansionSettled?(rootView.emergeRenderingMode, rootView.precision, rootView.accessibilityEnabled, error)
stopAndResetTimer()
}

public override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.updateScrollViewHeight()
updateScrollViewHeight()
}

public func updateScrollViewHeight() {
// Timeout limit
if timer == nil {
startTimer()
}

guard expansionSettled != nil else {
runCallback()
return
Expand All @@ -92,5 +103,32 @@ public final class ExpandingViewController: UIHostingController<EmergeModifierVi
}
}

// MARK: - Timer

func startTimer() {
guard timer == nil else {
print("Timer already exists")
return
}
startTime = Date()
timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] _ in
guard let self,
let start = startTime,
Date().timeIntervalSince(start) >= HeightExpansionTimeLimitInSeconds else {
return
}
let timeoutError = RenderingError.expandingViewTimeout(CGSize(width: UIScreen.main.bounds.size.width,
height: firstScrollView?.visibleContentHeight ?? -1))
NSLog("ExpandingViewController: Expanding Scroll View timed out. Current height is \(firstScrollView?.visibleContentHeight ?? -1)")
runCallback(timeoutError)
}
}

func stopAndResetTimer() {
timer?.invalidate()
timer = nil
startTime = nil
}

}
#endif
14 changes: 12 additions & 2 deletions Sources/SnapshotPreviewsCore/View+Snapshot.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import SnapshotSharedModels
public enum RenderingError: Error {
case failedRendering(CGSize)
case maxSize(CGSize)
case expandingViewTimeout(CGSize)
}

extension AccessibilityMarker: AccessibilityMark {
Expand Down Expand Up @@ -57,8 +58,17 @@ extension View {
async: Bool,
completion: @escaping (SnapshotResult) -> Void)
{
controller.expansionSettled = { [weak controller, weak window] renderingMode, precision, accessibilityEnabled in
guard let controller, let window, let containerVC = controller.parent else { return }
controller.expansionSettled = { [weak controller, weak window] renderingMode, precision, accessibilityEnabled, error in
guard let controller, let window, let containerVC = controller.parent else {
return
}

if let error {
DispatchQueue.main.async {
completion(SnapshotResult(image: .failure(error), precision: precision, accessibilityEnabled: accessibilityEnabled, accessibilityMarkers: nil, colorScheme: _colorScheme))
}
return
}

if async {
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
Expand Down

0 comments on commit 15737c9

Please sign in to comment.