Skip to content

Commit

Permalink
Fix zero-loop gifs (#2896)
Browse files Browse the repository at this point in the history
  • Loading branch information
crow authored Dec 19, 2023
1 parent b35f270 commit 2f531c7
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 13 deletions.
6 changes: 5 additions & 1 deletion Airship/AirshipCore/Source/ThomasAsyncImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,11 @@ public struct ThomasAsyncImage<Placeholder: View, ImageView: View>: View {

self.currentImage = frame?.image

while !Task.isCancelled && (loadedImage.loopCount == nil || loopsCompleted < loadedImage.loopCount!) {
/// GIFs will sometimes have a 0 in their loop count metadata to denote infinite loops
let loopCount = loadedImage.loopCount ?? 0

/// Continue looping if loop count is nil (coalesces to zero), zero or nonzero and greater than the loops completed
while !Task.isCancelled && (loopCount <= 0 || loopCount > loopsCompleted) {
let duration = frame?.duration ?? AirshipImageData.minFrameDuration

async let delay: () = Task.sleep(nanoseconds: UInt64(duration * 1_000_000_000))
Expand Down
39 changes: 27 additions & 12 deletions Airship/AirshipCore/Tests/Events/EventTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -146,22 +146,37 @@ class EventTest: XCTestCase {
}

func testScreenTracking() throws {
let event = ScreenTrackingEvent(
guard let event = ScreenTrackingEvent(
screen: "test_screen",
previousScreen: "previous_screen",
startDate: Date(timeIntervalSince1970: 0),
duration: 1
)


XCTAssertEqual(event!.data["duration"] as! String, "1.000")
XCTAssertEqual(event!.data["entered_time"] as! String, "0.000")
XCTAssertEqual(event!.data["exited_time"] as! String, "1.000")
XCTAssertEqual(
event!.data["previous_screen"] as! String,
"previous_screen"
)
XCTAssertEqual(event!.data["screen"] as! String, "test_screen")
) else {
XCTFail("Event is nil")
return
}

guard let durationString = event.data["duration"] as? String,
let enteredTimeString = event.data["entered_time"] as? String,
let exitedTimeString = event.data["exited_time"] as? String,
let duration = TimeInterval(durationString),
let enteredTime = TimeInterval(enteredTimeString),
let exitedTime = TimeInterval(exitedTimeString) else {
XCTFail("One or more strings could not be converted to TimeIntervals for comparison")
return
}

let expectedDurationInSeconds: TimeInterval = 1.0
let expectedEnteredTimeInSeconds: TimeInterval = 0.0
let expectedExitedTimeInSeconds: TimeInterval = 1.0
let errorMarginInSeconds: TimeInterval = 1 /// Use accuracy margin to avoid timing issues in ci

XCTAssertEqual(duration, expectedDurationInSeconds, accuracy: errorMarginInSeconds, "Duration does not match within the acceptable error margin.")
XCTAssertEqual(enteredTime, expectedEnteredTimeInSeconds, accuracy: errorMarginInSeconds, "Entered time does not match within the acceptable error margin.")
XCTAssertEqual(exitedTime, expectedExitedTimeInSeconds, accuracy: errorMarginInSeconds, "Exited time does not match within the acceptable error margin.")

XCTAssertEqual(event.data["previous_screen"] as? String, "previous_screen", "Previous screen does not match.")
XCTAssertEqual(event.data["screen"] as? String, "test_screen", "Screen does not match.")
}

func testScreenValidation() throws {
Expand Down

0 comments on commit 2f531c7

Please sign in to comment.