Repository: airbnb/lottie-ios
File: Sources/Private/CoreAnimation/Layers/BaseCompositionLayer.swift (Swift)

Code before:
    baseLayerModel = typedLayer.baseLayerModel
    super.init(layer: typedLayer)
  }

  // MARK: Internal

  /// The layer that content / sublayers should be rendered in.
  /// This is the layer that transform animations are applied to.
  let contentsLayer = BaseAnimationLayer()

  /// Whether or not this layer render should render any visible content
  var renderLayerContents: Bool { true }

  /// Sets up the base `LayerModel` animations for this layer,
  /// and all child `AnimationLayer`s.
  ///  - Can be overridden by subclasses, which much call `super`.
  override func setupAnimations(context: LayerAnimationContext) throws {
    var context = context
    if renderLayerContents {
      context = context.addingKeypathComponent(baseLayerModel.name)
    }

    try setupLayerAnimations(context: context)
    try setupChildAnimations(context: context)
  }

  func setupLayerAnimations(context: LayerAnimationContext) throws {
    let context = context.addingKeypathComponent(baseLayerModel.name)

    try contentsLayer.addTransformAnimations(for: baseLayerModel.transform, context: context)

    if renderLayerContents {
      try contentsLayer.addOpacityAnimation(for: baseLayerModel.transform, context: context)

      contentsLayer.addVisibilityAnimation(
        inFrame: CGFloat(baseLayerModel.inFrame),
        outFrame: CGFloat(baseLayerModel.outFrame),
        context: context)
    }
  }

  func setupChildAnimations(context: LayerAnimationContext) throws {
    try super.setupAnimations(context: context)
  }

  override func addSublayer(_ layer: CALayer) {
    if layer === contentsLayer {
      super.addSublayer(contentsLayer)
    } else {
      contentsLayer.addSublayer(layer)
    }

Review comment (bug):
Fixed an issue where we were:
 1. incorrectly appending the layer name twice in the path
 2. missing "Transform" from the path

For example, `"H1.Transform.Scale"` was incorrectly using `"H1.H1.Scale"` previously.

Code after:
    baseLayerModel = typedLayer.baseLayerModel
    super.init(layer: typedLayer)
  }

  // MARK: Internal

  /// The layer that content / sublayers should be rendered in.
  /// This is the layer that transform animations are applied to.
  let contentsLayer = BaseAnimationLayer()

  /// Whether or not this layer render should render any visible content
  var renderLayerContents: Bool { true }

  /// Sets up the base `LayerModel` animations for this layer,
  /// and all child `AnimationLayer`s.
  ///  - Can be overridden by subclasses, which much call `super`.
  override func setupAnimations(context: LayerAnimationContext) throws {
    let layerContext = context.addingKeypathComponent(baseLayerModel.name)
    let childContext = renderLayerContents ? layerContext : context

    try setupLayerAnimations(context: layerContext)
    try setupChildAnimations(context: childContext)
  }

  func setupLayerAnimations(context: LayerAnimationContext) throws {
    let transformContext = context.addingKeypathComponent("Transform")

    try contentsLayer.addTransformAnimations(for: baseLayerModel.transform, context: transformContext)

    if renderLayerContents {
      try contentsLayer.addOpacityAnimation(for: baseLayerModel.transform, context: transformContext)

      contentsLayer.addVisibilityAnimation(
        inFrame: CGFloat(baseLayerModel.inFrame),
        outFrame: CGFloat(baseLayerModel.outFrame),
        context: context)
    }
  }

  func setupChildAnimations(context: LayerAnimationContext) throws {
    try super.setupAnimations(context: context)
  }

  override func addSublayer(_ layer: CALayer) {
    if layer === contentsLayer {
      super.addSublayer(contentsLayer)
    } else {
      contentsLayer.addSublayer(layer)
    }
  }