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

Adds .lottie file load capability to LottieAnimation #1785

Merged
merged 53 commits into from
Nov 1, 2022

Conversation

eharrison
Copy link
Contributor

Adds support to parse .lottie files
the dotLottie format (dotlottie.io) is a zip file with animation.json bundled along with image resources, and manifest

Motivation:

Changes

  • Added internal classes of ZIPFoundation (required to decompress the .lottie file)
  • Added .lottie file parsing as a fallback to loading json animation data
  • .lottie file also applies speed, loop mode and imageProviderSettings according to it's content

@eharrison
Copy link
Contributor Author

Hello! Here's Evandro. Head of mobile @ LottieFiles. Sending this as an effort to make .lottie more accessible. Please let me know if you see any issues. Thank you! :)

Copy link
Member

@calda calda left a comment

Choose a reason for hiding this comment

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

Left some comments. At a high level there are a few things we need to figure out:

  1. Can we incorporate ZIPFoundation using a package manager, instead of simply pasting its source into our repo?
  2. Can we load the .lottie file contents into memory and then delete the temporary directory we created when uncompressing it?
  3. Instead of modifying the existing methods that create LottieAnimations, can we add a set of asynchronous methods specifically for loading .lottie files? From there the user could access any of the animations included in the file.

This will also need to include snapshot tests that render animations from .lottie files, and the code will need to be formatted according to Airbnb's Swift style guide (you can run bundle exec rake format:swift to do this automatically).

Sources/Public/Animation/DotLottie/DotLottieFile.swift Outdated Show resolved Hide resolved
Sources/Public/Animation/DotLottie/DotLottieFile.swift Outdated Show resolved Hide resolved
Sources/Public/Animation/DotLottie/DotLottieFile.swift Outdated Show resolved Hide resolved
Sources/Public/Animation/DotLottie/DotLottieFile.swift Outdated Show resolved Hide resolved
Sources/Public/Animation/LottieAnimationHelpers.swift Outdated Show resolved Hide resolved
Sources/Public/Animation/DotLottie/DotLottieManifest.swift Outdated Show resolved Hide resolved
Sources/Public/Animation/DotLottie/DotLottieUtils.swift Outdated Show resolved Hide resolved
@calda calda mentioned this pull request Oct 20, 2022
Copy link
Member

@calda calda left a comment

Choose a reason for hiding this comment

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

Looking good! Mostly minor comments. I agree that embedding the pieces of functionality from ZIPFoundation that we need as source is the best approach here, thanks for slimming it down to the bare essentials.

I still think the DotLottieFile initializer / load / decompress functions should be marked as async so they can't be used directly from the main thread. Thoughts?

We also need some snapshot tests for .lottie files. Could you add a few of these to Tests/Samples and make sure SnapshotTests is capturing snapshots of them? After running the tests this should result in image files for each .lottie file being included in the repo.

Sources/Public/DotLottie/DotLottieFileHelpers.swift Outdated Show resolved Hide resolved
@@ -157,4 +157,7 @@ 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

Choose a reason for hiding this comment

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

have this configuration in a separate dictionary inside DotLottieFile and then besides searching for the animation with id, also search for the configuration with id.

That sounds reasonable, I think this would be better

Sources/Public/DotLottie/DotLottieFile.swift Outdated Show resolved Hide resolved
Sources/Public/DotLottie/DotLottieFile.swift Outdated Show resolved Hide resolved
Sources/Public/DotLottie/DotLottieFile.swift Show resolved Hide resolved
Sources/Public/DotLottie/DotLottieFile.swift Show resolved Hide resolved
Sources/Public/DotLottie/Utility/DotLottieAnimation.swift Outdated Show resolved Hide resolved
Sources/Public/DotLottie/DotLottieFile.swift Outdated Show resolved Hide resolved
Copy link
Member

@calda calda left a comment

Choose a reason for hiding this comment

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

Thanks for the contribution!

@calda calda merged commit 41b05dd into airbnb:master Nov 1, 2022
@eharrison eharrison deleted the dotlottie branch November 1, 2022 16:26
@rasberik
Copy link

rasberik commented Nov 10, 2022

Currently there is issue when play() method getting called but animation is not loaded yet.
Especially for local .lottie files,

// AnimationViewInitializers
DotLottieFile.named(name, bundle: bundle, dotLottieCache: dotLottieCache) { result in
      guard case Result.success(let lottie) = result else { return }
      self.loadAnimation(animationId, from: lottie)
    }

there is currently no way to know when it is ready to play or how to properly handle this. Most of my dotLottie files are not playing, just stuck in first frame because it returns in following block:

// LottieAnimationView
public func play(completion: LottieCompletionBlock? = nil) {
    guard let animation = animation else {
      return //here
    }
    ...
  }

I think it would be nice to have some ways to handle it

@rasberik
Copy link

@eharrison @calda

@calda
Copy link
Member

calda commented Nov 10, 2022

@rasberik, could you file an issue and ideally also provide a sample project that reproduces the issue?

@rasberik
Copy link

rasberik commented Nov 10, 2022

@rasberik, could you file an issue and ideally also provide a sample project that reproduces the issue?

@calda

Thanks, I prepared a PR here: #1802
We can continue the discussion there if its ok?

Sample project creation might take me a while due to busy schedule, my apologies.
Files Im using cant be shared unfortunately 🙏

I believe using .lottie file over 50-100kb will be more than enough to reproduce the issue:

let lottieAnimationView = LottieAnimationView(dotLottieName: resourceName, bundle: bundle)
... (layout) 
lottieAnimationView.play()

@rasberik
Copy link

@calda
Will this be enough as reproduction evidence?

https://github.com/rasberik/lottie-ios/pull/1/files

@calda
Copy link
Member

calda commented Nov 10, 2022

Helpful, thanks!

@rasberik
Copy link

@calda I separated tests and added to #1802

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.

4 participants