diff --git a/Lottie.xcodeproj/project.pbxproj b/Lottie.xcodeproj/project.pbxproj index bdbcdbc5cf..ecf635e999 100644 --- a/Lottie.xcodeproj/project.pbxproj +++ b/Lottie.xcodeproj/project.pbxproj @@ -3229,6 +3229,7 @@ MARKETING_VERSION = 1.0; MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17"; + OTHER_SWIFT_FLAGS = "-warnings-as-errors"; PRODUCT_BUNDLE_IDENTIFIER = com.airbnb.Lottie; PRODUCT_NAME = Lottie; SKIP_INSTALL = YES; @@ -3262,6 +3263,7 @@ MARKETING_VERSION = 1.0; MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17"; + OTHER_SWIFT_FLAGS = "-warnings-as-errors"; PRODUCT_BUNDLE_IDENTIFIER = com.airbnb.Lottie; PRODUCT_NAME = Lottie; SKIP_INSTALL = YES; @@ -3334,6 +3336,7 @@ MARKETING_VERSION = 1.0; MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17"; + OTHER_SWIFT_FLAGS = "-warnings-as-errors"; PRODUCT_BUNDLE_IDENTIFIER = com.airbnb.Lottie; PRODUCT_NAME = Lottie; SDKROOT = macosx; @@ -3368,6 +3371,7 @@ MARKETING_VERSION = 1.0; MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17"; + OTHER_SWIFT_FLAGS = "-warnings-as-errors"; PRODUCT_BUNDLE_IDENTIFIER = com.airbnb.Lottie; PRODUCT_NAME = Lottie; SDKROOT = macosx; @@ -3400,6 +3404,7 @@ MARKETING_VERSION = 1.0; MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17"; + OTHER_SWIFT_FLAGS = "-warnings-as-errors"; PRODUCT_BUNDLE_IDENTIFIER = com.airbnb.Lottie; PRODUCT_NAME = Lottie; SDKROOT = appletvos; @@ -3434,6 +3439,7 @@ MARKETING_VERSION = 1.0; MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++17"; + OTHER_SWIFT_FLAGS = "-warnings-as-errors"; PRODUCT_BUNDLE_IDENTIFIER = com.airbnb.Lottie; PRODUCT_NAME = Lottie; SDKROOT = appletvos; diff --git a/Sources/Private/Model/Assets/Asset.swift b/Sources/Private/Model/Assets/Asset.swift index d610b1ce55..9fcfcb6a41 100644 --- a/Sources/Private/Model/Assets/Asset.swift +++ b/Sources/Private/Model/Assets/Asset.swift @@ -7,6 +7,8 @@ import Foundation +// MARK: - Asset + public class Asset: Codable, DictionaryInitializable { // MARK: Lifecycle @@ -41,3 +43,9 @@ public class Asset: Codable, DictionaryInitializable { case id } } + +// MARK: Sendable + +/// Since `Asset` isn't `final`, we have to use `@unchecked Sendable` instead of `Sendable.` +/// All `Asset` subclasses are immutable `Sendable` values. +extension Asset: @unchecked Sendable { } diff --git a/Sources/Private/Model/Assets/AssetLibrary.swift b/Sources/Private/Model/Assets/AssetLibrary.swift index ba44c3bc44..bc9d24ac65 100644 --- a/Sources/Private/Model/Assets/AssetLibrary.swift +++ b/Sources/Private/Model/Assets/AssetLibrary.swift @@ -7,7 +7,7 @@ import Foundation -final class AssetLibrary: Codable, AnyInitializable { +final class AssetLibrary: Codable, AnyInitializable, Sendable { // MARK: Lifecycle diff --git a/Sources/Private/Model/Assets/ImageAsset.swift b/Sources/Private/Model/Assets/ImageAsset.swift index 52c62ab6d9..c68bbdb15d 100644 --- a/Sources/Private/Model/Assets/ImageAsset.swift +++ b/Sources/Private/Model/Assets/ImageAsset.swift @@ -9,7 +9,7 @@ import Foundation // MARK: - ImageAsset -public final class ImageAsset: Asset { +public final class ImageAsset: Asset, Sendable { // MARK: Lifecycle diff --git a/Sources/Private/Model/Assets/PrecompAsset.swift b/Sources/Private/Model/Assets/PrecompAsset.swift index e26ee7af54..72037617e9 100644 --- a/Sources/Private/Model/Assets/PrecompAsset.swift +++ b/Sources/Private/Model/Assets/PrecompAsset.swift @@ -7,7 +7,7 @@ import Foundation -final class PrecompAsset: Asset { +final class PrecompAsset: Asset, Sendable { // MARK: Lifecycle diff --git a/Sources/Private/Model/Keyframes/KeyframeGroup.swift b/Sources/Private/Model/Keyframes/KeyframeGroup.swift index 8fca5380f6..a19b6bc8d9 100644 --- a/Sources/Private/Model/Keyframes/KeyframeGroup.swift +++ b/Sources/Private/Model/Keyframes/KeyframeGroup.swift @@ -203,6 +203,10 @@ extension KeyframeGroup: Hashable where T: Hashable { } } +// MARK: Sendable + +extension KeyframeGroup: Sendable where T: Sendable { } + extension Keyframe { /// Creates a copy of this `Keyframe` with the same timing data, but a different value func withValue(_ newValue: Value) -> Keyframe { diff --git a/Sources/Private/Model/Layers/ImageLayerModel.swift b/Sources/Private/Model/Layers/ImageLayerModel.swift index 91ea324799..c29534e1f7 100644 --- a/Sources/Private/Model/Layers/ImageLayerModel.swift +++ b/Sources/Private/Model/Layers/ImageLayerModel.swift @@ -8,7 +8,7 @@ import Foundation /// A layer that holds an image. -final class ImageLayerModel: LayerModel { +final class ImageLayerModel: LayerModel, Sendable { // MARK: Lifecycle diff --git a/Sources/Private/Model/Layers/LayerModel.swift b/Sources/Private/Model/Layers/LayerModel.swift index 5fc3807f61..43c629cb13 100644 --- a/Sources/Private/Model/Layers/LayerModel.swift +++ b/Sources/Private/Model/Layers/LayerModel.swift @@ -226,3 +226,9 @@ extension Array where Element == LayerModel { } } } + +// MARK: - LayerModel + Sendable + +/// Since `LayerModel` isn't `final`, we have to use `@unchecked Sendable` instead of `Sendable.` +/// All `LayerModel` subclasses are immutable `Sendable` values. +extension LayerModel: @unchecked Sendable { } diff --git a/Sources/Private/Model/Layers/PreCompLayerModel.swift b/Sources/Private/Model/Layers/PreCompLayerModel.swift index e1cb11c64f..b394c50143 100644 --- a/Sources/Private/Model/Layers/PreCompLayerModel.swift +++ b/Sources/Private/Model/Layers/PreCompLayerModel.swift @@ -8,7 +8,7 @@ import Foundation /// A layer that holds another animation composition. -final class PreCompLayerModel: LayerModel { +final class PreCompLayerModel: LayerModel, Sendable { // MARK: Lifecycle diff --git a/Sources/Private/Model/Layers/ShapeLayerModel.swift b/Sources/Private/Model/Layers/ShapeLayerModel.swift index b9562ad420..74cfae91d3 100644 --- a/Sources/Private/Model/Layers/ShapeLayerModel.swift +++ b/Sources/Private/Model/Layers/ShapeLayerModel.swift @@ -8,7 +8,7 @@ import Foundation /// A layer that holds vector shape objects. -final class ShapeLayerModel: LayerModel { +final class ShapeLayerModel: LayerModel, Sendable { // MARK: Lifecycle diff --git a/Sources/Private/Model/Layers/SolidLayerModel.swift b/Sources/Private/Model/Layers/SolidLayerModel.swift index 9ad232a238..ded8b94a04 100644 --- a/Sources/Private/Model/Layers/SolidLayerModel.swift +++ b/Sources/Private/Model/Layers/SolidLayerModel.swift @@ -8,7 +8,7 @@ import Foundation /// A layer that holds a solid color. -final class SolidLayerModel: LayerModel { +final class SolidLayerModel: LayerModel, Sendable { // MARK: Lifecycle diff --git a/Sources/Private/Model/Layers/TextLayerModel.swift b/Sources/Private/Model/Layers/TextLayerModel.swift index 0dc6f0e09f..65ab4010c1 100644 --- a/Sources/Private/Model/Layers/TextLayerModel.swift +++ b/Sources/Private/Model/Layers/TextLayerModel.swift @@ -8,7 +8,7 @@ import Foundation /// A layer that holds text. -final class TextLayerModel: LayerModel { +final class TextLayerModel: LayerModel, Sendable { // MARK: Lifecycle diff --git a/Sources/Private/Model/Objects/Marker.swift b/Sources/Private/Model/Objects/Marker.swift index d981a2cd0c..f689f9e58c 100644 --- a/Sources/Private/Model/Objects/Marker.swift +++ b/Sources/Private/Model/Objects/Marker.swift @@ -8,7 +8,7 @@ import Foundation /// A time marker -final class Marker: Codable, DictionaryInitializable { +final class Marker: Codable, Sendable, DictionaryInitializable { // MARK: Lifecycle diff --git a/Sources/Private/Model/ShapeItems/Ellipse.swift b/Sources/Private/Model/ShapeItems/Ellipse.swift index df8528605b..15b1146bd0 100644 --- a/Sources/Private/Model/ShapeItems/Ellipse.swift +++ b/Sources/Private/Model/ShapeItems/Ellipse.swift @@ -17,7 +17,7 @@ enum PathDirection: Int, Codable { // MARK: - Ellipse -final class Ellipse: ShapeItem { +final class Ellipse: ShapeItem, Sendable { // MARK: Lifecycle diff --git a/Sources/Private/Model/ShapeItems/Fill.swift b/Sources/Private/Model/ShapeItems/Fill.swift index f22dcfdfb4..621f64a785 100644 --- a/Sources/Private/Model/ShapeItems/Fill.swift +++ b/Sources/Private/Model/ShapeItems/Fill.swift @@ -17,7 +17,7 @@ enum FillRule: Int, Codable { // MARK: - Fill -final class Fill: ShapeItem { +final class Fill: ShapeItem, Sendable { // MARK: Lifecycle diff --git a/Sources/Private/Model/ShapeItems/GradientFill.swift b/Sources/Private/Model/ShapeItems/GradientFill.swift index 71d185655c..5b68bd6b6f 100644 --- a/Sources/Private/Model/ShapeItems/GradientFill.swift +++ b/Sources/Private/Model/ShapeItems/GradientFill.swift @@ -9,7 +9,7 @@ import Foundation // MARK: - GradientType -enum GradientType: Int, Codable { +enum GradientType: Int, Codable, Sendable { case none case linear case radial @@ -17,7 +17,7 @@ enum GradientType: Int, Codable { // MARK: - GradientFill -final class GradientFill: ShapeItem { +final class GradientFill: ShapeItem, Sendable { // MARK: Lifecycle diff --git a/Sources/Private/Model/ShapeItems/GradientStroke.swift b/Sources/Private/Model/ShapeItems/GradientStroke.swift index f29b1c6a08..ad208e0dd8 100644 --- a/Sources/Private/Model/ShapeItems/GradientStroke.swift +++ b/Sources/Private/Model/ShapeItems/GradientStroke.swift @@ -9,7 +9,7 @@ import Foundation // MARK: - LineCap -enum LineCap: Int, Codable { +enum LineCap: Int, Codable, Sendable { case none case butt case round @@ -18,7 +18,7 @@ enum LineCap: Int, Codable { // MARK: - LineJoin -enum LineJoin: Int, Codable { +enum LineJoin: Int, Codable, Sendable { case none case miter case round @@ -27,7 +27,7 @@ enum LineJoin: Int, Codable { // MARK: - GradientStroke -final class GradientStroke: ShapeItem { +final class GradientStroke: ShapeItem, Sendable { // MARK: Lifecycle diff --git a/Sources/Private/Model/ShapeItems/Group.swift b/Sources/Private/Model/ShapeItems/Group.swift index e95210906e..3eecd410e5 100644 --- a/Sources/Private/Model/ShapeItems/Group.swift +++ b/Sources/Private/Model/ShapeItems/Group.swift @@ -8,7 +8,7 @@ import Foundation /// An item that define a a group of shape items -final class Group: ShapeItem { +final class Group: ShapeItem, Sendable { // MARK: Lifecycle diff --git a/Sources/Private/Model/ShapeItems/Merge.swift b/Sources/Private/Model/ShapeItems/Merge.swift index 3b35e8b1c9..8fc5f761d0 100644 --- a/Sources/Private/Model/ShapeItems/Merge.swift +++ b/Sources/Private/Model/ShapeItems/Merge.swift @@ -9,7 +9,7 @@ import Foundation // MARK: - MergeMode -enum MergeMode: Int, Codable { +enum MergeMode: Int, Codable, Sendable { case none case merge case add @@ -20,7 +20,7 @@ enum MergeMode: Int, Codable { // MARK: - Merge -final class Merge: ShapeItem { +final class Merge: ShapeItem, Sendable { // MARK: Lifecycle diff --git a/Sources/Private/Model/ShapeItems/Rectangle.swift b/Sources/Private/Model/ShapeItems/Rectangle.swift index e268334a73..0940d99e24 100644 --- a/Sources/Private/Model/ShapeItems/Rectangle.swift +++ b/Sources/Private/Model/ShapeItems/Rectangle.swift @@ -7,7 +7,7 @@ import Foundation -final class Rectangle: ShapeItem { +final class Rectangle: ShapeItem, Sendable { // MARK: Lifecycle diff --git a/Sources/Private/Model/ShapeItems/Repeater.swift b/Sources/Private/Model/ShapeItems/Repeater.swift index 0980ebdd57..2280aecc1f 100644 --- a/Sources/Private/Model/ShapeItems/Repeater.swift +++ b/Sources/Private/Model/ShapeItems/Repeater.swift @@ -7,7 +7,7 @@ import Foundation -final class Repeater: ShapeItem { +final class Repeater: ShapeItem, Sendable { // MARK: Lifecycle diff --git a/Sources/Private/Model/ShapeItems/RoundedCorners.swift b/Sources/Private/Model/ShapeItems/RoundedCorners.swift index e2c1b68eb4..6572ba2cf4 100644 --- a/Sources/Private/Model/ShapeItems/RoundedCorners.swift +++ b/Sources/Private/Model/ShapeItems/RoundedCorners.swift @@ -9,7 +9,7 @@ import Foundation // MARK: - RoundedCorners -final class RoundedCorners: ShapeItem { +final class RoundedCorners: ShapeItem, Sendable { // MARK: Lifecycle diff --git a/Sources/Private/Model/ShapeItems/Shape.swift b/Sources/Private/Model/ShapeItems/Shape.swift index c1eeb66e68..fea42d0e63 100644 --- a/Sources/Private/Model/ShapeItems/Shape.swift +++ b/Sources/Private/Model/ShapeItems/Shape.swift @@ -8,7 +8,7 @@ import Foundation /// An item that defines an custom shape -final class Shape: ShapeItem { +final class Shape: ShapeItem, Sendable { // MARK: Lifecycle diff --git a/Sources/Private/Model/ShapeItems/ShapeItem.swift b/Sources/Private/Model/ShapeItems/ShapeItem.swift index a22f50ba3f..0738c93234 100644 --- a/Sources/Private/Model/ShapeItems/ShapeItem.swift +++ b/Sources/Private/Model/ShapeItems/ShapeItem.swift @@ -52,7 +52,7 @@ extension ShapeType: ClassFamily { // MARK: - ShapeType -enum ShapeType: String, Codable { +enum ShapeType: String, Codable, Sendable { case ellipse = "el" case fill = "fl" case gradientFill = "gf" @@ -165,3 +165,9 @@ extension Array where Element == ShapeItem { } } } + +// MARK: - ShapeItem + Sendable + +/// Since `ShapeItem` isn't `final`, we have to use `@unchecked Sendable` instead of `Sendable.` +/// All `ShapeItem` subclasses are immutable `Sendable` values. +extension ShapeItem: @unchecked Sendable { } diff --git a/Sources/Private/Model/ShapeItems/ShapeTransform.swift b/Sources/Private/Model/ShapeItems/ShapeTransform.swift index 797b761537..2ac62353f2 100644 --- a/Sources/Private/Model/ShapeItems/ShapeTransform.swift +++ b/Sources/Private/Model/ShapeItems/ShapeTransform.swift @@ -7,7 +7,7 @@ import Foundation -final class ShapeTransform: ShapeItem { +final class ShapeTransform: ShapeItem, Sendable { // MARK: Lifecycle diff --git a/Sources/Private/Model/ShapeItems/Star.swift b/Sources/Private/Model/ShapeItems/Star.swift index e13e47a0d6..aa902df511 100644 --- a/Sources/Private/Model/ShapeItems/Star.swift +++ b/Sources/Private/Model/ShapeItems/Star.swift @@ -9,7 +9,7 @@ import Foundation // MARK: - StarType -enum StarType: Int, Codable { +enum StarType: Int, Codable, Sendable { case none case star case polygon @@ -17,7 +17,7 @@ enum StarType: Int, Codable { // MARK: - Star -final class Star: ShapeItem { +final class Star: ShapeItem, Sendable { // MARK: Lifecycle diff --git a/Sources/Private/Model/ShapeItems/Stroke.swift b/Sources/Private/Model/ShapeItems/Stroke.swift index 87a1728e68..c224fd4c64 100644 --- a/Sources/Private/Model/ShapeItems/Stroke.swift +++ b/Sources/Private/Model/ShapeItems/Stroke.swift @@ -7,7 +7,7 @@ import Foundation -final class Stroke: ShapeItem { +final class Stroke: ShapeItem, Sendable { // MARK: Lifecycle diff --git a/Sources/Private/Model/ShapeItems/Trim.swift b/Sources/Private/Model/ShapeItems/Trim.swift index aaa6ce4f4e..e3e0360f9c 100644 --- a/Sources/Private/Model/ShapeItems/Trim.swift +++ b/Sources/Private/Model/ShapeItems/Trim.swift @@ -16,7 +16,7 @@ enum TrimType: Int, Codable { // MARK: - Trim -final class Trim: ShapeItem { +final class Trim: ShapeItem, Sendable { // MARK: Lifecycle diff --git a/Sources/Private/Model/Text/Font.swift b/Sources/Private/Model/Text/Font.swift index c1c9869252..5e60c7d06d 100644 --- a/Sources/Private/Model/Text/Font.swift +++ b/Sources/Private/Model/Text/Font.swift @@ -9,7 +9,7 @@ import Foundation // MARK: - Font -final class Font: Codable, DictionaryInitializable { +final class Font: Codable, Sendable, DictionaryInitializable { // MARK: Lifecycle @@ -41,7 +41,7 @@ final class Font: Codable, DictionaryInitializable { // MARK: - FontList /// A list of fonts -final class FontList: Codable, DictionaryInitializable { +final class FontList: Codable, Sendable, DictionaryInitializable { // MARK: Lifecycle diff --git a/Sources/Private/Model/Text/Glyph.swift b/Sources/Private/Model/Text/Glyph.swift index 03a7c58e55..b11a0148ec 100644 --- a/Sources/Private/Model/Text/Glyph.swift +++ b/Sources/Private/Model/Text/Glyph.swift @@ -8,7 +8,7 @@ import Foundation /// A model that holds a vector character -final class Glyph: Codable, DictionaryInitializable { +final class Glyph: Codable, Sendable, DictionaryInitializable { // MARK: Lifecycle diff --git a/Sources/Private/Utility/Primitives/VectorsExtensions.swift b/Sources/Private/Utility/Primitives/VectorsExtensions.swift index 118b4ee758..0fb7423be9 100644 --- a/Sources/Private/Utility/Primitives/VectorsExtensions.swift +++ b/Sources/Private/Utility/Primitives/VectorsExtensions.swift @@ -69,7 +69,7 @@ extension Double { // MARK: - LottieVector2D /// Needed for decoding json {x: y:} to a CGPoint -public struct LottieVector2D: Codable, Hashable { +public struct LottieVector2D: Codable, Hashable, Sendable { // MARK: Lifecycle diff --git a/Sources/Public/Animation/LottieAnimation.swift b/Sources/Public/Animation/LottieAnimation.swift index 184d510bc8..bca001c912 100644 --- a/Sources/Public/Animation/LottieAnimation.swift +++ b/Sources/Public/Animation/LottieAnimation.swift @@ -9,7 +9,7 @@ import Foundation // MARK: - CoordinateSpace -public enum CoordinateSpace: Int, Codable { +public enum CoordinateSpace: Int, Codable, Sendable { case type2d case type3d } @@ -20,7 +20,7 @@ public enum CoordinateSpace: Int, Codable { /// /// A `LottieAnimation` holds all of the animation data backing a Lottie Animation. /// Codable, see JSON schema [here](https://github.com/airbnb/lottie-web/tree/master/docs/json). -public final class LottieAnimation: Codable, DictionaryInitializable { +public final class LottieAnimation: Codable, Sendable, DictionaryInitializable { // MARK: Lifecycle @@ -164,7 +164,7 @@ public final class LottieAnimation: Codable, DictionaryInitializable { /// - reducedMotion /// - reduced_motion /// - reduced-motion - lazy private(set) var reducedMotionMarker: Marker? = { + var reducedMotionMarker: Marker? { let allowedReducedMotionMarkerNames = Set([ "reduced motion", "reduced_motion", @@ -175,9 +175,5 @@ public final class LottieAnimation: Codable, DictionaryInitializable { return markers?.first(where: { marker in allowedReducedMotionMarkerNames.contains(marker.name.lowercased()) }) - }() + } } - -// MARK: Sendable - -extension LottieAnimation: @unchecked Sendable { } diff --git a/Sources/Public/AnimationCache/DefaultAnimationCache.swift b/Sources/Public/AnimationCache/DefaultAnimationCache.swift index 1fb9899ae9..3504a3fa6d 100644 --- a/Sources/Public/AnimationCache/DefaultAnimationCache.swift +++ b/Sources/Public/AnimationCache/DefaultAnimationCache.swift @@ -49,5 +49,5 @@ public class DefaultAnimationCache: AnimationCacheProvider, @unchecked Sendable private static let defaultCacheCountLimit = 100 - private var cache = NSCache() + private let cache = NSCache() } diff --git a/Sources/Public/DotLottie/DotLottieFile.swift b/Sources/Public/DotLottie/DotLottieFile.swift index 058f4572ed..3e121218a9 100644 --- a/Sources/Public/DotLottie/DotLottieFile.swift +++ b/Sources/Public/DotLottie/DotLottieFile.swift @@ -147,4 +147,7 @@ extension String { // MARK: - DotLottieFile + Sendable +// Mark `DotLottieFile` as `@unchecked Sendable` to allow it to be used when strict concurrency is enabled. +// In the future, it may be necessary to make changes to the internal implementation of `DotLottieFile` +// to make it truly thread-safe. extension DotLottieFile: @unchecked Sendable { } diff --git a/Sources/Public/Keyframes/Keyframe.swift b/Sources/Public/Keyframes/Keyframe.swift index 4e63a576a1..85d6da3a95 100644 --- a/Sources/Public/Keyframes/Keyframe.swift +++ b/Sources/Public/Keyframes/Keyframe.swift @@ -90,3 +90,7 @@ extension Keyframe: Hashable where T: Hashable { hasher.combine(spatialOutTangent) } } + +// MARK: Sendable + +extension Keyframe: Sendable where T: Sendable { } diff --git a/Sources/Public/Primitives/Vectors.swift b/Sources/Public/Primitives/Vectors.swift index 1029ccad62..61fca480bd 100644 --- a/Sources/Public/Primitives/Vectors.swift +++ b/Sources/Public/Primitives/Vectors.swift @@ -9,7 +9,7 @@ import Foundation // MARK: - LottieVector1D -public struct LottieVector1D: Hashable { +public struct LottieVector1D: Hashable, Sendable { public init(_ value: Double) { self.value = value @@ -23,7 +23,7 @@ public struct LottieVector1D: Hashable { /// A three dimensional vector. /// These vectors are encoded and decoded from [Double] -public struct LottieVector3D: Hashable { +public struct LottieVector3D: Hashable, Sendable { public let x: Double public let y: Double