Repository: airbnb/lottie-ios
File: lottie-swift/src/Private/Model/Animation.swift (Swift)

Code before:
  public let framerate: Double
  
  /// The height of the composition in points.
  let width: Int
  
  /// The width of the composition in points.
  let height: Int
  
  /// The list of animation layers
  let layers: [LayerModel]
  
  /// The list of glyphs used for text rendering
  let glyphs: [Glyph]?
  
  /// The list of fonts used for text rendering
  let fonts: FontList?
  
  /// Asset Library
  let assetLibrary: AssetLibrary?
  
  /// Markers
  let markers: [Marker]?
  let markerMap: [String : Marker]?
  
  /// Return all marker names, in order, or an empty list if none are specified
  public var markerNames: [String]
  {
    guard let markers = markers else { return [] }
    return markers.map{$0.name}
  }
  
  enum CodingKeys : String, CodingKey {
    case version = "v"
    case type = "ddd"
    case startFrame = "ip"
    case endFrame = "op"
    case framerate = "fr"
    case width = "w"
    case height = "h"
    case layers = "layers"
    case glyphs = "chars"
    case fonts = "fonts"
    case assetLibrary = "assets"
    case markers = "markers"
  }
  
  required public init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: Animation.CodingKeys.self)
    self.version = try container.decode(String.self, forKey: .version)
    self.type = try container.decodeIfPresent(CoordinateSpace.self, forKey: .type) ?? .type2d
    self.startFrame = try container.decode(AnimationFrameTime.self, forKey: .startFrame)

Review comment (suggestion):
```suggestion
  public var markerNames: [String] {
```

Code after:
  public let framerate: Double
  
  /// The height of the composition in points.
  let width: Int
  
  /// The width of the composition in points.
  let height: Int
  
  /// The list of animation layers
  let layers: [LayerModel]
  
  /// The list of glyphs used for text rendering
  let glyphs: [Glyph]?
  
  /// The list of fonts used for text rendering
  let fonts: FontList?
  
  /// Asset Library
  let assetLibrary: AssetLibrary?
  
  /// Markers
  let markers: [Marker]?
  let markerMap: [String : Marker]?
  
  /// Return all marker names, in order, or an empty list if none are specified
  public var markerNames: [String] {
    guard let markers = markers else { return [] }
    return markers.map { $0.name }
  }
  
  enum CodingKeys : String, CodingKey {
    case version = "v"
    case type = "ddd"
    case startFrame = "ip"
    case endFrame = "op"
    case framerate = "fr"
    case width = "w"
    case height = "h"
    case layers = "layers"
    case glyphs = "chars"
    case fonts = "fonts"
    case assetLibrary = "assets"
    case markers = "markers"
  }
  
  required public init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: Animation.CodingKeys.self)
    self.version = try container.decode(String.self, forKey: .version)
    self.type = try container.decodeIfPresent(CoordinateSpace.self, forKey: .type) ?? .type2d
    self.startFrame = try container.decode(AnimationFrameTime.self, forKey: .startFrame)
    self.endFrame = try container.decode(AnimationFrameTime.self, forKey: .endFrame)