lottie-ios 4.3.3 → 4.4.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 (199) hide show
  1. package/.github/workflows/main.yml +51 -58
  2. package/Lottie.xcodeproj/project.pbxproj +40 -0
  3. package/Lottie.xcodeproj/xcuserdata/calstephens.xcuserdatad/xcschemes/xcschememanagement.plist +4 -17
  4. package/Lottie.xcworkspace/xcshareddata/swiftpm/Package.resolved +37 -40
  5. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  6. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +9 -666
  7. package/Package.resolved +20 -22
  8. package/Package.swift +4 -2
  9. package/README.md +21 -3
  10. package/Rakefile +52 -28
  11. package/Sources/PrivacyInfo.xcprivacy +23 -0
  12. package/Sources/Private/CoreAnimation/Animations/CAAnimation+TimingConfiguration.swift +1 -1
  13. package/Sources/Private/CoreAnimation/Animations/CALayer+addAnimation.swift +23 -13
  14. package/Sources/Private/CoreAnimation/Animations/CustomPathAnimation.swift +8 -2
  15. package/Sources/Private/CoreAnimation/Animations/EllipseAnimation.swift +7 -1
  16. package/Sources/Private/CoreAnimation/Animations/GradientAnimations.swift +15 -2
  17. package/Sources/Private/CoreAnimation/Animations/LayerProperty.swift +8 -1
  18. package/Sources/Private/CoreAnimation/Animations/RectangleAnimation.swift +8 -1
  19. package/Sources/Private/CoreAnimation/Animations/StarAnimation.swift +12 -1
  20. package/Sources/Private/CoreAnimation/Animations/StrokeAnimation.swift +0 -1
  21. package/Sources/Private/CoreAnimation/Animations/TransformAnimations.swift +19 -11
  22. package/Sources/Private/CoreAnimation/Animations/VisibilityAnimation.swift +45 -19
  23. package/Sources/Private/CoreAnimation/CoreAnimationLayer.swift +38 -3
  24. package/Sources/Private/CoreAnimation/Extensions/CALayer+fillBounds.swift +1 -1
  25. package/Sources/Private/CoreAnimation/Extensions/Keyframes+combined.swift +9 -2
  26. package/Sources/Private/CoreAnimation/Extensions/Keyframes+timeRemapping.swift +46 -0
  27. package/Sources/Private/CoreAnimation/Layers/AnimationLayer.swift +77 -13
  28. package/Sources/Private/CoreAnimation/Layers/BaseCompositionLayer.swift +1 -1
  29. package/Sources/Private/CoreAnimation/Layers/CALayer+setupLayerHierarchy.swift +2 -2
  30. package/Sources/Private/CoreAnimation/Layers/ImageLayer.swift +1 -1
  31. package/Sources/Private/CoreAnimation/Layers/LayerModel+makeAnimationLayer.swift +1 -7
  32. package/Sources/Private/CoreAnimation/Layers/PreCompLayer.swift +19 -53
  33. package/Sources/Private/CoreAnimation/Layers/ShapeItemLayer.swift +2 -2
  34. package/Sources/Private/CoreAnimation/Layers/ShapeLayer.swift +97 -31
  35. package/Sources/Private/CoreAnimation/Layers/SolidLayer.swift +5 -2
  36. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/EpoxyModelArrayBuilder.swift +1 -1
  37. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Model/EpoxyModelProperty.swift +10 -10
  38. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIHostingController.swift +1 -1
  39. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIHostingView.swift +1 -3
  40. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIIntrinsicContentSizeInvalidator.swift +2 -0
  41. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUILayoutMargins.swift +2 -0
  42. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxyableView+SwiftUIView.swift +2 -0
  43. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/LayoutUtilities/MeasuringViewRepresentable.swift +2 -0
  44. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/LayoutUtilities/SwiftUIMeasurementContainer.swift +2 -0
  45. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/SwiftUIView.swift +2 -0
  46. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/UIView+SwiftUIView.swift +2 -0
  47. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/UIViewConfiguringSwiftUIView.swift +2 -0
  48. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/ViewType.swift +2 -1
  49. package/Sources/Private/EmbeddedLibraries/LRUCache/LRUCache.swift +256 -0
  50. package/Sources/Private/EmbeddedLibraries/LRUCache/README.md +24 -0
  51. package/Sources/Private/EmbeddedLibraries/README.md +16 -0
  52. package/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+Helpers.swift +2 -2
  53. package/Sources/Private/EmbeddedLibraries/ZipFoundation/Archive+MemoryFile.swift +7 -7
  54. package/Sources/Private/EmbeddedLibraries/ZipFoundation/Data+Compression.swift +2 -2
  55. package/Sources/Private/EmbeddedLibraries/ZipFoundation/FileManager+ZIP.swift +5 -5
  56. package/Sources/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.swift +1 -2
  57. package/Sources/Private/MainThread/LayerContainers/CompLayers/ImageCompositionLayer.swift +1 -3
  58. package/Sources/Private/MainThread/LayerContainers/CompLayers/MaskContainerLayer.swift +1 -2
  59. package/Sources/Private/MainThread/LayerContainers/CompLayers/PreCompositionLayer.swift +2 -3
  60. package/Sources/Private/MainThread/LayerContainers/CompLayers/SolidCompositionLayer.swift +2 -3
  61. package/Sources/Private/MainThread/LayerContainers/CompLayers/TextCompositionLayer.swift +5 -12
  62. package/Sources/Private/MainThread/LayerContainers/MainThreadAnimationLayer.swift +0 -1
  63. package/Sources/Private/MainThread/LayerContainers/Utility/CachedImageProvider.swift +11 -7
  64. package/Sources/Private/MainThread/LayerContainers/Utility/CompositionLayersInitializer.swift +3 -3
  65. package/Sources/Private/MainThread/LayerContainers/Utility/CoreTextRenderLayer.swift +12 -12
  66. package/Sources/Private/MainThread/LayerContainers/Utility/InvertedMatteLayer.swift +1 -3
  67. package/Sources/Private/MainThread/LayerContainers/Utility/LayerFontProvider.swift +0 -2
  68. package/Sources/Private/MainThread/LayerContainers/Utility/LayerImageProvider.swift +1 -3
  69. package/Sources/Private/MainThread/LayerContainers/Utility/LayerTextProvider.swift +0 -2
  70. package/Sources/Private/MainThread/LayerContainers/Utility/LayerTransformNode.swift +0 -2
  71. package/Sources/Private/MainThread/NodeRenderSystem/Extensions/ItemsExtension.swift +1 -3
  72. package/Sources/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/KeypathSearchable.swift +0 -1
  73. package/Sources/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/NodePropertyMap.swift +0 -1
  74. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/GroupOutputNode.swift +1 -3
  75. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/PassThroughOutputNode.swift +1 -2
  76. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/PathOutputNode.swift +0 -1
  77. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/FillRenderer.swift +0 -2
  78. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/GradientFillRenderer.swift +0 -1
  79. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/GradientStrokeRenderer.swift +0 -1
  80. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/LegacyGradientFillRenderer.swift +0 -1
  81. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/Renderables/StrokeRenderer.swift +2 -3
  82. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderContainers/GroupNode.swift +1 -3
  83. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/StrokeNode.swift +2 -2
  84. package/Sources/Private/MainThread/NodeRenderSystem/Nodes/Text/TextAnimatorNode.swift +0 -2
  85. package/Sources/Private/MainThread/NodeRenderSystem/Protocols/AnimatorNode.swift +0 -1
  86. package/Sources/Private/MainThread/NodeRenderSystem/Protocols/PathNode.swift +0 -2
  87. package/Sources/Private/MainThread/NodeRenderSystem/Protocols/RenderNode.swift +0 -2
  88. package/Sources/Private/MainThread/NodeRenderSystem/RenderLayers/ShapeContainerLayer.swift +0 -1
  89. package/Sources/Private/MainThread/NodeRenderSystem/RenderLayers/ShapeRenderLayer.swift +0 -1
  90. package/Sources/Private/Model/Assets/Asset.swift +2 -3
  91. package/Sources/Private/Model/Assets/AssetLibrary.swift +11 -11
  92. package/Sources/Private/Model/Assets/ImageAsset.swift +20 -0
  93. package/Sources/Private/Model/Assets/PrecompAsset.swift +0 -2
  94. package/Sources/Private/Model/DictionaryInitializable.swift +18 -10
  95. package/Sources/Private/Model/DotLottie/DotLottieImageProvider.swift +9 -6
  96. package/Sources/Private/Model/DotLottie/DotLottieUtils.swift +1 -1
  97. package/Sources/Private/Model/Extensions/KeyedDecodingContainerExtensions.swift +5 -4
  98. package/Sources/Private/Model/Keyframes/KeyframeData.swift +1 -4
  99. package/Sources/Private/Model/Keyframes/KeyframeGroup.swift +1 -3
  100. package/Sources/Private/Model/LayerEffects/DropShadowEffect.swift +0 -2
  101. package/Sources/Private/Model/LayerEffects/EffectValues/ColorEffectValue.swift +0 -2
  102. package/Sources/Private/Model/LayerEffects/EffectValues/EffectValue.swift +4 -5
  103. package/Sources/Private/Model/LayerEffects/EffectValues/Vector1DEffectValue.swift +0 -2
  104. package/Sources/Private/Model/LayerEffects/LayerEffect.swift +2 -3
  105. package/Sources/Private/Model/LayerStyles/DropShadowStyle.swift +0 -2
  106. package/Sources/Private/Model/LayerStyles/LayerStyle.swift +2 -3
  107. package/Sources/Private/Model/Layers/ImageLayerModel.swift +0 -2
  108. package/Sources/Private/Model/Layers/LayerModel.swift +16 -5
  109. package/Sources/Private/Model/Layers/PreCompLayerModel.swift +0 -2
  110. package/Sources/Private/Model/Layers/ShapeLayerModel.swift +0 -2
  111. package/Sources/Private/Model/Layers/SolidLayerModel.swift +0 -2
  112. package/Sources/Private/Model/Layers/TextLayerModel.swift +0 -2
  113. package/Sources/Private/Model/Objects/DashPattern.swift +1 -3
  114. package/Sources/Private/Model/Objects/Marker.swift +0 -2
  115. package/Sources/Private/Model/Objects/Mask.swift +0 -2
  116. package/Sources/Private/Model/Objects/Transform.swift +46 -9
  117. package/Sources/Private/Model/ShapeItems/Ellipse.swift +0 -2
  118. package/Sources/Private/Model/ShapeItems/Fill.swift +0 -2
  119. package/Sources/Private/Model/ShapeItems/GradientFill.swift +1 -3
  120. package/Sources/Private/Model/ShapeItems/GradientStroke.swift +1 -3
  121. package/Sources/Private/Model/ShapeItems/Group.swift +0 -2
  122. package/Sources/Private/Model/ShapeItems/Merge.swift +1 -3
  123. package/Sources/Private/Model/ShapeItems/Rectangle.swift +0 -2
  124. package/Sources/Private/Model/ShapeItems/Repeater.swift +0 -2
  125. package/Sources/Private/Model/ShapeItems/RoundedCorners.swift +0 -2
  126. package/Sources/Private/Model/ShapeItems/Shape.swift +0 -2
  127. package/Sources/Private/Model/ShapeItems/ShapeItem.swift +2 -3
  128. package/Sources/Private/Model/ShapeItems/ShapeTransform.swift +0 -2
  129. package/Sources/Private/Model/ShapeItems/Star.swift +1 -3
  130. package/Sources/Private/Model/ShapeItems/Stroke.swift +0 -2
  131. package/Sources/Private/Model/ShapeItems/Trim.swift +1 -3
  132. package/Sources/Private/Model/Text/Font.swift +0 -2
  133. package/Sources/Private/Model/Text/Glyph.swift +0 -2
  134. package/Sources/Private/Model/Text/TextAnimator.swift +0 -2
  135. package/Sources/Private/Model/Text/TextDocument.swift +2 -4
  136. package/Sources/Private/Utility/Debugging/AnimatorNodeDebugging.swift +0 -2
  137. package/Sources/Private/Utility/Debugging/LayerDebugging.swift +4 -5
  138. package/Sources/Private/Utility/Extensions/AnimationKeypathExtension.swift +2 -3
  139. package/Sources/Private/Utility/Extensions/DataExtension.swift +0 -1
  140. package/Sources/Private/Utility/Extensions/StringExtensions.swift +5 -0
  141. package/Sources/Private/Utility/Helpers/AnimationContext.swift +2 -3
  142. package/Sources/Private/Utility/Helpers/AnyEquatable.swift +0 -2
  143. package/Sources/Private/Utility/Helpers/Binding+Map.swift +2 -0
  144. package/Sources/Private/Utility/Helpers/View+ValueChanged.swift +2 -0
  145. package/Sources/Private/Utility/LottieAnimationSource.swift +11 -1
  146. package/Sources/Private/Utility/Primitives/BezierPath.swift +2 -3
  147. package/Sources/Private/Utility/Primitives/CGPointExtension.swift +1 -1
  148. package/Sources/Private/Utility/Primitives/ColorExtension.swift +1 -2
  149. package/Sources/Private/Utility/Primitives/VectorsExtensions.swift +6 -6
  150. package/Sources/Public/Animation/LottieAnimation.swift +2 -2
  151. package/Sources/Public/Animation/LottieAnimationHelpers.swift +7 -5
  152. package/Sources/Public/Animation/LottieAnimationLayer.swift +30 -43
  153. package/Sources/Public/Animation/LottieAnimationView.swift +18 -8
  154. package/Sources/Public/Animation/LottieAnimationViewInitializers.swift +3 -3
  155. package/Sources/Public/Animation/LottiePlaybackMode.swift +53 -0
  156. package/Sources/Public/Animation/LottieView.swift +145 -48
  157. package/Sources/Public/AnimationCache/AnimationCacheProvider.swift +0 -2
  158. package/Sources/Public/AnimationCache/DefaultAnimationCache.swift +21 -7
  159. package/Sources/Public/AnimationCache/LRUAnimationCache.swift +0 -2
  160. package/Sources/Public/Controls/AnimatedButton.swift +4 -6
  161. package/Sources/Public/Controls/AnimatedControl.swift +1 -3
  162. package/Sources/Public/Controls/AnimatedSwitch.swift +1 -3
  163. package/Sources/Public/Controls/LottieButton.swift +2 -1
  164. package/Sources/Public/Controls/LottieSwitch.swift +2 -0
  165. package/Sources/Public/DotLottie/Cache/DotLottieCache.swift +17 -4
  166. package/Sources/Public/DotLottie/Cache/DotLottieCacheProvider.swift +1 -3
  167. package/Sources/Public/DotLottie/DotLottieConfiguration.swift +53 -5
  168. package/Sources/Public/DotLottie/DotLottieFile.swift +4 -3
  169. package/Sources/Public/DotLottie/DotLottieFileHelpers.swift +18 -11
  170. package/Sources/Public/DynamicProperties/AnimationKeypath.swift +0 -2
  171. package/Sources/Public/DynamicProperties/AnyValueProvider.swift +0 -1
  172. package/Sources/Public/DynamicProperties/ValueProviders/ColorValueProvider.swift +2 -2
  173. package/Sources/Public/DynamicProperties/ValueProviders/FloatValueProvider.swift +1 -1
  174. package/Sources/Public/DynamicProperties/ValueProviders/GradientValueProvider.swift +1 -1
  175. package/Sources/Public/DynamicProperties/ValueProviders/PointValueProvider.swift +1 -1
  176. package/Sources/Public/DynamicProperties/ValueProviders/SizeValueProvider.swift +1 -1
  177. package/Sources/Public/FontProvider/AnimationFontProvider.swift +0 -2
  178. package/Sources/Public/ImageProvider/AnimationImageProvider.swift +0 -2
  179. package/Sources/Public/Keyframes/Interpolatable.swift +26 -0
  180. package/Sources/Public/Primitives/LottieColor.swift +0 -2
  181. package/Sources/Public/Primitives/Vectors.swift +0 -2
  182. package/Sources/Public/TextProvider/AnimationTextProvider.swift +0 -2
  183. package/Sources/Public/iOS/AnimationSubview.swift +0 -1
  184. package/Sources/Public/iOS/BundleImageProvider.swift +3 -8
  185. package/Sources/Public/iOS/Compatibility/CompatibleAnimationView.swift +4 -8
  186. package/Sources/Public/iOS/LottieAnimationViewBase.swift +5 -2
  187. package/Sources/Public/iOS/UIColorExtension.swift +1 -2
  188. package/Sources/Public/macOS/BundleImageProvider.macOS.swift +3 -6
  189. package/lottie-ios.podspec +6 -2
  190. package/package.json +1 -1
  191. package/Lottie.xcodeproj/project.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  192. package/Lottie.xcodeproj/project.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  193. package/Lottie.xcodeproj/xcuserdata/cal.xcuserdatad/xcschemes/xcschememanagement.plist +0 -37
  194. package/Lottie.xcworkspace/xcuserdata/cal.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  195. package/Lottie.xcworkspace/xcuserdata/cal.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +0 -6
  196. package/Lottie.xcworkspace/xcuserdata/cal.xcuserdatad/xcdebugger/Expressions.xcexplist +0 -153
  197. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/IDEFindNavigatorScopes.plist +0 -5
  198. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Expressions.xcexplist +0 -231
  199. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcschemes/xcschememanagement.plist +0 -37
