-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix parsing issue, add support for DotLottieConfiguration in SwiftUI LottieView #2277
Changes from all commits
6445e5f
0a5b6f8
470cf26
f90b2c6
0f5342b
94dd969
19f8cdf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,14 +18,17 @@ final class AssetLibrary: Codable, AnyInitializable, Sendable { | |
var imageAssets = [String : ImageAsset]() | ||
var precompAssets = [String : PrecompAsset]() | ||
|
||
while !container.isAtEnd { | ||
let keyContainer = try containerForKeys.nestedContainer(keyedBy: PrecompAsset.CodingKeys.self) | ||
if keyContainer.contains(.layers) { | ||
let precompAsset = try container.decode(PrecompAsset.self) | ||
while | ||
!container.isAtEnd, | ||
let keyContainer = try? containerForKeys.nestedContainer(keyedBy: PrecompAsset.CodingKeys.self) | ||
{ | ||
if | ||
keyContainer.contains(.layers), | ||
let precompAsset = try? container.decode(PrecompAsset.self) | ||
{ | ||
decodedAssets[precompAsset.id] = precompAsset | ||
precompAssets[precompAsset.id] = precompAsset | ||
} else { | ||
let imageAsset = try container.decode(ImageAsset.self) | ||
} else if let imageAsset = try? container.decode(ImageAsset.self) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If an image asset fails to parse for some reason, we can recover gracefully instead of throwing an error and rejecting the animation |
||
decodedAssets[imageAsset.id] = imageAsset | ||
imageAssets[imageAsset.id] = imageAsset | ||
} | ||
|
@@ -37,7 +40,7 @@ final class AssetLibrary: Codable, AnyInitializable, Sendable { | |
|
||
init(value: Any) throws { | ||
guard let dictionaries = value as? [[String: Any]] else { | ||
throw InitializableError.invalidInput | ||
throw InitializableError.invalidInput() | ||
} | ||
var decodedAssets = [String : Asset]() | ||
var imageAssets = [String : ImageAsset]() | ||
|
@@ -47,8 +50,7 @@ final class AssetLibrary: Codable, AnyInitializable, Sendable { | |
let asset = try PrecompAsset(dictionary: dictionary) | ||
decodedAssets[asset.id] = asset | ||
precompAssets[asset.id] = asset | ||
} else { | ||
let asset = try ImageAsset(dictionary: dictionary) | ||
} else if let asset = try? ImageAsset(dictionary: dictionary) { | ||
decodedAssets[asset.id] = asset | ||
imageAssets[asset.id] = asset | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,7 @@ | |
// MARK: - InitializableError | ||
|
||
enum InitializableError: Error { | ||
case invalidInput | ||
case invalidInput(file: StaticString = #file, line: UInt = #line) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding in file and line context makes it easier to debug where these errors are coming from |
||
} | ||
|
||
// MARK: - DictionaryInitializable | ||
|
@@ -30,14 +30,24 @@ protocol AnyInitializable { | |
extension Dictionary { | ||
|
||
@_disfavoredOverload | ||
func value<T, KeyType: RawRepresentable>(for key: KeyType) throws -> T where KeyType.RawValue == Key { | ||
func value<T, KeyType: RawRepresentable>( | ||
for key: KeyType, | ||
file: StaticString = #file, | ||
line: UInt = #line) | ||
throws -> T where KeyType.RawValue == Key | ||
{ | ||
guard let value = self[key.rawValue] as? T else { | ||
throw InitializableError.invalidInput | ||
throw InitializableError.invalidInput(file: file, line: line) | ||
} | ||
return value | ||
} | ||
|
||
func value<T: AnyInitializable, KeyType: RawRepresentable>(for key: KeyType) throws -> T where KeyType.RawValue == Key { | ||
func value<T: AnyInitializable, KeyType: RawRepresentable>( | ||
for key: KeyType, | ||
file: StaticString = #file, | ||
line: UInt = #line) | ||
throws -> T where KeyType.RawValue == Key | ||
{ | ||
if let value = self[key.rawValue] as? T { | ||
return value | ||
} | ||
|
@@ -46,7 +56,7 @@ extension Dictionary { | |
return try T(value: value) | ||
} | ||
|
||
throw InitializableError.invalidInput | ||
throw InitializableError.invalidInput(file: file, line: line) | ||
} | ||
|
||
} | ||
|
@@ -57,7 +67,7 @@ extension [Double]: AnyInitializable { | |
|
||
init(value: Any) throws { | ||
guard let array = value as? [Double] else { | ||
throw InitializableError.invalidInput | ||
throw InitializableError.invalidInput() | ||
} | ||
self = array | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -93,7 +93,7 @@ class LayerModel: Codable, DictionaryInitializable { | |
inFrame = try container.decode(Double.self, forKey: .inFrame) | ||
outFrame = try container.decode(Double.self, forKey: .outFrame) | ||
startTime = try container.decode(Double.self, forKey: .startTime) | ||
transform = try container.decode(Transform.self, forKey: .transform) | ||
transform = try container.decodeIfPresent(Transform.self, forKey: .transform) ?? .default | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All of the individual properties in a |
||
parent = try container.decodeIfPresent(Int.self, forKey: .parent) | ||
blendMode = try container.decodeIfPresent(BlendMode.self, forKey: .blendMode) ?? .normal | ||
masks = try container.decodeIfPresent([Mask].self, forKey: .masks) | ||
|
@@ -119,8 +119,15 @@ class LayerModel: Codable, DictionaryInitializable { | |
inFrame = try dictionary.value(for: CodingKeys.inFrame) | ||
outFrame = try dictionary.value(for: CodingKeys.outFrame) | ||
startTime = try dictionary.value(for: CodingKeys.startTime) | ||
transform = try Transform(dictionary: try dictionary.value(for: CodingKeys.transform)) | ||
parent = try? dictionary.value(for: CodingKeys.parent) | ||
if | ||
let transformDictionary: [String: Any] = try dictionary.value(for: CodingKeys.transform), | ||
let transform = try? Transform(dictionary: transformDictionary) | ||
{ | ||
self.transform = transform | ||
} else { | ||
transform = .default | ||
} | ||
if | ||
let blendModeRawValue = dictionary[CodingKeys.blendMode.rawValue] as? Int, | ||
let blendMode = BlendMode(rawValue: blendModeRawValue) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,8 +20,18 @@ extension LottieAnimationSource { | |
switch self { | ||
case .lottieAnimation(let animation): | ||
return animation | ||
case .dotLottieFile: | ||
return dotLottieAnimation?.animation | ||
} | ||
} | ||
|
||
/// The `DotLottieFile.Animation`, if this is a dotLottie animation | ||
var dotLottieAnimation: DotLottieFile.Animation? { | ||
switch self { | ||
case .lottieAnimation: | ||
return nil | ||
case .dotLottieFile(let dotLottieFile): | ||
return dotLottieFile.animation()?.animation | ||
return dotLottieFile.animation() | ||
Comment on lines
-24
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
} | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add resilient decoder https://github.com/airbnb/ResilientDecoding in case we need the error at another time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't use the
Codable
decoding implementation by default (the dictionary-based implementation is the default in Lottie 4.0+ since it's a lot faster), so no need to invest much in theCodable
implementation