lottie-ios 4.2.0 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. package/.github/workflows/main.yml +117 -11
  2. package/Gemfile +1 -0
  3. package/Gemfile.lock +5 -0
  4. package/Lottie.xcodeproj/project.pbxproj +1542 -194
  5. package/Lottie.xcodeproj/project.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  6. package/Lottie.xcodeproj/xcshareddata/xcschemes/Lottie (iOS).xcscheme +1 -1
  7. package/Lottie.xcodeproj/xcshareddata/xcschemes/Lottie (macOS).xcscheme +1 -1
  8. package/Lottie.xcodeproj/xcshareddata/xcschemes/Lottie (tvOS).xcscheme +4 -5
  9. package/Lottie.xcodeproj/xcshareddata/xcschemes/Lottie (visionOS).xcscheme +66 -0
  10. package/Lottie.xcodeproj/xcuserdata/calstephens.xcuserdatad/xcschemes/xcschememanagement.plist +18 -0
  11. package/Lottie.xcworkspace/xcshareddata/swiftpm/Package.resolved +2 -11
  12. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  13. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +346 -102
  14. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Expressions.xcexplist +16 -5
  15. package/Package.resolved +2 -2
  16. package/Package.swift +16 -9
  17. package/README.md +2 -2
  18. package/Rakefile +122 -25
  19. package/Sources/Private/CoreAnimation/Animations/DropShadowAnimation.swift +160 -0
  20. package/Sources/Private/CoreAnimation/Animations/LayerProperty.swift +83 -10
  21. package/Sources/Private/CoreAnimation/Animations/TransformAnimations.swift +85 -79
  22. package/Sources/Private/CoreAnimation/CoreAnimationLayer.swift +7 -7
  23. package/Sources/Private/CoreAnimation/Extensions/Keyframes+combined.swift +67 -6
  24. package/Sources/Private/CoreAnimation/Layers/AnimationLayer.swift +2 -2
  25. package/Sources/Private/CoreAnimation/Layers/BaseCompositionLayer.swift +9 -0
  26. package/Sources/Private/CoreAnimation/Layers/ImageLayer.swift +1 -0
  27. package/Sources/Private/CoreAnimation/Layers/LayerModel+makeAnimationLayer.swift +1 -1
  28. package/Sources/Private/CoreAnimation/Layers/RepeaterLayer.swift +2 -0
  29. package/Sources/Private/CoreAnimation/Layers/ShapeLayer.swift +11 -13
  30. package/Sources/Private/CoreAnimation/Layers/SolidLayer.swift +20 -5
  31. package/Sources/Private/CoreAnimation/Layers/TextLayer.swift +13 -3
  32. package/Sources/Private/CoreAnimation/ValueProviderStore.swift +6 -4
  33. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/Collection+Diff.swift +263 -0
  34. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/Diffable.swift +18 -0
  35. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/DiffableSection.swift +16 -0
  36. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/IndexChangeset.swift +187 -0
  37. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Diffing/SectionedChangeset.swift +32 -0
  38. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Logging/EpoxyLogger.swift +99 -0
  39. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/CallbackContextEpoxyModeled.swift +8 -0
  40. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/EpoxyModelArrayBuilder.swift +48 -0
  41. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/EpoxyModelProperty.swift +158 -0
  42. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/EpoxyModelStorage.swift +88 -0
  43. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/EpoxyModeled.swift +54 -0
  44. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Internal/AnyEpoxyModelProperty.swift +29 -0
  45. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Internal/ClassReference.swift +39 -0
  46. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/AnimatedProviding.swift +10 -0
  47. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/DataIDProviding.swift +57 -0
  48. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/DidDisplayProviding.swift +41 -0
  49. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/DidEndDisplayingProviding.swift +41 -0
  50. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/DidSelectProviding.swift +36 -0
  51. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/ErasedContentProviding.swift +49 -0
  52. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/MakeViewProviding.swift +60 -0
  53. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/SetBehaviorsProviding.swift +38 -0
  54. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/SetContentProviding.swift +38 -0
  55. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/StyleIDProviding.swift +37 -0
  56. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/TraitCollectionProviding.swift +14 -0
  57. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/ViewDifferentiatorProviding.swift +34 -0
  58. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/ViewProviding.swift +13 -0
  59. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/Providers/WillDisplayProviding.swift +41 -0
  60. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/ViewEpoxyModeled.swift +10 -0
  61. package/Sources/Private/EmbeddedLibraries/EpoxyCore/README.md +31 -0
  62. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIHostingController.swift +46 -0
  63. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIHostingView.swift +391 -0
  64. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIIntrinsicContentSizeInvalidator.swift +44 -0
  65. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUILayoutMargins.swift +51 -0
  66. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxyableView+SwiftUIView.swift +172 -0
  67. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/LayoutUtilities/MeasuringViewRepresentable.swift +128 -0
  68. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/LayoutUtilities/SwiftUIMeasurementContainer.swift +452 -0
  69. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/SwiftUIView.swift +148 -0
  70. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/UIView+SwiftUIView.swift +40 -0
  71. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/UIViewConfiguringSwiftUIView.swift +43 -0
  72. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/BehaviorsConfigurableView.swift +45 -0
  73. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/ContentConfigurableView.swift +36 -0
  74. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/EpoxyableView.swift +5 -0
  75. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/StyledView.swift +42 -0
  76. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/ViewType.swift +51 -0
  77. package/Sources/Private/EmbeddedLibraries/README.md +27 -0
  78. package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Archive+BackingConfiguration.swift +4 -4
  79. package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Archive+MemoryFile.swift +2 -2
  80. package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Archive+Writing.swift +4 -4
  81. package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Archive.swift +8 -7
  82. package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Data+Compression.swift +5 -5
  83. package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/FileManager+ZIP.swift +4 -4
  84. package/Sources/Private/MainThread/LayerContainers/CompLayers/ImageCompositionLayer.swift +6 -0
  85. package/Sources/Private/MainThread/LayerContainers/CompLayers/MaskContainerLayer.swift +3 -1
  86. package/Sources/Private/MainThread/LayerContainers/CompLayers/PreCompositionLayer.swift +18 -5
  87. package/Sources/Private/MainThread/LayerContainers/CompLayers/TextCompositionLayer.swift +31 -3
  88. package/Sources/Private/MainThread/LayerContainers/MainThreadAnimationLayer.swift +33 -8
  89. package/Sources/Private/MainThread/LayerContainers/Utility/CachedImageProvider.swift +8 -1
  90. package/Sources/Private/MainThread/LayerContainers/Utility/CompositionLayersInitializer.swift +13 -4
  91. package/Sources/Private/MainThread/LayerContainers/Utility/LayerFontProvider.swift +2 -2
  92. package/Sources/Private/MainThread/LayerContainers/Utility/LayerImageProvider.swift +1 -0
  93. package/Sources/Private/MainThread/LayerContainers/Utility/LayerTextProvider.swift +4 -4
  94. package/Sources/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/NodePropertyMap.swift +1 -1
  95. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/ModifierNodes/TrimPathNode.swift +3 -1
  96. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/GradientFillRenderer.swift +2 -1
  97. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/LegacyGradientFillRenderer.swift +2 -1
  98. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/GradientFillNode.swift +1 -1
  99. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/GradientStrokeNode.swift +2 -2
  100. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/StrokeNode.swift +1 -1
  101. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/Text/TextAnimatorNode.swift +1 -1
  102. package/Sources/Private/MainThread/NodeRenderSystem/RenderLayers/ShapeContainerLayer.swift +6 -2
  103. package/Sources/Private/Model/Assets/Asset.swift +8 -0
  104. package/Sources/Private/Model/Assets/AssetLibrary.swift +2 -2
  105. package/Sources/Private/Model/Assets/ImageAsset.swift +3 -3
  106. package/Sources/Private/Model/DotLottie/DotLottieAnimation.swift +16 -2
  107. package/Sources/Private/Model/DotLottie/DotLottieImageProvider.swift +20 -7
  108. package/Sources/Private/Model/Extensions/KeyedDecodingContainerExtensions.swift +26 -0
  109. package/Sources/Private/Model/Keyframes/KeyframeGroup.swift +8 -5
  110. package/Sources/Private/Model/LayerEffects/DropShadowEffect.swift +45 -0
  111. package/Sources/Private/Model/LayerEffects/EffectValues/ColorEffectValue.swift +38 -0
  112. package/Sources/Private/Model/LayerEffects/EffectValues/EffectValue.swift +98 -0
  113. package/Sources/Private/Model/LayerEffects/EffectValues/Vector1DEffectValue.swift +38 -0
  114. package/Sources/Private/Model/LayerEffects/LayerEffect.swift +103 -0
  115. package/Sources/Private/Model/LayerStyles/DropShadowStyle.swift +72 -0
  116. package/Sources/Private/Model/LayerStyles/LayerStyle.swift +85 -0
  117. package/Sources/Private/Model/Layers/LayerModel.swift +27 -0
  118. package/Sources/Private/Model/Objects/Marker.swift +1 -1
  119. package/Sources/Private/Model/Objects/Transform.swift +1 -2
  120. package/Sources/Private/Model/ShapeItems/GradientFill.swift +1 -1
  121. package/Sources/Private/Model/ShapeItems/GradientStroke.swift +2 -2
  122. package/Sources/Private/Model/ShapeItems/Merge.swift +1 -1
  123. package/Sources/Private/Model/ShapeItems/ShapeItem.swift +31 -26
  124. package/Sources/Private/Model/ShapeItems/ShapeTransform.swift +0 -9
  125. package/Sources/Private/Model/ShapeItems/Star.swift +1 -1
  126. package/Sources/Private/Model/Text/Font.swift +2 -2
  127. package/Sources/Private/Model/Text/Glyph.swift +1 -1
  128. package/Sources/Private/RootAnimationLayer.swift +2 -2
  129. package/Sources/Private/Utility/Debugging/LayerDebugging.swift +3 -1
  130. package/Sources/Private/Utility/Extensions/AnimationKeypathExtension.swift +32 -2
  131. package/Sources/Private/Utility/Helpers/AnimationContext.swift +4 -2
  132. package/Sources/Private/Utility/Helpers/AnyEquatable.swift +24 -0
  133. package/Sources/Private/Utility/Helpers/Binding+Map.swift +18 -0
  134. package/Sources/Private/Utility/Helpers/View+ValueChanged.swift +20 -0
  135. package/Sources/Private/Utility/LottieAnimationSource.swift +41 -0
  136. package/Sources/Private/Utility/Primitives/BezierPath.swift +2 -2
  137. package/Sources/Private/Utility/Primitives/BezierPathRoundExtension.swift +2 -2
  138. package/Sources/Private/Utility/Primitives/VectorsExtensions.swift +1 -1
  139. package/Sources/Public/Animation/LottieAnimation.swift +21 -2
  140. package/Sources/Public/Animation/LottieAnimationLayer.swift +1464 -0
  141. package/Sources/Public/Animation/LottieAnimationView.swift +258 -735
  142. package/Sources/Public/Animation/LottiePlaybackMode.swift +117 -0
  143. package/Sources/Public/Animation/LottieView.swift +462 -0
  144. package/Sources/Public/AnimationCache/AnimationCacheProvider.swift +2 -1
  145. package/Sources/Public/AnimationCache/DefaultAnimationCache.swift +5 -6
  146. package/Sources/Public/Configuration/DecodingStrategy.swift +15 -0
  147. package/Sources/Public/Configuration/LottieConfiguration.swift +47 -0
  148. package/Sources/Public/Configuration/ReducedMotionOption.swift +114 -0
  149. package/Sources/Public/{LottieConfiguration.swift → Configuration/RenderingEngineOption.swift} +2 -57
  150. package/Sources/Public/{iOS → Controls}/AnimatedButton.swift +56 -13
  151. package/Sources/Public/{iOS → Controls}/AnimatedControl.swift +80 -8
  152. package/Sources/Public/{iOS → Controls}/AnimatedSwitch.swift +71 -31
  153. package/Sources/Public/Controls/LottieButton.swift +122 -0
  154. package/Sources/Public/Controls/LottieSwitch.swift +144 -0
  155. package/Sources/Public/Controls/LottieViewType.swift +79 -0
  156. package/Sources/Public/DotLottie/DotLottieConfiguration.swift +24 -0
  157. package/Sources/Public/DotLottie/DotLottieFile.swift +21 -6
  158. package/Sources/Public/DotLottie/DotLottieFileHelpers.swift +79 -0
  159. package/Sources/Public/DynamicProperties/AnimationKeypath.swift +11 -1
  160. package/Sources/Public/DynamicProperties/ValueProviders/ColorValueProvider.swift +14 -0
  161. package/Sources/Public/DynamicProperties/ValueProviders/FloatValueProvider.swift +13 -0
  162. package/Sources/Public/DynamicProperties/ValueProviders/GradientValueProvider.swift +22 -5
  163. package/Sources/Public/DynamicProperties/ValueProviders/PointValueProvider.swift +14 -0
  164. package/Sources/Public/DynamicProperties/ValueProviders/SizeValueProvider.swift +13 -0
  165. package/Sources/Public/FontProvider/AnimationFontProvider.swift +8 -0
  166. package/Sources/Public/ImageProvider/AnimationImageProvider.swift +24 -0
  167. package/Sources/Public/Keyframes/Keyframe.swift +6 -0
  168. package/Sources/Public/Primitives/Vectors.swift +2 -2
  169. package/Sources/Public/TextProvider/AnimationTextProvider.swift +79 -6
  170. package/Sources/Public/iOS/AnimationSubview.swift +1 -1
  171. package/Sources/Public/iOS/BundleImageProvider.swift +16 -2
  172. package/Sources/Public/iOS/Compatibility/CompatibleAnimationView.swift +2 -2
  173. package/Sources/Public/iOS/FilepathImageProvider.swift +22 -3
  174. package/Sources/Public/iOS/LottieAnimationViewBase.swift +7 -1
  175. package/Sources/Public/macOS/BundleImageProvider.macOS.swift +15 -1
  176. package/Sources/Public/macOS/FilepathImageProvider.macOS.swift +21 -2
  177. package/lottie-ios.podspec +2 -1
  178. package/package.json +1 -1
  179. package/Sources/Private/Model/DotLottie/DotLottieConfiguration.swift +0 -15
  180. /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Archive+Helpers.swift +0 -0
  181. /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Archive+Progress.swift +0 -0
  182. /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Archive+Reading.swift +0 -0
  183. /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Archive+ReadingDeprecated.swift +0 -0
  184. /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Archive+WritingDeprecated.swift +0 -0
  185. /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Archive+ZIP64.swift +0 -0
  186. /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Data+CompressionDeprecated.swift +0 -0
  187. /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Data+Serialization.swift +0 -0
  188. /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Entry+Serialization.swift +0 -0
  189. /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Entry+ZIP64.swift +0 -0
  190. /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/Entry.swift +0 -0
  191. /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/README.md +0 -0
  192. /package/Sources/Private/{Model/DotLottie → EmbeddedLibraries}/ZipFoundation/URL+ZIP.swift +0 -0
@@ -20,6 +20,10 @@ extension DotLottieFile {
20
20
  dotLottieCache: DotLottieCacheProvider? = DotLottieCache.sharedCache)
21
21
  -> Result<DotLottieFile, Error>
22
22
  {
23
+ LottieLogger.shared.assert(
24
+ !Thread.isMainThread,
25
+ "`DotLottieFile.SynchronouslyBlockingCurrentThread` methods shouldn't be called on the main thread.")
26
+
23
27
  /// Check cache for lottie
24
28
  if
25
29
  let dotLottieCache = dotLottieCache,
@@ -55,6 +59,10 @@ extension DotLottieFile {
55
59
  dotLottieCache: DotLottieCacheProvider? = DotLottieCache.sharedCache)
56
60
  -> Result<DotLottieFile, Error>
57
61
  {
62
+ LottieLogger.shared.assert(
63
+ !Thread.isMainThread,
64
+ "`DotLottieFile.SynchronouslyBlockingCurrentThread` methods shouldn't be called on the main thread.")
65
+
58
66
  /// Create a cache key for the lottie.
59
67
  let cacheKey = bundle.bundlePath + (subdirectory ?? "") + "/" + name
60
68
 
@@ -78,6 +86,30 @@ extension DotLottieFile {
78
86
  return .failure(error)
79
87
  }
80
88
  }
89
+
90
+ /// Loads an DotLottie from a data synchronously. Returns a `Result<DotLottieFile, Error>`
91
+ ///
92
+ /// Please use the asynchronous methods whenever possible. This operation will block the Thread it is running in.
93
+ ///
94
+ /// - Parameters:
95
+ /// - data: The data(`Foundation.Data`) object to load DotLottie from
96
+ /// - filename: The name of the lottie file without the lottie extension. eg. "StarAnimation"
97
+ public static func loadedFrom(
98
+ data: Data,
99
+ filename: String)
100
+ -> Result<DotLottieFile, Error>
101
+ {
102
+ LottieLogger.shared.assert(
103
+ !Thread.isMainThread,
104
+ "`DotLottieFile.SynchronouslyBlockingCurrentThread` methods shouldn't be called on the main thread.")
105
+
106
+ do {
107
+ let dotLottieFile = try DotLottieFile(data: data, filename: filename)
108
+ return .success(dotLottieFile)
109
+ } catch {
110
+ return .failure(error)
111
+ }
112
+ }
81
113
  }