@@ -5,7 +5,6 @@
5
5
  // Created by Brandon Withrow on 1/30/19.
6
6
  //
7
7
 
8
- import Foundation
9
8
  import QuartzCore
10
9
 
11
10
  // MARK: - Renderer
@@ -5,7 +5,6 @@
5
5
  // Created by Brandon Withrow on 1/30/19.
6
6
  //
7
7
 
8
- import Foundation
9
8
  import QuartzCore
10
9
 
11
10
  /// A rendered for a Path Fill
@@ -5,7 +5,6 @@
5
5
  // Created by Brandon Withrow on 1/30/19.
6
6
  //
7
7
 
8
- import Foundation
9
8
  import QuartzCore
10
9
 
11
10
  extension LineJoin {
@@ -132,7 +131,7 @@ final class StrokeRenderer: PassThroughOutputNode, Renderable {
132
131
  inContext.setMiterLimit(miterLimit)
133
132
  inContext.setLineCap(lineCap.cgLineCap)
134
133
  inContext.setLineJoin(lineJoin.cgLineJoin)
135
- if let dashPhase = dashPhase, let lengths = dashLengths {
134
+ if let dashPhase, let lengths = dashLengths {
136
135
  inContext.setLineDash(phase: dashPhase, lengths: lengths)
137
136
  } else {
138
137
  inContext.setLineDash(phase: 0, lengths: [])
@@ -143,7 +142,7 @@ final class StrokeRenderer: PassThroughOutputNode, Renderable {
143
142
  guard inContext.path != nil, inContext.path!.isEmpty == false else {
144
143
  return
145
144
  }
146
- guard let color = color else { return }
145
+ guard let color else { return }
147
146
  hasUpdate = false
148
147
  setupForStroke(inContext)
149
148
  inContext.setAlpha(opacity)
@@ -5,8 +5,6 @@
5
5
  // Created by Brandon Withrow on 1/18/19.
6
6
  //
7
7
 
8
- import CoreGraphics
9
- import Foundation
10
8
  import QuartzCore
11
9
 
12
10
  // MARK: - GroupNodeProperties
@@ -16,7 +14,7 @@ final class GroupNodeProperties: NodePropertyMap, KeypathSearchable {
16
14
  // MARK: Lifecycle
17
15
 
18
16
  init(transform: ShapeTransform?) {
19
- if let transform = transform {
17
+ if let transform {
20
18
  anchor = NodeProperty(provider: KeyframeInterpolator(keyframes: transform.anchor.keyframes))
21
19
  position = NodeProperty(provider: KeyframeInterpolator(keyframes: transform.position.keyframes))
22
20
  scale = NodeProperty(provider: KeyframeInterpolator(keyframes: transform.scale.keyframes))
@@ -131,7 +131,7 @@ final class StrokeNode: AnimatorNode, RenderNode {
131
131
 
132
132
  // MARK: - [DashElement] + shapeLayerConfiguration
133
133
 
134
- extension Array where Element == DashElement {
134
+ extension [DashElement] {
135
135
  typealias ShapeLayerConfiguration = (
136
136
  dashPatterns: ContiguousArray<ContiguousArray<Keyframe<LottieVector1D>>>,
137
137
  dashPhase: ContiguousArray<Keyframe<LottieVector1D>>)
@@ -168,7 +168,7 @@ extension Array where Element == DashElement {
168
168
  }
169
169
  }
170
170
 
171
- extension Array where Element == CGFloat {
171
+ extension [CGFloat] {
172
172
  // If all of the items in the dash pattern are zeros, then we shouldn't attempt to render it.
173
173
  // This causes Core Animation to have extremely poor performance for some reason, even though
174
174
  // it doesn't affect the appearance of the animation.
@@ -5,8 +5,6 @@
5
5
  // Created by Brandon Withrow on 2/19/19.
6
6
  //
7
7
 
8
- import CoreGraphics
9
- import Foundation
10
8
  import QuartzCore
11
9
 
12
10
  // MARK: - TextAnimatorNodeProperties
@@ -5,7 +5,6 @@
5
5
  // Created by Brandon Withrow on 1/15/19.
6
6
  //
7
7
 
8
- import Foundation
9
8
  import QuartzCore
10
9
 
11
10
  // MARK: - NodeOutput
@@ -5,8 +5,6 @@
5
5
  // Created by Brandon Withrow on 1/17/19.
6
6
  //
7
7
 
8
- import Foundation
9
-
10
8
  // MARK: - PathNode
11
9
 
12
10
  protocol PathNode {
@@ -5,8 +5,6 @@
5
5
  // Created by Brandon Withrow on 1/17/19.
6
6
  //
7
7
 
8
- import CoreGraphics
9
- import Foundation
10
8
  import QuartzCore
11
9
 
12
10
  // MARK: - RenderNode
@@ -5,7 +5,6 @@
5
5
  // Created by Brandon Withrow on 1/30/19.
6
6
  //
7
7
 
8
- import Foundation
9
8
  import QuartzCore
10
9
 
11
10
  /// The base layer that holds Shapes and Shape Renderers
@@ -5,7 +5,6 @@
5
5
  // Created by Brandon Withrow on 1/18/19.
6
6
  //
7
7
 
8
- import Foundation
9
8
  import QuartzCore
10
9
 
11
10
  /// The layer responsible for rendering shape objects
@@ -5,8 +5,6 @@
5
5
  // Created by Brandon Withrow on 1/9/19.
6
6
  //
7
7
 
8
- import Foundation
9
-
10
8
  // MARK: - Asset
11
9
 
12
10
  public class Asset: Codable, DictionaryInitializable {
@@ -28,7 +26,7 @@ public class Asset: Codable, DictionaryInitializable {
28
26
  } else if let id = dictionary[CodingKeys.id.rawValue] as? Int {
29
27
  self.id = String(id)
30
28
  } else {
31
- throw InitializableError.invalidInput
29
+ throw InitializableError.invalidInput()
32
30
  }
33
31
  }
34
32
 
@@ -48,4 +46,5 @@ public class Asset: Codable, DictionaryInitializable {
48
46
 
49
47
  /// Since `Asset` isn't `final`, we have to use `@unchecked Sendable` instead of `Sendable.`
50
48
  /// All `Asset` subclasses are immutable `Sendable` values.
49
+ // swiftlint:disable:next no_unchecked_sendable
51
50
  extension Asset: @unchecked Sendable { }
@@ -5,8 +5,6 @@
5
5
  // Created by Brandon Withrow on 1/9/19.
6
6
  //
7
7
 
8
- import Foundation
9
-
10
8
  final class AssetLibrary: Codable, AnyInitializable, Sendable {
11
9
 
12
10
  // MARK: Lifecycle
@@ -20,14 +18,17 @@ final class AssetLibrary: Codable, AnyInitializable, Sendable {
20
18
  var imageAssets = [String : ImageAsset]()
21
19
  var precompAssets = [String : PrecompAsset]()
22
20
 
23
- while !container.isAtEnd {
24
- let keyContainer = try containerForKeys.nestedContainer(keyedBy: PrecompAsset.CodingKeys.self)
25
- if keyContainer.contains(.layers) {
26
- let precompAsset = try container.decode(PrecompAsset.self)
21
+ while
22
+ !container.isAtEnd,
23
+ let keyContainer = try? containerForKeys.nestedContainer(keyedBy: PrecompAsset.CodingKeys.self)
24
+ {
25
+ if
26
+ keyContainer.contains(.layers),
27
+ let precompAsset = try? container.decode(PrecompAsset.self)
28
+ {
27
29
  decodedAssets[precompAsset.id] = precompAsset
28
30
  precompAssets[precompAsset.id] = precompAsset
29
- } else {
30
- let imageAsset = try container.decode(ImageAsset.self)
31
+ } else if let imageAsset = try? container.decode(ImageAsset.self) {
31
32
  decodedAssets[imageAsset.id] = imageAsset
32
33
  imageAssets[imageAsset.id] = imageAsset
33
34
  }
@@ -39,7 +40,7 @@ final class AssetLibrary: Codable, AnyInitializable, Sendable {
39
40
 
40
41
  init(value: Any) throws {
41
42
  guard let dictionaries = value as? [[String: Any]] else {
42
- throw InitializableError.invalidInput
43
+ throw InitializableError.invalidInput()
43
44
  }
44
45
  var decodedAssets = [String : Asset]()
45
46
  var imageAssets = [String : ImageAsset]()
@@ -49,8 +50,7 @@ final class AssetLibrary: Codable, AnyInitializable, Sendable {
49
50
  let asset = try PrecompAsset(dictionary: dictionary)
50
51
  decodedAssets[asset.id] = asset
51
52
  precompAssets[asset.id] = asset
52
- } else {
53
- let asset = try ImageAsset(dictionary: dictionary)
53
+ } else if let asset = try? ImageAsset(dictionary: dictionary) {
54
54
  decodedAssets[asset.id] = asset
55
55
  imageAssets[asset.id] = asset
56
56
  }
@@ -5,8 +5,15 @@
5
5
  // Created by Brandon Withrow on 1/9/19.
6
6
  //
7
7
 
8
+ import CoreGraphics
8
9
  import Foundation
9
10
 
11
+ #if canImport(UIKit)
12
+ import UIKit
13
+ #elseif canImport(AppKit)
14
+ import AppKit
15
+ #endif
16
+
10
17
  // MARK: - ImageAsset
11
18
 
12
19
  public final class ImageAsset: Asset {
@@ -111,3 +118,16 @@ extension Data {
111
118
  }
112
119
 
113
120
  }
121
+
122
+ extension ImageAsset {
123
+ /// A `CGImage` loaded from this asset if represented using a Base 64 encoding
124
+ var base64Image: CGImage? {
125
+ guard let data = Data(imageAsset: self) else { return nil }
126
+
127
+ #if canImport(UIKit)
128
+ return UIImage(data: data)?.cgImage
129
+ #elseif canImport(AppKit)
130
+ return NSImage(data: data)?.lottie_CGImage
131
+ #endif
132
+ }
133
+ }
@@ -5,8 +5,6 @@
5
5
  // Created by Brandon Withrow on 1/9/19.
6
6
  //
7
7
 
8
- import Foundation
9
-
10
8
  final class PrecompAsset: Asset {
11
9
 
12
10
  // MARK: Lifecycle
@@ -5,12 +5,10 @@
5
5
  // Created by Marcelo Fabri on 5/5/22.
6
6
  //
7
7
 
8
- import Foundation
9
-
10
8
  // MARK: - InitializableError
11
9
 
12
10
  enum InitializableError: Error {
13
- case invalidInput
11
+ case invalidInput(file: StaticString = #file, line: UInt = #line)
14
12
  }
15
13
 
16
14
  // MARK: - DictionaryInitializable
@@ -32,14 +30,24 @@ protocol AnyInitializable {
32
30
  extension Dictionary {
33
31
 
34
32
  @_disfavoredOverload
35
- func value<T, KeyType: RawRepresentable>(for key: KeyType) throws -> T where KeyType.RawValue == Key {
33
+ func value<T, KeyType: RawRepresentable>(
34
+ for key: KeyType,
35
+ file: StaticString = #file,
36
+ line: UInt = #line)
37
+ throws -> T where KeyType.RawValue == Key
38
+ {
36
39
  guard let value = self[key.rawValue] as? T else {
37
- throw InitializableError.invalidInput
40
+ throw InitializableError.invalidInput(file: file, line: line)
38
41
  }
39
42
  return value
40
43
  }
41
44
 
42
- func value<T: AnyInitializable, KeyType: RawRepresentable>(for key: KeyType) throws -> T where KeyType.RawValue == Key {
45
+ func value<T: AnyInitializable, KeyType: RawRepresentable>(
46
+ for key: KeyType,
47
+ file: StaticString = #file,
48
+ line: UInt = #line)
49
+ throws -> T where KeyType.RawValue == Key
50
+ {
43
51
  if let value = self[key.rawValue] as? T {
44
52
  return value
45
53
  }
@@ -48,18 +56,18 @@ extension Dictionary {
48
56
  return try T(value: value)
49
57
  }
50
58
 
51
- throw InitializableError.invalidInput
59
+ throw InitializableError.invalidInput(file: file, line: line)
52
60
  }
53
61
 
54
62
  }
55
63
 
56
- // MARK: - Array + AnyInitializable
64
+ // MARK: - AnyInitializable + AnyInitializable
57
65
 
58
- extension Array: AnyInitializable where Element == Double {
66
+ extension [Double]: AnyInitializable {
59
67
 
60
68
  init(value: Any) throws {
61
69
  guard let array = value as? [Double] else {
62
- throw InitializableError.invalidInput
70
+ throw InitializableError.invalidInput()
63
71
  }
64
72
  self = array
65
73
  }
@@ -5,7 +5,6 @@
5
5
  // Created by Evandro Hoffmann on 20/10/22.
6
6
  //
7
7
 
8
- import Foundation
9
8
  #if canImport(UIKit)
10
9
  import UIKit
11
10
  #elseif canImport(AppKit)
@@ -23,12 +22,12 @@ class DotLottieImageProvider: AnimationImageProvider {
23
22
  ///
24
23
  /// - Parameter filepath: The absolute filepath containing the images.
25
24
  ///
26
- init(filepath: String) {
27
- self.filepath = URL(fileURLWithPath: filepath)
28
- loadImages()
25
+ convenience init?(filepath: String) {
26
+ self.init(filepath: URL(fileURLWithPath: filepath))
29
27
  }
30
28
 
31
- init(filepath: URL) {
29
+ init?(filepath: URL) {
30
+ guard filepath.urls.count > 0 else { return nil }
32
31
  self.filepath = filepath
33
32
  loadImages()
34
33
  }
@@ -38,7 +37,11 @@ class DotLottieImageProvider: AnimationImageProvider {
38
37
  let filepath: URL
39
38
 
40
39
  func imageForAsset(asset: ImageAsset) -> CGImage? {
41
- images[asset.name]
40
+ if let base64Image = asset.base64Image {
41
+ return base64Image
42
+ }
43
+
44
+ return images[asset.name]
42
45
  }
43
46
 
44
47
  // MARK: Private
@@ -9,7 +9,7 @@ import Foundation
9
9
 
10
10
  // MARK: - DotLottieUtils
11
11
 
12
- struct DotLottieUtils {
12
+ enum DotLottieUtils {
13
13
  static let dotLottieExtension = "lottie"
14
14
  static let jsonExtension = "json"
15
15
 
@@ -1,7 +1,5 @@
1
1
  // From: https://medium.com/@kewindannerfjordremeczki/swift-4-0-decodable-heterogeneous-collections-ecc0e6b468cf
2
2
 
3
- import Foundation
4
-
5
3
  // MARK: - ClassFamily
6
4
 
7
5
  /// To support a new class family, create an enum that conforms to this protocol and contains the different types.
@@ -9,6 +7,9 @@ protocol ClassFamily: Decodable {
9
7
  /// The discriminator key.
10
8
  static var discriminator: Discriminator { get }
11
9
 
10
+ /// The "unknown" fallback case if the type discriminator could not be parsed successfully.
11
+ static var unknown: Self { get }
12
+
12
13
  /// Returns the class type of the object corresponding to the value.
13
14
  func getType() -> AnyObject.Type
14
15
  }
@@ -34,7 +35,7 @@ extension KeyedDecodingContainer {
34
35
  var tmpContainer = container
35
36
  while !container.isAtEnd {
36
37
  let typeContainer = try container.nestedContainer(keyedBy: Discriminator.self)
37
- let family: U = try typeContainer.decode(U.self, forKey: U.discriminator)
38
+ let family: U = (try? typeContainer.decodeIfPresent(U.self, forKey: U.discriminator)) ?? .unknown
38
39
  if let type = family.getType() as? T.Type {
39
40
  list.append(try tmpContainer.decode(type))
40
41
  }
@@ -60,7 +61,7 @@ extension KeyedDecodingContainer {
60
61
  var tmpContainer = container
61
62
  while !container.isAtEnd {
62
63
  let typeContainer = try container.nestedContainer(keyedBy: Discriminator.self)
63
- let family: U = try typeContainer.decode(U.self, forKey: U.discriminator)
64
+ let family: U = (try? typeContainer.decodeIfPresent(U.self, forKey: U.discriminator)) ?? .unknown
64
65
  if let type = family.getType() as? T.Type {
65
66
  list.append(try tmpContainer.decode(type))
66
67
  }
@@ -5,9 +5,6 @@
5
5
  // Created by Brandon Withrow on 1/7/19.
6
6
  //
7
7
 
8
- import CoreGraphics
9
- import Foundation
10
-
11
8
  // MARK: - KeyframeData
12
9
 
13
10
  /// A generic class used to parse and remap keyframe json.
@@ -72,7 +69,7 @@ final class KeyframeData<T> {
72
69
  let spatialOutTangent: LottieVector3D?
73
70
 
74
71
  var isHold: Bool {
75
- if let hold = hold {
72
+ if let hold {
76
73
  return hold > 0
77
74
  }
78
75
  return false
@@ -5,8 +5,6 @@
5
5
  // Created by Brandon Withrow on 1/14/19.
6
6
  //
7
7
 
8
- import Foundation
9
-
10
8
  // MARK: - KeyframeGroup
11
9
 
12
10
  /// Used for coding/decoding a group of Keyframes by type.
@@ -166,7 +164,7 @@ extension KeyframeGroup: DictionaryInitializable where T: AnyInitializable {
166
164
  let value: T = data.startValue ?? previousKeyframeData?.endValue,
167
165
  let time = data.time
168
166
  else {
169
- throw InitializableError.invalidInput
167
+ throw InitializableError.invalidInput()
170
168
  }
171
169
  keyframes.append(Keyframe<T>(
172
170
  value: value,
@@ -1,8 +1,6 @@
1
1
  // Created by Cal Stephens on 8/14/23.
2
2
  // Copyright © 2023 Airbnb Inc. All rights reserved.
3
3
 
4
- import Foundation
5
-
6
4
  final class DropShadowEffect: LayerEffect {
7
5
 
8
6
  // MARK: Lifecycle
@@ -1,8 +1,6 @@
1
1
  // Created by Cal Stephens on 8/14/23.
2
2
  // Copyright © 2023 Airbnb Inc. All rights reserved.
3
3
 
4
- import Foundation
5
-
6
4
  final class ColorEffectValue: EffectValue {
7
5
 
8
6
  // MARK: Lifecycle
@@ -1,8 +1,6 @@
1
1
  // Created by Cal Stephens on 8/15/23.
2
2
  // Copyright © 2023 Airbnb Inc. All rights reserved.
3
3
 
4
- import Foundation
5
-
6
4
  // MARK: - EffectValueType
7
5
 
8
6
  /// https://lottiefiles.github.io/lottie-docs/schema/#/$defs/effect-values
@@ -50,8 +48,8 @@ class EffectValue: Codable, DictionaryInitializable {
50
48
  }
51
49
 
52
50
  required init(dictionary: [String: Any]) throws {
53
- type = EffectValueType(rawValue: try dictionary.value(for: CodingKeys.type)) ?? .unknown
54
- name = try dictionary.value(for: CodingKeys.name) ?? "Effect"
51
+ type = (try? dictionary.value(for: CodingKeys.type)).flatMap(EffectValueType.init(rawValue:)) ?? .unknown
52
+ name = (try? dictionary.value(for: CodingKeys.name)) ?? "Effect"
55
53
  }
56
54
 
57
55
  // MARK: Internal
@@ -70,7 +68,7 @@ class EffectValue: Codable, DictionaryInitializable {
70
68
  }
71
69
  }
72
70
 
73
- extension Array where Element == EffectValue {
71
+ extension [EffectValue] {
74
72
  static func fromDictionaries(_ dictionaries: [[String: Any]]) throws -> [EffectValue] {
75
73
  try dictionaries.compactMap { dictionary in
76
74
  let shapeType = dictionary[EffectValue.CodingKeys.type.rawValue] as? Int
@@ -95,4 +93,5 @@ extension Array where Element == EffectValue {
95
93
 
96
94
  /// Since `EffectValue` isn't `final`, we have to use `@unchecked Sendable` instead of `Sendable.`
97
95
  /// All `EffectValue` subclasses are immutable `Sendable` values.
96
+ // swiftlint:disable:next no_unchecked_sendable
98
97
  extension EffectValue: @unchecked Sendable { }
@@ -1,8 +1,6 @@
1
1
  // Created by Cal Stephens on 8/14/23.
2
2
  // Copyright © 2023 Airbnb Inc. All rights reserved.
3
3
 
4
- import Foundation
5
-
6
4
  final class Vector1DEffectValue: EffectValue {
7
5
 
8
6
  // MARK: Lifecycle
@@ -1,8 +1,6 @@
1
1
  // Created by Cal Stephens on 8/14/23.
2
2
  // Copyright © 2023 Airbnb Inc. All rights reserved.
3
3
 
4
- import Foundation
5
-
6
4
  // MARK: - LayerEffectType
7
5
 
8
6
  /// https://lottiefiles.github.io/lottie-docs/schema/#/$defs/effects
@@ -81,7 +79,7 @@ class LayerEffect: Codable, DictionaryInitializable {
81
79
  }
82
80
  }
83
81
 
84
- extension Array where Element == LayerEffect {
82
+ extension [LayerEffect] {
85
83
  static func fromDictionaries(_ dictionaries: [[String: Any]]) throws -> [LayerEffect] {
86
84
  try dictionaries.compactMap { dictionary in
87
85
  let shapeType = dictionary[LayerEffect.CodingKeys.type.rawValue] as? Int
@@ -100,4 +98,5 @@ extension Array where Element == LayerEffect {
100
98
 
101
99
  /// Since `LayerEffect` isn't `final`, we have to use `@unchecked Sendable` instead of `Sendable.`
102
100
  /// All `LayerEffect` subclasses are immutable `Sendable` values.
101
+ // swiftlint:disable:next no_unchecked_sendable
103
102
  extension LayerEffect: @unchecked Sendable { }
@@ -1,8 +1,6 @@
1
1
  // Created by Cal Stephens on 8/14/23.
2
2
  // Copyright © 2023 Airbnb Inc. All rights reserved.
3
3
 
4
- import Foundation
5
-
6
4
  final class DropShadowStyle: LayerStyle {
7
5
 
8
6
  // MARK: Lifecycle
@@ -1,8 +1,6 @@
1
1
  // Created by Cal Stephens on 8/14/23.
2
2
  // Copyright © 2023 Airbnb Inc. All rights reserved.
3
3
 
4
- import Foundation
5
-
6
4
  // MARK: - LayerStyleType
7
5
 
8
6
  enum LayerStyleType: Int, Codable, Sendable {
@@ -63,7 +61,7 @@ class LayerStyle: Codable, DictionaryInitializable {
63
61
  }
64
62
  }
65
63
 
66
- extension Array where Element == LayerStyle {
64
+ extension [LayerStyle] {
67
65
  static func fromDictionaries(_ dictionaries: [[String: Any]]) throws -> [LayerStyle] {
68
66
  try dictionaries.compactMap { dictionary in
69
67
  let shapeType = dictionary[LayerStyle.CodingKeys.type.rawValue] as? Int
@@ -82,4 +80,5 @@ extension Array where Element == LayerStyle {
82
80
 
83
81
  /// Since `LayerStyle` isn't `final`, we have to use `@unchecked Sendable` instead of `Sendable.`
84
82
  /// All `LayerStyle` subclasses are immutable `Sendable` values.
83
+ // swiftlint:disable:next no_unchecked_sendable
85
84
  extension LayerStyle: @unchecked Sendable { }
@@ -5,8 +5,6 @@
5
5
  // Created by Brandon Withrow on 1/8/19.
6
6
  //
7
7
 
8
- import Foundation
9
-
10
8
  /// A layer that holds an image.
11
9
  final class ImageLayerModel: LayerModel {
12
10
 
@@ -5,8 +5,6 @@
5
5
  // Created by Brandon Withrow on 1/7/19.
6
6
  //
7
7
 
8
- import Foundation
9
-
10
8
  // MARK: - LayerType + ClassFamily
11
9
 
12
10
  /// Used for mapping a heterogeneous list to classes for parsing.
@@ -27,6 +25,8 @@ extension LayerType: ClassFamily {
27
25
  return ShapeLayerModel.self
28
26
  case .text:
29
27
  return TextLayerModel.self
28
+ case .unknown:
29
+ return LayerModel.self
30
30
  }
31
31
  }
32
32
  }
@@ -40,6 +40,7 @@ public enum LayerType: Int, Codable {
40
40
  case null
41
41
  case shape
42
42
  case text
43
+ case unknown
43
44
 
44
45
  public init(from decoder: Decoder) throws {
45
46
  self = try LayerType(rawValue: decoder.singleValueContainer().decode(RawValue.self)) ?? .null
@@ -92,7 +93,7 @@ class LayerModel: Codable, DictionaryInitializable {
92
93
  inFrame = try container.decode(Double.self, forKey: .inFrame)
93
94
  outFrame = try container.decode(Double.self, forKey: .outFrame)
94
95
  startTime = try container.decode(Double.self, forKey: .startTime)
95
- transform = try container.decode(Transform.self, forKey: .transform)
96
+ transform = try container.decodeIfPresent(Transform.self, forKey: .transform) ?? .default
96
97
  parent = try container.decodeIfPresent(Int.self, forKey: .parent)
97
98
  blendMode = try container.decodeIfPresent(BlendMode.self, forKey: .blendMode) ?? .normal
98
99
  masks = try container.decodeIfPresent([Mask].self, forKey: .masks)
@@ -118,8 +119,15 @@ class LayerModel: Codable, DictionaryInitializable {
118
119
  inFrame = try dictionary.value(for: CodingKeys.inFrame)
119
120
  outFrame = try dictionary.value(for: CodingKeys.outFrame)
120
121
  startTime = try dictionary.value(for: CodingKeys.startTime)
121
- transform = try Transform(dictionary: try dictionary.value(for: CodingKeys.transform))
122
122
  parent = try? dictionary.value(for: CodingKeys.parent)
123
+ if
124
+ let transformDictionary: [String: Any] = try dictionary.value(for: CodingKeys.transform),
125
+ let transform = try? Transform(dictionary: transformDictionary)
126
+ {
127
+ self.transform = transform
128
+ } else {
129
+ transform = .default
130
+ }
123
131
  if
124
132
  let blendModeRawValue = dictionary[CodingKeys.blendMode.rawValue] as? Int,
125
133
  let blendMode = BlendMode(rawValue: blendModeRawValue)
@@ -223,7 +231,7 @@ class LayerModel: Codable, DictionaryInitializable {
223
231
  }
224
232
  }
225
233
 
226
- extension Array where Element == LayerModel {
234
+ extension [LayerModel] {
227
235
 
228
236
  static func fromDictionaries(_ dictionaries: [[String: Any]]) throws -> [LayerModel] {
229
237
  try dictionaries.compactMap { dictionary in
@@ -241,6 +249,8 @@ extension Array where Element == LayerModel {
241
249
  return try ShapeLayerModel(dictionary: dictionary)
242
250
  case .text:
243
251
  return try TextLayerModel(dictionary: dictionary)
252
+ case .unknown:
253
+ return try LayerModel(dictionary: dictionary)
244
254
  case .none:
245
255
  return nil
246
256
  }
@@ -252,4 +262,5 @@ extension Array where Element == LayerModel {
252
262
 
253
263
  /// Since `LayerModel` isn't `final`, we have to use `@unchecked Sendable` instead of `Sendable.`
254
264
  /// All `LayerModel` subclasses are immutable `Sendable` values.
265
+ // swiftlint:disable:next no_unchecked_sendable
255
266
  extension LayerModel: @unchecked Sendable { }
@@ -5,8 +5,6 @@
5
5
  // Created by Brandon Withrow on 1/8/19.
6
6
  //
7
7
 
8
- import Foundation
9
-
10
8
  /// A layer that holds another animation composition.
11
9
  final class PreCompLayerModel: LayerModel {
12
10