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

Add snapshot tests for dot lottie animations, and other cleanup #1794

Merged
merged 7 commits into from
Nov 2, 2022

Conversation

calda
Copy link
Member

@calda calda commented Nov 1, 2022

#1785 added support for dot lottie animations. This PR adds snapshot tests for these animations, plus other cleanup for the changes in that PR.

@@ -2658,7 +2658,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
Copy link
Member Author

Choose a reason for hiding this comment

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

Bumped the test target to 15.0 so we can use async/await in the tests

}

// MARK: Private

private var imageCache: NSCache<NSString, CGImage> = .init()
private var images = [String: CGImage]()
Copy link
Member Author

Choose a reason for hiding this comment

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

Updated this to use a dictionary instead of a cache, since this data isn't something that can be recomputed once evicted from a cache

Copy link
Collaborator

Choose a reason for hiding this comment

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

If we store the filepath.url couldn't we recover from a memory pressure eviction? It seems risky to have a bunch of CGImages in memory and not be able to release them on memory pressure warning as it may lead to apps being jetsam'd

Copy link
Member Author

Choose a reason for hiding this comment

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

When loading a dot lottie file, we currently:

  1. decompress the zip archive to a temporary directory
  2. load the file contents into memory
  3. delete the files in the temporary directory

I think deleting the temporary unzipped files after loading them is a good idea because:

  1. I think we don't want to be leaving behind a large number of files in the host app's temporary directory. The OS cleans these up in theory but I'm not sure we should rely on that.
  2. Since the OS can clean up those files at any time in theory, I don't think its safe to assume that they will still exist at any point in the future

That means that we don't have a way to gracefully reload the images if they get removed from the NSCache, since the filepath URLs are no longer valid.

Copy link
Member Author

Choose a reason for hiding this comment

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

I suppose we could re-decompress the zip archive to reload the images if necessary after they're evicted from the cache, but that functionality doesn't current exist.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Gotcha, sounds good. Perhaps we could add a note about adding that behavior if needed?

/// - Parameter bundle: The bundle in which the lottie is located. Defaults to `Bundle.main`
/// - Parameter subdirectory: A subdirectory in the bundle in which the lottie is located. Optional.
/// - Parameter dotLottieCache: A cache for holding loaded lotties. Defaults to `LRUDotLottieCache.sharedCache`. Optional.
@available(iOS 13.0, macOS 10.15, tvOS 13.0, *)
Copy link
Member Author

Choose a reason for hiding this comment

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

Added async variants for all of these methods

@calda
Copy link
Member Author

calda commented Nov 1, 2022

fyi @eharrison

@@ -157,7 +157,4 @@ public final class LottieAnimation: Codable, DictionaryInitializable {
/// Markers
let markers: [Marker]?
let markerMap: [String: Marker]?

/// DotLottie configuration to setup the player
var dotLottieConfiguration: DotLottieConfiguration?
Copy link
Member Author

Choose a reason for hiding this comment

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

Removed this property in favor of a DotLottieFile.Animation type that includes a LottieAnimation and DotLottieConfiguration

/// - Parameter animationCache: A cache for holding loaded animations. Defaults to `LottieAnimationCache.shared`. Optional.
///
@available(iOS 13.0, macOS 10.15, tvOS 13.0, *)
public static func loadedFrom(
Copy link
Member Author

Choose a reason for hiding this comment

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

I added async methods for loading DotLottieFiles so figured we may as well also add this one for remote LottieAnimations

Copy link
Collaborator

Choose a reason for hiding this comment

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

Nice!

Copy link
Collaborator

@erichoracek erichoracek left a comment

Choose a reason for hiding this comment

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

@calda Good stuff! LGTM with a few suggestions/question

Tests/AnimationKeypathTests.swift Outdated Show resolved Hide resolved
}

// MARK: Private

private var imageCache: NSCache<NSString, CGImage> = .init()
private var images = [String: CGImage]()
Copy link
Collaborator

Choose a reason for hiding this comment

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

If we store the filepath.url couldn't we recover from a memory pressure eviction? It seems risky to have a bunch of CGImages in memory and not be able to release them on memory pressure warning as it may lead to apps being jetsam'd

/// - Parameter animationCache: A cache for holding loaded animations. Defaults to `LottieAnimationCache.shared`. Optional.
///
@available(iOS 13.0, macOS 10.15, tvOS 13.0, *)
public static func loadedFrom(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nice!

closure: @escaping DotLottieLoadClosure,
dotLottieCache: DotLottieCacheProvider? = DotLottieCache.sharedCache)
dotLottieCache: DotLottieCacheProvider? = DotLottieCache.sharedCache,
handleResult: @escaping (Result<DotLottieFile, Error>) -> Void)
{
DispatchQueue.global().async {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Seems like if you wanted you could potentially check for task cancellation in these methods via Task.isCancelled to support async cancellation

calda and others added 2 commits November 2, 2022 11:19
Co-authored-by: Eric Horacek <eric.horacek@airbnb.com>
@calda calda enabled auto-merge (squash) November 2, 2022 18:20
@calda calda disabled auto-merge November 2, 2022 20:00
@calda calda enabled auto-merge (squash) November 2, 2022 21:38
@calda calda merged commit 0c43942 into master Nov 2, 2022
@calda calda deleted the cal--dot-lottie-tests branch November 2, 2022 22:04
iago849 pushed a commit to atteamapps/lottie-ios that referenced this pull request Feb 8, 2024
MoroziOS pushed a commit to MoroziOS/tmg-lottie-ios that referenced this pull request May 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants