lottie-ios 4.4.0 → 4.4.2

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 (44) hide show
  1. package/.github/workflows/main.yml +15 -10
  2. package/Gemfile +1 -1
  3. package/Gemfile.lock +25 -25
  4. package/Lottie.xcodeproj/project.pbxproj +40 -44
  5. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/IDEFindNavigatorScopes.plist +5 -0
  6. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  7. package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +5 -21
  8. package/Package.swift +1 -1
  9. package/README.md +1 -1
  10. package/Rakefile +5 -17
  11. package/Sources/Private/EmbeddedLibraries/EpoxyCore/README.md +3 -4
  12. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIIntrinsicContentSizeInvalidator.swift +0 -1
  13. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUILayoutMargins.swift +0 -4
  14. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxyableView+SwiftUIView.swift +0 -4
  15. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/LayoutUtilities/MeasuringViewRepresentable.swift +0 -4
  16. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/LayoutUtilities/SwiftUIMeasurementContainer.swift +0 -1
  17. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/SwiftUIView.swift +0 -4
  18. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/UIView+SwiftUIView.swift +0 -1
  19. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/UIViewConfiguringSwiftUIView.swift +0 -2
  20. package/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/ViewType.swift +0 -4
  21. package/Sources/Private/MainThread/LayerContainers/Utility/CoreTextRenderLayer.swift +0 -1
  22. package/Sources/Private/Model/DotLottie/DotLottieImageProvider.swift +2 -2
  23. package/Sources/Private/Model/DotLottie/DotLottieUtils.swift +3 -5
  24. package/Sources/Private/Model/Extensions/Bundle.swift +1 -1
  25. package/Sources/Private/Utility/Extensions/DataExtension.swift +5 -8
  26. package/Sources/Private/Utility/Extensions/MathKit.swift +3 -3
  27. package/Sources/Private/Utility/Helpers/Binding+Map.swift +0 -1
  28. package/Sources/Private/Utility/Helpers/View+ValueChanged.swift +15 -2
  29. package/Sources/Public/Animation/LottieAnimationHelpers.swift +0 -1
  30. package/Sources/Public/Animation/LottieAnimationLayer.swift +8 -8
  31. package/Sources/Public/Animation/LottieAnimationView.swift +1 -6
  32. package/Sources/Public/Animation/LottieView.swift +11 -8
  33. package/Sources/Public/Controls/LottieButton.swift +0 -1
  34. package/Sources/Public/Controls/LottieSwitch.swift +0 -1
  35. package/Sources/Public/Controls/LottieViewType.swift +1 -1
  36. package/Sources/Public/DotLottie/DotLottieFileHelpers.swift +0 -5
  37. package/Sources/Public/iOS/Compatibility/CompatibleAnimationKeypath.swift +1 -1
  38. package/Sources/Public/iOS/Compatibility/CompatibleAnimationView.swift +1 -1
  39. package/Sources/Public/iOS/LottieAnimationViewBase.swift +1 -5
  40. package/Version.xcconfig +6 -0
  41. package/lottie-ios.podspec +7 -7
  42. package/package.json +1 -1
  43. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIHostingController.swift +0 -46
  44. package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIHostingView.swift +0 -389
@@ -7,32 +7,16 @@
7
7
  <BreakpointProxy
8
8
  BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
9
9
  <BreakpointContent
10
- uuid = "8091EB50-102C-46B2-9DCE-9CC40A3FE4E9"
10
+ uuid = "82609F00-E052-4A66-A922-03120D26327C"
11
11
  shouldBeEnabled = "No"
12
12
  ignoreCount = "0"
13
13
  continueAfterRunningActions = "No"
14
- filePath = "Sources/Private/MainThread/NodeRenderSystem/Nodes/RenderNodes/StrokeNode.swift"
14
+ filePath = "Sources/Private/CoreAnimation/CoreAnimationLayer.swift"
15
15
  startingColumnNumber = "9223372036854775807"
16
16
  endingColumnNumber = "9223372036854775807"
17
- startingLineNumber = "112"
18
- endingLineNumber = "112"
19
- landmarkName = "rebuildOutputs(frame:)"
20
- landmarkType = "7">
21
- </BreakpointContent>
22
- </BreakpointProxy>
23
- <BreakpointProxy
24
- BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
25
- <BreakpointContent
26
- uuid = "CC3C8E8A-14BE-4C8D-8423-0224C306B322"
27
- shouldBeEnabled = "No"
28
- ignoreCount = "0"
29
- continueAfterRunningActions = "No"
30
- filePath = "Sources/Private/CoreAnimation/Layers/ShapeItemLayer.swift"
31
- startingColumnNumber = "9223372036854775807"
32
- endingColumnNumber = "9223372036854775807"
33
- startingLineNumber = "245"
34
- endingLineNumber = "245"
35
- landmarkName = "ShapeItemLayer"
17
+ startingLineNumber = "26"
18
+ endingLineNumber = "26"
19
+ landmarkName = "CoreAnimationLayer"
36
20
  landmarkType = "3">
37
21
  </BreakpointContent>
38
22
  </BreakpointProxy>
package/Package.swift CHANGED
@@ -4,7 +4,7 @@ import PackageDescription
4
4
  let package = Package(
5
5
  name: "Lottie",
6
6
  // Minimum platform versions should be kept in sync with the per-platform targets in Lottie.xcodeproj, lottie-ios.podspec, and lottie-spm's Package.swift
7
- platforms: [.iOS("11.0"), .macOS("10.11"), .tvOS("11.0"), .custom("visionOS", versionString: "1.0")],
7
+ platforms: [.iOS("13.0"), .macOS("10.15"), .tvOS("13.0"), .custom("visionOS", versionString: "1.0")],
8
8
  products: [.library(name: "Lottie", targets: ["Lottie"])],
9
9
  dependencies: [
10
10
  .package(url: "https://github.com/airbnb/swift", .upToNextMajor(from: "1.0.1")),
package/README.md CHANGED
@@ -41,7 +41,7 @@ To install Lottie using [Swift Package Manager](https://github.com/apple/swift-p
41
41
  or you can add the following dependency to your `Package.swift`:
42
42
 
43
43
  ```swift
44
- .package(url: "https://github.com/airbnb/lottie-spm.git", from: "4.4.0")
44
+ .package(url: "https://github.com/airbnb/lottie-spm.git", from: "4.4.2")
45
45
  ```
46
46
 
47
47
  When using Swift Package Manager we recommend using the [lottie-spm](https://github.com/airbnb/lottie-spm) repo instead of the main lottie-ios repo. The main git repository for [lottie-ios](https://github.com/airbnb/lottie-ios) is somewhat large (300+ MB), and Swift Package Manager always downloads the full repository with all git history. The [lottie-spm](https://github.com/airbnb/lottie-spm) repo is much smaller (less than 500kb), so can be downloaded much more quickly.
package/Rakefile CHANGED
@@ -12,23 +12,23 @@ namespace :build do
12
12
 
13
13
  desc 'Builds the Lottie package for iOS'
14
14
  task :iOS do
15
- xcodebuild('build -scheme "Lottie (iOS)" -destination generic/platform=iOS -workspace Lottie.xcworkspace')
15
+ xcodebuild('build -scheme "Lottie (iOS)" -destination generic/platform=iOS -workspace Lottie.xcworkspace OTHER_SWIFT_FLAGS="-warnings-as-errors"')
16
16
  end
17
17
 
18
18
  desc 'Builds the Lottie package for macOS'
19
19
  task :macOS do
20
- xcodebuild('build -scheme "Lottie (macOS)" -destination generic/platform=macOS -workspace Lottie.xcworkspace')
20
+ xcodebuild('build -scheme "Lottie (macOS)" -destination generic/platform=macOS -workspace Lottie.xcworkspace OTHER_SWIFT_FLAGS="-warnings-as-errors"')
21
21
  end
22
22
 
23
23
  desc 'Builds the Lottie package for tvOS'
24
24
  task :tvOS do
25
- xcodebuild('build -scheme "Lottie (tvOS)" -destination generic/platform=tvOS -workspace Lottie.xcworkspace')
25
+ xcodebuild('build -scheme "Lottie (tvOS)" -destination generic/platform=tvOS -workspace Lottie.xcworkspace OTHER_SWIFT_FLAGS="-warnings-as-errors"')
26
26
  end
27
27
 
28
28
  desc 'Builds the Lottie package for visionOS'
29
29
  task :visionOS do
30
30
  ifVisionOSEnabled {
31
- xcodebuild('build -scheme "Lottie (visionOS)" -destination generic/platform=visionOS -workspace Lottie.xcworkspace')
31
+ xcodebuild('build -scheme "Lottie (visionOS)" -destination generic/platform=visionOS -workspace Lottie.xcworkspace OTHER_SWIFT_FLAGS="-warnings-as-errors"')
32
32
  }
33
33
  end
34
34
  end
@@ -146,8 +146,6 @@ namespace :test do
146
146
  sh 'cp -R [^script]* script/test-carthage/Carthage/Checkouts/lottie-ios'
147
147
 
148
148
  Dir.chdir('script/test-carthage') do
149
- installVisionOSIfNecessary()
150
-
151
149
  # Build the Lottie framework scheme
152
150
  sh 'carthage build --use-xcframeworks'
153
151
 
@@ -256,16 +254,6 @@ def ifVisionOSEnabled
256
254
  if ENV["SKIP_VISION_OS"] == "true"
257
255
  puts "Skipping visionOS build"
258
256
  else
259
- installVisionOSIfNecessary()
260
257
  yield
261
258
  end
262
- end
263
-
264
- def installVisionOSIfNecessary
265
- # visionOS is unsupported by default on Intel, but we can override this
266
- # https://github.com/actions/runner-images/issues/8144#issuecomment-1902072070
267
- sh 'defaults write com.apple.dt.Xcode AllowUnsupportedVisionOSHost -bool YES'
268
- sh 'defaults write com.apple.CoreSimulator AllowUnsupportedVisionOSHost -bool YES'
269
-
270
- xcodebuild("-downloadPlatform visionOS")
271
- end
259
+ end
@@ -23,9 +23,8 @@ When doing this, follow these steps:
23
23
  3. Change all of the `public` symbols defined in this module to instead be `internal`
24
24
  to prevent Lottie from exposing any EpoxyCore APIs.
25
25
 
26
- 4. Add `@available` annotations as necessary so the library compiles
27
- (Lottie has a lower minimum iOS version than EpoxyCore).
28
-
29
- 5. Namespace any types that conflict with other existing types.
26
+ 4. Namespace any types that conflict with other existing types.
30
27
  For example, the EpoxyCore `Entry` type conflicts with the ZipFoundation `Entry` type,
31
28
  so the EpoxyCore type has been renamed to `EpoxyEntry`.
29
+
30
+ 5. Delete `EpoxySwiftUIHostingController.swift` and `EpoxySwiftUIHostingView.swift`, which are not used by Lottie, and emit deprecation warnings when building for visionOS.
@@ -29,7 +29,6 @@ struct EpoxyIntrinsicContentSizeInvalidator {
29
29
 
30
30
  // MARK: - EnvironmentValues
31
31
 
32
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
33
32
  extension EnvironmentValues {
34
33
  /// A means of invalidating the intrinsic content size of the parent `EpoxySwiftUIHostingView`.
35
34
  var epoxyIntrinsicContentSizeInvalidator: EpoxyIntrinsicContentSizeInvalidator {
@@ -6,7 +6,6 @@ import SwiftUI
6
6
 
7
7
  // MARK: - View
8
8
 
9
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
10
9
  extension View {
11
10
  /// Applies the layout margins from the parent `EpoxySwiftUIHostingView` to this `View`, if there
12
11
  /// are any.
@@ -22,7 +21,6 @@ extension View {
22
21
 
23
22
  // MARK: - EnvironmentValues
24
23
 
25
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
26
24
  extension EnvironmentValues {
27
25
  /// The layout margins of the parent `EpoxySwiftUIHostingView`, else zero if there is none.
28
26
  var epoxyLayoutMargins: EdgeInsets {
@@ -33,7 +31,6 @@ extension EnvironmentValues {
33
31
 
34
32
  // MARK: - EpoxyLayoutMarginsKey
35
33
 
36
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
37
34
  private struct EpoxyLayoutMarginsKey: EnvironmentKey {
38
35
  static let defaultValue = EdgeInsets()
39
36
  }
@@ -42,7 +39,6 @@ private struct EpoxyLayoutMarginsKey: EnvironmentKey {
42
39
 
43
40
  /// A view modifier that applies the layout margins from an enclosing `EpoxySwiftUIHostingView` to
44
41
  /// the modified `View`.
45
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
46
42
  private struct EpoxyLayoutMarginsPadding: ViewModifier {
47
43
  @Environment(\.epoxyLayoutMargins) var epoxyLayoutMargins
48
44
 
@@ -6,7 +6,6 @@ import SwiftUI
6
6
 
7
7
  // MARK: - StyledView
8
8
 
9
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
10
9
  extension StyledView where Self: ContentConfigurableView & BehaviorsConfigurableView {
11
10
  /// Returns a SwiftUI `View` representing this `EpoxyableView`.
12
11
  ///
@@ -52,7 +51,6 @@ extension StyledView where Self: ContentConfigurableView & BehaviorsConfigurable
52
51
  }
53
52
  }
54
53
 
55
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
56
54
  extension StyledView
57
55
  where
58
56
  Self: ContentConfigurableView & BehaviorsConfigurableView,
@@ -96,7 +94,6 @@ extension StyledView
96
94
  }
97
95
  }
98
96
 
99
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
100
97
  extension StyledView
101
98
  where
102
99
  Self: ContentConfigurableView & BehaviorsConfigurableView,
@@ -138,7 +135,6 @@ extension StyledView
138
135
  }
139
136
  }
140
137
 
141
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
142
138
  extension StyledView
143
139
  where
144
140
  Self: ContentConfigurableView & BehaviorsConfigurableView,
@@ -13,7 +13,6 @@ import SwiftUI
13
13
  /// `sizeThatFits(…)` method.
14
14
  ///
15
15
  /// - SeeAlso: ``SwiftUIMeasurementContainer``
16
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
17
16
  protocol MeasuringViewRepresentable: ViewRepresentableType
18
17
  where
19
18
  RepresentableViewType == SwiftUIMeasurementContainer<Content>
@@ -32,7 +31,6 @@ protocol MeasuringViewRepresentable: ViewRepresentableType
32
31
 
33
32
  // MARK: Extensions
34
33
 
35
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
36
34
  extension MeasuringViewRepresentable {
37
35
  /// Returns a copy of this view with its sizing strategy updated to the given `sizing` value.
38
36
  func sizing(_ strategy: SwiftUIMeasurementContainerStrategy) -> Self {
@@ -45,7 +43,6 @@ extension MeasuringViewRepresentable {
45
43
  // MARK: Defaults
46
44
 
47
45
  #if os(iOS) || os(tvOS)
48
- @available(iOS 13.0, tvOS 13.0, *)
49
46
  extension MeasuringViewRepresentable {
50
47
  func _overrideSizeThatFits(
51
48
  _ size: inout CGSize,
@@ -87,7 +84,6 @@ extension MeasuringViewRepresentable {
87
84
  }
88
85
 
89
86
  #elseif os(macOS)
90
- @available(macOS 10.15, *)
91
87
  extension MeasuringViewRepresentable {
92
88
  func _overrideSizeThatFits(
93
89
  _ size: inout CGSize,
@@ -13,7 +13,6 @@ import SwiftUI
13
13
  /// height through the `SwiftUISizingContext` binding.
14
14
  ///
15
15
  /// - SeeAlso: ``MeasuringViewRepresentable``
16
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
17
16
  final class SwiftUIMeasurementContainer<Content: ViewType>: ViewType {
18
17
 
19
18
  // MARK: Lifecycle
@@ -12,7 +12,6 @@ import SwiftUI
12
12
  ///
13
13
  /// Includes an optional generic `Storage` value, which can be used to compare old and new values
14
14
  /// across state changes to prevent redundant view updates.
15
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
16
15
  struct SwiftUIView<Content: ViewType, Storage>: MeasuringViewRepresentable,
17
16
  UIViewConfiguringSwiftUIView
18
17
  {
@@ -51,7 +50,6 @@ struct SwiftUIView<Content: ViewType, Storage>: MeasuringViewRepresentable,
51
50
 
52
51
  // MARK: UIViewRepresentable
53
52
 
54
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
55
53
  extension SwiftUIView {
56
54
  func makeCoordinator() -> Coordinator {
57
55
  Coordinator(storage: storage)
@@ -98,7 +96,6 @@ extension SwiftUIView {
98
96
 
99
97
  // MARK: SwiftUIView.ConfigurationContext
100
98
 
101
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
102
99
  extension SwiftUIView {
103
100
  /// The configuration context that's available to configure the `Content` view whenever the
104
101
  /// `updateUIView()` method is invoked via a configuration closure.
@@ -130,7 +127,6 @@ extension SwiftUIView {
130
127
 
131
128
  // MARK: SwiftUIView.Coordinator
132
129
 
133
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
134
130
  extension SwiftUIView {
135
131
  /// A coordinator that stores the `storage` associated with this view, enabling the old storage
136
132
  /// value to be accessed during the `updateUIView(…)`.
@@ -6,7 +6,6 @@ import SwiftUI
6
6
 
7
7
  // MARK: - ViewTypeProtocol + swiftUIView
8
8
 
9
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
10
9
  extension ViewTypeProtocol {
11
10
  /// Returns a SwiftUI `View` representing this `UIView`, constructed with the given `makeView`
12
11
  /// closure and sized with the given sizing configuration.
@@ -8,7 +8,6 @@ import SwiftUI
8
8
 
9
9
  /// A protocol describing a SwiftUI `View` that can configure its `UIView` content via an array of
10
10
  /// `configuration` closures.
11
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
12
11
  protocol UIViewConfiguringSwiftUIView: View {
13
12
  /// The context available to this configuration, which provides the `UIView` instance at a minimum
14
13
  /// but can include additional context as needed.
@@ -24,7 +23,6 @@ protocol UIViewConfiguringSwiftUIView: View {
24
23
 
25
24
  // MARK: Extensions
26
25
 
27
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
28
26
  extension UIViewConfiguringSwiftUIView {
29
27
  /// Returns a copy of this view updated to have the given closure applied to its represented view
30
28
  /// whenever it is updated via the `updateUIView(…)` method.
@@ -12,14 +12,12 @@ typealias ViewType = UIView
12
12
 
13
13
  /// The platform's SwiftUI view representable type.
14
14
  /// Either `UIViewRepresentable` on iOS/tvOS or `NSViewRepresentable` on macOS.
15
- @available(iOS 13.0, tvOS 13.0, *)
16
15
  typealias ViewRepresentableType = UIViewRepresentable
17
16
 
18
17
  /// The platform's layout constraint priority type.
19
18
  /// Either `UILayoutPriority` on iOS/tvOS or `NSLayoutConstraint.Priority` on macOS.
20
19
  typealias LayoutPriorityType = UILayoutPriority
21
20
 
22
- @available(iOS 13.0, tvOS 13.0, *)
23
21
  extension ViewRepresentableType {
24
22
  /// The platform's view type for `ViewRepresentableType`.
25
23
  /// Either `UIViewType` on iOS/tvOS or `NSViewType` on macOS.
@@ -35,14 +33,12 @@ typealias ViewType = NSView
35
33
 
36
34
  /// The platform's SwiftUI view representable type.
37
35
  /// Either `UIViewRepresentable` on iOS/tvOS, or `NSViewRepresentable` on macOS.
38
- @available(macOS 10.15, *)
39
36
  typealias ViewRepresentableType = NSViewRepresentable
40
37
 
41
38
  /// The platform's layout constraint priority type.
42
39
  /// Either `UILayoutPriority` on iOS/tvOS, or `NSLayoutConstraint.Priority` on macOS.
43
40
  typealias LayoutPriorityType = NSLayoutConstraint.Priority
44
41
 
45
- @available(macOS 10.15, *)
46
42
  extension ViewRepresentableType {
47
43
  /// The platform's view type for `ViewRepresentableType`.
48
44
  /// Either `UIViewType` on iOS/tvOS or `NSViewType` on macOS.
@@ -184,7 +184,6 @@ final class CoreTextRenderLayer: CALayer {
184
184
  private var needsContentUpdate = false
185
185
 
186
186
  // Draws Debug colors for the font alignment.
187
- @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
188
187
  private func drawDebug(_ ctx: CGContext) {
189
188
  if let font {
190
189
  let ascent = CTFontGetAscent(font)
@@ -55,14 +55,14 @@ class DotLottieImageProvider: AnimationImageProvider {
55
55
 
56
56
  private func loadImages() {
57
57
  for url in filepath.urls {
58
- #if os(iOS) || os(tvOS) || os(watchOS) || targetEnvironment(macCatalyst)
58
+ #if canImport(UIKit)
59
59
  if
60
60
  let data = try? Data(contentsOf: url),
61
61
  let image = UIImage(data: data)?.cgImage
62
62
  {
63
63
  images[url.lastPathComponent] = image
64
64
  }
65
- #elseif os(macOS)
65
+ #elseif canImport(AppKit)
66
66
  if
67
67
  let data = try? Data(contentsOf: url),
68
68
  let image = NSImage(data: data)?.lottie_CGImage
@@ -15,10 +15,7 @@ enum DotLottieUtils {
15
15
 
16
16
  /// Temp folder to app directory
17
17
  static var tempDirectoryURL: URL {
18
- if #available(iOS 10.0, macOS 10.12, *) {
19
- return FileManager.default.temporaryDirectory
20
- }
21
- return URL(fileURLWithPath: NSTemporaryDirectory())
18
+ FileManager.default.temporaryDirectory
22
19
  }
23
20
  }
24
21
 
@@ -56,7 +53,8 @@ public enum DotLottieError: Error {
56
53
  case noDataLoaded
57
54
  /// Asset with this name was not found in the provided bundle.
58
55
  case assetNotFound(name: String, bundle: Bundle?)
59
- /// Animation loading from asset is not supported on macOS 10.10.
56
+ /// Animation loading from asset was not supported on macOS 10.10,
57
+ /// but this error is no longer used.
60
58
  case loadingFromAssetNotSupported
61
59
 
62
60
  @available(*, deprecated, message: "Unused")
@@ -1,5 +1,5 @@
1
1
  import Foundation
2
- #if os(iOS) || os(tvOS) || os(watchOS) || targetEnvironment(macCatalyst)
2
+ #if canImport(UIKit)
3
3
  import UIKit
4
4
  #endif
5
5
 
@@ -22,15 +22,12 @@ extension Data {
22
22
  throw DotLottieError.assetNotFound(name: assetName, bundle: bundle)
23
23
  }
24
24
  #else
25
- if #available(macOS 10.11, *) {
26
- if let asset = NSDataAsset(name: assetName, bundle: bundle) {
27
- self = asset.data
28
- return
29
- } else {
30
- throw DotLottieError.assetNotFound(name: assetName, bundle: bundle)
31
- }
25
+ if let asset = NSDataAsset(name: assetName, bundle: bundle) {
26
+ self = asset.data
27
+ return
28
+ } else {
29
+ throw DotLottieError.assetNotFound(name: assetName, bundle: bundle)
32
30
  }
33
- throw DotLottieError.loadingFromAssetNotSupported
34
31
  #endif
35
32
  }
36
33
  }
@@ -272,12 +272,12 @@ extension CGPoint {
272
272
 
273
273
  /// Operator convenience to divide points with /
274
274
  static func / (lhs: CGPoint, rhs: CGFloat) -> CGPoint {
275
- CGPoint(x: lhs.x / CGFloat(rhs), y: lhs.y / CGFloat(rhs))
275
+ CGPoint(x: lhs.x / rhs, y: lhs.y / rhs)
276
276
  }
277
277
 
278
278
  /// Operator convenience to multiply points with *
279
279
  static func * (lhs: CGPoint, rhs: CGFloat) -> CGPoint {
280
- CGPoint(x: lhs.x * CGFloat(rhs), y: lhs.y * CGFloat(rhs))
280
+ CGPoint(x: lhs.x * rhs, y: lhs.y * rhs)
281
281
  }
282
282
 
283
283
  /// Operator convenience to add points with +
@@ -369,7 +369,7 @@ extension CGPoint {
369
369
  while foundPoint == false {
370
370
  refineIterations = refineIterations + 1
371
371
  /// First see if the next point is still less than the projected length.
372
- let nextPoint = points[closestPoint + 1]
372
+ let nextPoint = points[min(closestPoint + 1, points.indices.last!)]
373
373
  if nextPoint.distance < accurateDistance {
374
374
  point = nextPoint
375
375
  closestPoint = closestPoint + 1
@@ -4,7 +4,6 @@
4
4
  #if canImport(SwiftUI)
5
5
  import SwiftUI
6
6
 
7
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
8
7
  extension Binding {
9
8
 
10
9
  /// Helper to transform a `Binding` from one `Value` type to another.
@@ -5,18 +5,31 @@
5
5
  import Combine
6
6
  import SwiftUI
7
7
 
8
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
9
8
  extension View {
10
9
  /// A backwards compatible wrapper for iOS 14 `onChange`
11
10
  @ViewBuilder
12
11
  func valueChanged<T: Equatable>(value: T, onChange: @escaping (T) -> Void) -> some View {
13
- if #available(iOS 14.0, *, macOS 11.0, tvOS 14.0) {
12
+ #if compiler(>=5.9)
13
+ if #available(iOS 17.0, macOS 14.0, tvOS 17.0, visionOS 1.0, *) {
14
+ self.onChange(of: value) { _, newValue in
15
+ onChange(newValue)
16
+ }
17
+ } else if #available(iOS 14.0, macOS 11.0, tvOS 14.0, *) {
18
+ self.onChange(of: value, perform: onChange)
19
+ } else {
20
+ onReceive(Just(value)) { value in
21
+ onChange(value)
22
+ }
23
+ }
24
+ #else
25
+ if #available(iOS 14.0, macOS 11.0, tvOS 14.0, *) {
14
26
  self.onChange(of: value, perform: onChange)
15
27
  } else {
16
28
  onReceive(Just(value)) { value in
17
29
  onChange(value)
18
30
  }
19
31
  }
32
+ #endif
20
33
  }
21
34
  }
22
35
  #endif
@@ -171,7 +171,6 @@ extension LottieAnimation {
171
171
  /// - Parameter url: The url to load the animation from.
172
172
  /// - Parameter animationCache: A cache for holding loaded animations. Defaults to `LottieAnimationCache.shared`. Optional.
173
173
  ///
174
- @available(iOS 13.0, macOS 10.15, tvOS 13.0, *)
175
174
  public static func loadedFrom(
176
175
  url: URL,
177
176
  session: URLSession = .shared,
@@ -1041,14 +1041,6 @@ public class LottieAnimationLayer: CALayer {
1041
1041
  }
1042
1042
  }
1043
1043
 
1044
- func updateRasterizationState() {
1045
- if isAnimationPlaying {
1046
- animationLayer?.shouldRasterize = false
1047
- } else {
1048
- animationLayer?.shouldRasterize = shouldRasterizeWhenIdle
1049
- }
1050
- }
1051
-
1052
1044
  /// Updates the animation frame. Does not affect any current animations
1053
1045
  func updateAnimationFrame(_ newFrame: CGFloat) {
1054
1046
  // In performance tests, we have to wrap the animation layer setup
@@ -1098,6 +1090,14 @@ public class LottieAnimationLayer: CALayer {
1098
1090
  addNewAnimationForContext(newContext)
1099
1091
  }
1100
1092
 
1093
+ func updateRasterizationState() {
1094
+ if isAnimationPlaying {
1095
+ animationLayer?.shouldRasterize = false
1096
+ } else {
1097
+ animationLayer?.shouldRasterize = shouldRasterizeWhenIdle
1098
+ }
1099
+ }
1100
+
1101
1101
  func loadAnimation(_ animationSource: LottieAnimationSource?) {
1102
1102
  switch animationSource {
1103
1103
  case .lottieAnimation(let animation):
@@ -855,7 +855,6 @@ open class LottieAnimationView: LottieAnimationViewBase {
855
855
  var shouldForceUpdates = false
856
856
 
857
857
  if let viewportFrame {
858
- setNeedsLayout()
859
858
  shouldForceUpdates = contentMode == .redraw
860
859
 
861
860
  let compAspect = viewportFrame.size.width / viewportFrame.size.height
@@ -995,11 +994,7 @@ open class LottieAnimationView: LottieAnimationViewBase {
995
994
  }
996
995
 
997
996
  func updateRasterizationState() {
998
- if lottieAnimationLayer.isAnimationPlaying {
999
- lottieAnimationLayer.animationLayer?.shouldRasterize = false
1000
- } else {
1001
- lottieAnimationLayer.animationLayer?.shouldRasterize = lottieAnimationLayer.shouldRasterizeWhenIdle
1002
- }
997
+ lottieAnimationLayer.updateRasterizationState()
1003
998
  }
1004
999
 
1005
1000
  /// Updates the animation frame. Does not affect any current animations
@@ -7,14 +7,13 @@ import SwiftUI
7
7
  // MARK: - LottieView
8
8
 
9
9
  /// A wrapper which exposes Lottie's `LottieAnimationView` to SwiftUI
10
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
11
10
  public struct LottieView<Placeholder: View>: UIViewConfiguringSwiftUIView {
12
11
 
13
12
  // MARK: Lifecycle
14
13
 
15
14
  /// Creates a `LottieView` that displays the given animation
16
15
  public init(animation: LottieAnimation?) where Placeholder == EmptyView {
17
- _animationSource = State(initialValue: animation.map(LottieAnimationSource.lottieAnimation))
16
+ localAnimation = animation.map(LottieAnimationSource.lottieAnimation)
18
17
  placeholder = nil
19
18
  }
20
19
 
@@ -29,7 +28,7 @@ public struct LottieView<Placeholder: View>: UIViewConfiguringSwiftUIView {
29
28
  /// }
30
29
  /// ```
31
30
  public init(dotLottieFile: DotLottieFile?) where Placeholder == EmptyView {
32
- _animationSource = State(initialValue: dotLottieFile.map(LottieAnimationSource.dotLottieFile))
31
+ localAnimation = dotLottieFile.map(LottieAnimationSource.dotLottieFile)
33
32
  placeholder = nil
34
33
  }
35
34
 
@@ -107,9 +106,9 @@ public struct LottieView<Placeholder: View>: UIViewConfiguringSwiftUIView {
107
106
  _ loadAnimation: @escaping () async throws -> LottieAnimationSource?,
108
107
  @ViewBuilder placeholder: @escaping () -> Placeholder)
109
108
  {
109
+ localAnimation = nil
110
110
  self.loadAnimation = loadAnimation
111
111
  self.placeholder = placeholder
112
- _animationSource = State(initialValue: nil)
113
112
  }
114
113
 
115
114
  // MARK: Public
@@ -454,7 +453,8 @@ public struct LottieView<Placeholder: View>: UIViewConfiguringSwiftUIView {
454
453
 
455
454
  // MARK: Private
456
455
 
457
- @State private var animationSource: LottieAnimationSource?
456
+ private let localAnimation: LottieAnimationSource?
457
+ @State private var remoteAnimation: LottieAnimationSource?
458
458
  private var playbackMode: LottiePlaybackMode?
459
459
  private var animationSpeed: Double?
460
460
  private var reloadAnimationTrigger: AnyEquatable?
@@ -474,12 +474,16 @@ public struct LottieView<Placeholder: View>: UIViewConfiguringSwiftUIView {
474
474
  imageProvider: AnimationImageProvider,
475
475
  imageProvidersAreEqual: (AnimationImageProvider, AnimationImageProvider) -> Bool)?
476
476
 
477
+ private var animationSource: LottieAnimationSource? {
478
+ localAnimation ?? remoteAnimation
479
+ }
480
+
477
481
  private func loadAnimationIfNecessary() {
478
482
  guard let loadAnimation else { return }
479
483
 
480
484
  Task {
481
485
  do {
482
- animationSource = try await loadAnimation()
486
+ remoteAnimation = try await loadAnimation()
483
487
  } catch {
484
488
  logger.warn("Failed to load asynchronous Lottie animation with error: \(error)")
485
489
  }
@@ -490,7 +494,7 @@ public struct LottieView<Placeholder: View>: UIViewConfiguringSwiftUIView {
490
494
  guard loadAnimation != nil else { return }
491
495
 
492
496
  if showPlaceholderWhileReloading {
493
- animationSource = nil
497
+ remoteAnimation = nil
494
498
  }
495
499
 
496
500
  loadAnimationIfNecessary()
@@ -564,7 +568,6 @@ public struct LottieView<Placeholder: View>: UIViewConfiguringSwiftUIView {
564
568
  }
565
569
  }
566
570
 
567
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
568
571
  extension View {
569
572
 
570
573
  /// The `.overlay` modifier that uses a `ViewBuilder` is available in iOS 15+, this helper function helps us to use the same API in older OSs
@@ -5,7 +5,6 @@
5
5
  import SwiftUI
6
6
 
7
7
  /// A wrapper which exposes Lottie's `AnimatedButton` to SwiftUI
8
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
9
8
  public struct LottieButton: UIViewConfiguringSwiftUIView {
10
9
 
11
10
  // MARK: Lifecycle
@@ -5,7 +5,6 @@
5
5
  import SwiftUI
6
6
 
7
7
  /// A wrapper which exposes Lottie's `AnimatedSwitch` to SwiftUI
8
- @available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
9
8
  public struct LottieSwitch: UIViewConfiguringSwiftUIView {
10
9
 
11
10
  // MARK: Lifecycle
@@ -44,7 +44,7 @@ public enum LottieNSControlState: UInt, RawRepresentable {
44
44
  /// - `UIControl.Event` on iOS / tvOS and `LottieNSControlEvent` on macOS.
45
45
  public typealias LottieControlEvent = LottieNSControlEvent
46
46
 
47
- public struct LottieNSControlEvent: Equatable {
47
+ public struct LottieNSControlEvent: Equatable, Sendable {
48
48
 
49
49
  // MARK: Lifecycle
50
50