82
114
 
83
115
  /// Loads a DotLottie model from a bundle by its name. Returns `nil` if a file is not found.
@@ -289,4 +321,51 @@ extension DotLottieFile {
289
321
  }
290
322
  }
291
323
 
324
+ /// Loads an DotLottie from a data asynchronously.
325
+ ///
326
+ /// - Parameters:
327
+ /// - data: The data(`Foundation.Data`) object to load DotLottie from
328
+ /// - filename: The name of the lottie file without the lottie extension. eg. "StarAnimation"
329
+ /// - dispatchQueue: A dispatch queue used to load animations. Defaults to `DispatchQueue.global()`. Optional.
330
+ /// - handleResult: A closure to be called when the file has loaded.
331
+ public static func loadedFrom(
332
+ data: Data,
333
+ filename: String,
334
+ dispatchQueue: DispatchQueue = .global(),
335
+ handleResult: @escaping (Result<DotLottieFile, Error>) -> Void)
336
+ {
337
+ dispatchQueue.async {
338
+ do {
339
+ let dotLottie = try DotLottieFile(data: data, filename: filename)
340
+ DispatchQueue.main.async {
341
+ handleResult(.success(dotLottie))
342
+ }
343
+ } catch {
344
+ DispatchQueue.main.async {
345
+ handleResult(.failure(error))
346
+ }
347
+ }
348
+ }
349
+ }
350
+
351
+ /// Loads an DotLottie from a data asynchronously.
352
+ ///
353
+ /// - Parameters:
354
+ /// - data: The data(`Foundation.Data`) object to load DotLottie from
355
+ /// - filename: The name of the lottie file without the lottie extension. eg. "StarAnimation"
356
+ /// - dispatchQueue: A dispatch queue used to load animations. Defaults to `DispatchQueue.global()`. Optional.
357
+ @available(iOS 13.0, macOS 10.15, tvOS 13.0, *)
358
+ public static func loadedFrom(
359
+ data: Data,
360
+ filename: String,
361
+ dispatchQueue: DispatchQueue = .global())
362
+ async throws -> DotLottieFile
363
+ {
364
+ try await withCheckedThrowingContinuation { continuation in
365
+ loadedFrom(data: data, filename: filename, dispatchQueue: dispatchQueue) { result in
366
+ continuation.resume(with: result)
367
+ }
368
+ }
369
+ }
370
+
292
371
  }
@@ -29,6 +29,8 @@ import Foundation
29
29
  /// Represents the color node for every Stroke named "Stroke 1" in the animation.
30
30
  public struct AnimationKeypath: Hashable, ExpressibleByStringLiteral {
31
31
 
32
+ // MARK: Lifecycle
33
+
32
34
  /// Creates a keypath from a dot-separated string. The string is separated by "."
33
35
  public init(keypath: String) {
34
36
  keys = keypath.components(separatedBy: ".")
@@ -44,6 +46,14 @@ public struct AnimationKeypath: Hashable, ExpressibleByStringLiteral {
44
46
  self.keys = keys
45
47
  }
46
48
 
47
- var keys: [String]
49
+ // MARK: Public
50
+
51
+ /// The dot-separated key values that represent this keypath.
52
+ public internal(set) var keys: [String]
53
+
54
+ /// The `String` representation of this keypath
55
+ public var string: String {
56
+ keys.joined(separator: ".")
57
+ }
48
58
 
49
59
  }
@@ -8,6 +8,8 @@
8
8
  import CoreGraphics
9
9
  import Foundation
10
10
 
11
+ // MARK: - ColorValueProvider
12
+
11
13
  /// A `ValueProvider` that returns a CGColor Value
12
14
  public final class ColorValueProvider: ValueProvider {
13
15
 
@@ -18,6 +20,7 @@ public final class ColorValueProvider: ValueProvider {
18
20
  self.block = block
19
21
  color = LottieColor(r: 0, g: 0, b: 0, a: 1)
20
22
  keyframes = nil
23
+ identity = UUID()
21
24
  }
22
25
 
23
26
  /// Initializes with a single color.
@@ -26,6 +29,7 @@ public final class ColorValueProvider: ValueProvider {
26
29
  block = nil
27
30
  keyframes = nil
28
31
  hasUpdate = true
32
+ identity = color
29
33
  }
30
34
 
31
35
  /// Initializes with multiple colors, with timing information
@@ -34,6 +38,7 @@ public final class ColorValueProvider: ValueProvider {
34
38
  color = LottieColor(r: 0, g: 0, b: 0, a: 1)
35
39
  block = nil
36
40
  hasUpdate = true
41
+ identity = keyframes
37
42
  }
38
43
 
39
44
  // MARK: Public
@@ -81,4 +86,13 @@ public final class ColorValueProvider: ValueProvider {
81
86
 
82
87
  private var block: ColorValueBlock?
83
88
  private var keyframes: [Keyframe<LottieColor>]?
89
+ private var identity: AnyHashable
90
+ }
91
+
92
+ // MARK: Equatable
93
+
94
+ extension ColorValueProvider: Equatable {
95
+ public static func ==(_ lhs: ColorValueProvider, _ rhs: ColorValueProvider) -> Bool {
96
+ lhs.identity == rhs.identity
97
+ }
84
98
  }
@@ -8,6 +8,8 @@
8
8
  import CoreGraphics
9
9
  import Foundation
10
10
 
11
+ // MARK: - FloatValueProvider
12
+
11
13
  /// A `ValueProvider` that returns a CGFloat Value
12
14
  public final class FloatValueProvider: ValueProvider {
13
15
 
@@ -17,6 +19,7 @@ public final class FloatValueProvider: ValueProvider {
17
19
  public init(block: @escaping CGFloatValueBlock) {
18
20
  self.block = block
19
21
  float = 0
22
+ identity = UUID()
20
23
  }
21
24
 
22
25
  /// Initializes with a single float.
@@ -24,6 +27,7 @@ public final class FloatValueProvider: ValueProvider {
24
27
  self.float = float
25
28
  block = nil
26
29
  hasUpdate = true
30
+ identity = float
27
31
  }
28
32
 
29
33
  // MARK: Public
@@ -67,4 +71,13 @@ public final class FloatValueProvider: ValueProvider {
67
71
  private var hasUpdate = true
68
72
 
69
73
  private var block: CGFloatValueBlock?
74
+ private var identity: AnyHashable
75
+ }
76
+
77
+ // MARK: Equatable
78
+
79
+ extension FloatValueProvider: Equatable {
80
+ public static func ==(_ lhs: FloatValueProvider, _ rhs: FloatValueProvider) -> Bool {
81
+ lhs.identity == rhs.identity
82
+ }
70
83
  }
@@ -8,6 +8,8 @@
8
8
  import CoreGraphics
9
9
  import Foundation
10
10
 
11
+ // MARK: - GradientValueProvider
12
+
11
13
  /// A `ValueProvider` that returns a Gradient Color Value.
12
14
  public final class GradientValueProvider: ValueProvider {
13
15
 
@@ -22,6 +24,7 @@ public final class GradientValueProvider: ValueProvider {
22
24
  locationsBlock = locations
23
25
  colors = []
24
26
  self.locations = []
27
+ identity = UUID()
25
28
  }
26
29
 
27
30
  /// Initializes with an array of colors.
@@ -31,6 +34,7 @@ public final class GradientValueProvider: ValueProvider {
31
34
  {
32
35
  self.colors = colors
33
36
  self.locations = locations
37
+ identity = [AnyHashable(colors), AnyHashable(locations)]
34
38
  updateValueArray()
35
39
  hasUpdate = true
36
40
  }
@@ -65,16 +69,18 @@ public final class GradientValueProvider: ValueProvider {
65
69
  }
66
70
 
67
71
  public var storage: ValueProviderStorage<[Double]> {
68
- .closure { [self] frame in
69
- hasUpdate = false
72
+ if let block = block {
73
+ return .closure { [self] frame in
74
+ hasUpdate = false
70
75
 
71
- if let block = block {
72
76
  let newColors = block(frame)
73
77
  let newLocations = locationsBlock?(frame) ?? []
74
78
  value = value(from: newColors, locations: newLocations)
75
- }
76
79
 
77
- return value
80
+ return value
81
+ }
82
+ } else {
83
+ return .singleValue(value)
78
84
  }
79
85
  }
80
86
 
@@ -93,6 +99,8 @@ public final class GradientValueProvider: ValueProvider {
93
99
  private var locationsBlock: ColorLocationsBlock?
94
100
  private var value: [Double] = []
95
101
 
102
+ private let identity: AnyHashable
103
+
96
104
  private func value(from colors: [LottieColor], locations: [Double]) -> [Double] {
97
105
  var colorValues = [Double]()
98
106
  var alphaValues = [Double]()
@@ -120,4 +128,13 @@ public final class GradientValueProvider: ValueProvider {
120
128
  private func updateValueArray() {
121
129
  value = value(from: colors, locations: locations)
122
130
  }
131
+
132
+ }
133
+
134
+ // MARK: Equatable
135
+
136
+ extension GradientValueProvider: Equatable {
137
+ public static func ==(_ lhs: GradientValueProvider, _ rhs: GradientValueProvider) -> Bool {
138
+ lhs.identity == rhs.identity
139
+ }
123
140
  }
@@ -7,6 +7,9 @@
7
7
 
8
8
  import CoreGraphics
9
9
  import Foundation
10
+
11
+ // MARK: - PointValueProvider
12
+
10
13
  /// A `ValueProvider` that returns a CGPoint Value
11
14
  public final class PointValueProvider: ValueProvider {
12
15
 
@@ -16,6 +19,7 @@ public final class PointValueProvider: ValueProvider {
16
19
  public init(block: @escaping PointValueBlock) {
17
20
  self.block = block
18
21
  point = .zero
22
+ identity = UUID()
19
23
  }
20
24
 
21
25
  /// Initializes with a single point.
@@ -23,6 +27,7 @@ public final class PointValueProvider: ValueProvider {
23
27
  self.point = point
24
28
  block = nil
25
29
  hasUpdate = true
30
+ identity = [point.x, point.y]
26
31
  }
27
32
 
28
33
  // MARK: Public
@@ -66,4 +71,13 @@ public final class PointValueProvider: ValueProvider {
66
71
  private var hasUpdate = true
67
72
 
68
73
  private var block: PointValueBlock?
74
+ private let identity: AnyHashable
75
+ }
76
+
77
+ // MARK: Equatable
78
+
79
+ extension PointValueProvider: Equatable {
80
+ public static func ==(_ lhs: PointValueProvider, _ rhs: PointValueProvider) -> Bool {
81
+ lhs.identity == rhs.identity
82
+ }
69
83
  }
@@ -8,6 +8,8 @@
8
8
  import CoreGraphics
9
9
  import Foundation
10
10
 
11
+ // MARK: - SizeValueProvider
12
+
11
13
  /// A `ValueProvider` that returns a CGSize Value
12
14
  public final class SizeValueProvider: ValueProvider {
13
15
 
@@ -17,6 +19,7 @@ public final class SizeValueProvider: ValueProvider {
17
19
  public init(block: @escaping SizeValueBlock) {
18
20
  self.block = block
19
21
  size = .zero
22
+ identity = UUID()
20
23
  }
21
24
 
22
25
  /// Initializes with a single size.
@@ -24,6 +27,7 @@ public final class SizeValueProvider: ValueProvider {
24
27
  self.size = size
25
28
  block = nil
26
29
  hasUpdate = true
30
+ identity = [size.width, size.height]
27
31
  }
28
32
 
29
33
  // MARK: Public
@@ -67,4 +71,13 @@ public final class SizeValueProvider: ValueProvider {
67
71
  private var hasUpdate = true
68
72
 
69
73
  private var block: SizeValueBlock?
74
+ private let identity: AnyHashable
75
+ }
76
+
77
+ // MARK: Equatable
78
+
79
+ extension SizeValueProvider: Equatable {
80
+ public static func ==(_ lhs: SizeValueProvider, _ rhs: SizeValueProvider) -> Bool {
81
+ lhs.identity == rhs.identity
82
+ }
70
83
  }
@@ -33,3 +33,11 @@ public final class DefaultFontProvider: AnimationFontProvider {
33
33
  CTFontCreateWithName(family as CFString, size, nil)
34
34
  }
35
35
  }
36
+
37
+ // MARK: Equatable
38
+
39
+ extension DefaultFontProvider: Equatable {
40
+ public static func ==(_: DefaultFontProvider, _: DefaultFontProvider) -> Bool {
41
+ true
42
+ }
43
+ }
@@ -7,6 +7,9 @@
7
7
 
8
8
  import CoreGraphics
9
9
  import Foundation
10
+ import QuartzCore
11
+
12
+ // MARK: - AnimationImageProvider
10
13
 
11
14
  /// Image provider is a protocol that is used to supply images to `LottieAnimationView`.
12
15
  ///
@@ -17,5 +20,26 @@ import Foundation
17
20
  /// Additionally custom Image Providers can be made to load images from a URL,
18
21
  /// or to Cache images.
19
22
  public protocol AnimationImageProvider {
23
+
24
+ /// Whether or not the resulting image of this image provider can be cached by Lottie. Defaults to true.
25
+ /// If true, Lottie may internally cache the result of `imageForAsset`
26
+ var cacheEligible: Bool { get }
27
+
28
+ /// The image to display for the given `ImageAsset` defined in the `LottieAnimation` JSON file.
20
29
  func imageForAsset(asset: ImageAsset) -> CGImage?
30
+
31
+ /// Specifies how the layer's contents are positioned or scaled within its bounds for a given asset.
32
+ /// Defaults to `.resize`, which stretches the image to fill the layer.
33
+ func contentsGravity(for asset: ImageAsset) -> CALayerContentsGravity
34
+ }
35
+
36
+ extension AnimationImageProvider {
37
+ public var cacheEligible: Bool {
38
+ true
39
+ }
40
+
41
+ /// The default value is `.resize`, similar to that of `CALayer`.
42
+ public func contentsGravity(for _: ImageAsset) -> CALayerContentsGravity {
43
+ .resize
44
+ }
21
45
  }
@@ -1,6 +1,8 @@
1
1
  // Created by Cal Stephens on 1/24/22.
2
2
  // Copyright © 2022 Airbnb Inc. All rights reserved.
3
3
 
4
+ import CoreFoundation
5
+
4
6
  // MARK: - Keyframe
5
7
 
6
8
  /// A keyframe with a single value, and timing information
@@ -90,3 +92,7 @@ extension Keyframe: Hashable where T: Hashable {
90
92
  hasher.combine(spatialOutTangent)
91
93
  }
92
94
  }
95
+
96
+ // MARK: Sendable
97
+
98
+ extension Keyframe: Sendable where T: Sendable { }
@@ -9,7 +9,7 @@ import Foundation
9
9
 
10
10
  // MARK: - LottieVector1D
11
11
 
12
- public struct LottieVector1D: Hashable {
12
+ public struct LottieVector1D: Hashable, Sendable {
13
13
 
14
14
  public init(_ value: Double) {
15
15
  self.value = value
@@ -23,7 +23,7 @@ public struct LottieVector1D: Hashable {
23
23
 
24
24
  /// A three dimensional vector.
25
25
  /// These vectors are encoded and decoded from [Double]
26
- public struct LottieVector3D: Hashable {
26
+ public struct LottieVector3D: Hashable, Sendable {
27
27
 
28
28
  public let x: Double
29
29
  public let y: Double
@@ -7,17 +7,52 @@
7
7
 
8
8
  import Foundation
9
9
 
10
- // MARK: - AnimationTextProvider
10
+ // MARK: - AnimationKeypathTextProvider
11
11
 
12
- /// Text provider is a protocol that is used to supply text to `LottieAnimationView`.
13
- public protocol AnimationTextProvider: AnyObject {
12
+ /// Protocol for providing dynamic text to for a Lottie animation.
13
+ public protocol AnimationKeypathTextProvider: AnyObject {
14
+ /// The text to display for the given `AnimationKeypath`.
15
+ /// If `nil` is returned, continues using the existing default text value.
16
+ func text(for keypath: AnimationKeypath, sourceText: String) -> String?
17
+ }
18
+
19
+ // MARK: - AnimationKeypathTextProvider
20
+
21
+ /// Legacy protocol for providing dynamic text for a Lottie animation.
22
+ /// Instead prefer conforming to `AnimationKeypathTextProvider`.
23
+ @available(*, deprecated, message: """
24
+ `AnimationKeypathTextProvider` has been deprecated and renamed to `LegacyAnimationTextProvider`. \
25
+ Instead, conform to `AnimationKeypathTextProvider` instead or conform to `LegacyAnimationTextProvider` explicitly.
26
+ """)
27
+ public typealias AnimationTextProvider = LegacyAnimationTextProvider
28
+
29
+ // MARK: - LegacyAnimationTextProvider
30
+
31
+ /// Legacy protocol for providing dynamic text for a Lottie animation.
32
+ /// Instead prefer conforming to `AnimationKeypathTextProvider`.
33
+ public protocol LegacyAnimationTextProvider: AnimationKeypathTextProvider {
34
+ /// Legacy method to look up the text to display for the given keypath.
35
+ /// Instead, prefer implementing `AnimationKeypathTextProvider.`
36
+ /// The behavior of this method depends on the current rendering engine:
37
+ /// - The Core Animation rendering engine always calls this method
38
+ /// with the full keypath (e.g. `MY_LAYER.text_value`).
39
+ /// - The Main Thread rendering engine always calls this method
40
+ /// with the final component of the key path (e.g. just `text_value`).
14
41
  func textFor(keypathName: String, sourceText: String) -> String
15
42
  }
16
43
 
44
+ extension LegacyAnimationTextProvider {
45
+ public func text(for _: AnimationKeypath, sourceText _: String) -> String? {
46
+ nil
47
+ }
48
+ }
49
+
17
50
  // MARK: - DictionaryTextProvider
18
51
 
19
- /// Text provider that simply map values from dictionary
20
- public final class DictionaryTextProvider: AnimationTextProvider {
52
+ /// Text provider that simply map values from dictionary.
53
+ /// - The dictionary keys can either be the full layer keypath string (e.g. `MY_LAYER.text_value`)
54
+ /// or simply the final path component of the keypath (e.g. `text_value`).
55
+ public final class DictionaryTextProvider: AnimationKeypathTextProvider, LegacyAnimationTextProvider {
21
56
 
22
57
  // MARK: Lifecycle
23
58
 
@@ -27,6 +62,24 @@ public final class DictionaryTextProvider: AnimationTextProvider {
27
62
 
28
63
  // MARK: Public
29
64
 
65
+ public func text(for keypath: AnimationKeypath, sourceText: String) -> String? {
66
+ if let valueForFullKeypath = values[keypath.fullPath] {
67
+ return valueForFullKeypath
68
+ }
69
+
70
+ else if
71
+ let lastKeypathComponent = keypath.keys.last,
72
+ let valueForLastComponent = values[lastKeypathComponent]
73
+ {
74
+ return valueForLastComponent
75
+ }
76
+
77
+ else {
78
+ return sourceText
79
+ }
80
+ }
81
+
82
+ // Never called directly by Lottie, but we continue to implement this conformance for backwards compatibility.
30
83
  public func textFor(keypathName: String, sourceText: String) -> String {
31
84
  values[keypathName] ?? sourceText
32
85
  }
@@ -36,10 +89,18 @@ public final class DictionaryTextProvider: AnimationTextProvider {
36
89
  let values: [String: String]
37
90
  }
38
91
 
92
+ // MARK: Equatable
93
+
94
+ extension DictionaryTextProvider: Equatable {
95
+ public static func ==(_ lhs: DictionaryTextProvider, _ rhs: DictionaryTextProvider) -> Bool {
96
+ lhs.values == rhs.values
97
+ }
98
+ }
99
+
39
100
  // MARK: - DefaultTextProvider
40
101
 
41
102
  /// Default text provider. Uses text in the animation file
42
- public final class DefaultTextProvider: AnimationTextProvider {
103
+ public final class DefaultTextProvider: AnimationKeypathTextProvider, LegacyAnimationTextProvider {
43
104
 
44
105
  // MARK: Lifecycle
45
106
 
@@ -50,4 +111,16 @@ public final class DefaultTextProvider: AnimationTextProvider {
50
111
  public func textFor(keypathName _: String, sourceText: String) -> String {
51
112
  sourceText
52
113
  }
114
+
115
+ public func text(for _: AnimationKeypath, sourceText: String) -> String {
116
+ sourceText
117
+ }
118
+ }
119
+
120
+ // MARK: Equatable
121
+
122
+ extension DefaultTextProvider: Equatable {
123
+ public static func ==(_: DefaultTextProvider, _: DefaultTextProvider) -> Bool {
124
+ true
125
+ }
53
126
  }
@@ -6,7 +6,7 @@
6
6
  //
7
7
 
8
8
  import Foundation
9
- #if os(iOS) || os(tvOS) || os(watchOS) || targetEnvironment(macCatalyst)
9
+ #if canImport(UIKit)
10
10
  import UIKit
11
11
 
12
12
  /// A view that can be added to a keypath of an AnimationView
@@ -7,7 +7,7 @@
7
7
 
8
8
  import CoreGraphics
9
9
  import Foundation
10
- #if os(iOS) || os(tvOS) || os(watchOS) || targetEnvironment(macCatalyst)
10
+ #if canImport(UIKit)
11
11
  import UIKit
12
12
 
13
13
  /// An `AnimationImageProvider` that provides images by name from a specific bundle.
@@ -23,10 +23,12 @@ public class BundleImageProvider: AnimationImageProvider {
23
23
  ///
24
24
  /// - Parameter bundle: The bundle containing images for the provider.
25
25
  /// - Parameter searchPath: The subpath is a path within the bundle to search for image assets.
26
+ /// - Parameter contentsGravity: The contents gravity to use when rendering the image.
26
27
  ///
27
- public init(bundle: Bundle, searchPath: String?) {
28
+ public init(bundle: Bundle, searchPath: String?, contentsGravity: CALayerContentsGravity = .resize) {
28
29
  self.bundle = bundle
29
30
  self.searchPath = searchPath
31
+ self.contentsGravity = contentsGravity
30
32
  }
31
33
 
32
34
  // MARK: Public
@@ -81,9 +83,21 @@ public class BundleImageProvider: AnimationImageProvider {
81
83
  return image.cgImage
82
84
  }
83
85
 
86
+ public func contentsGravity(for _: ImageAsset) -> CALayerContentsGravity {
87
+ contentsGravity
88
+ }
89
+
84
90
  // MARK: Internal
85
91
 
86
92
  let bundle: Bundle
87
93
  let searchPath: String?
94
+ let contentsGravity: CALayerContentsGravity
95
+ }
96
+
97
+ extension BundleImageProvider: Equatable {
98
+ public static func ==(_ lhs: BundleImageProvider, _ rhs: BundleImageProvider) -> Bool {
99
+ lhs.bundle == rhs.bundle
100
+ && lhs.searchPath == rhs.searchPath
101
+ }
88
102
  }
89
103
  #endif
@@ -30,7 +30,7 @@ public final class CompatibleAnimation: NSObject {
30
30
 
31
31
  // MARK: Internal
32
32
 
33
- internal var animation: LottieAnimation? {
33
+ var animation: LottieAnimation? {
34
34
  LottieAnimation.named(name, bundle: bundle, subdirectory: subdirectory)
35
35
  }
36
36
 
@@ -533,7 +533,7 @@ public final class CompatibleDictionaryTextProvider: NSObject {
533
533
 
534
534
  // MARK: Internal
535
535
 
536
- internal var textProvider: AnimationTextProvider? {
536
+ var textProvider: AnimationKeypathTextProvider? {
537
537
  DictionaryTextProvider(values)
538
538
  }
539
539