Skip to content

Commit

Permalink
♻️ Handle an AppcuesFrameView being registered with multiple IDs
Browse files Browse the repository at this point in the history
  • Loading branch information
mmaatttt committed Aug 15, 2023
1 parent 37faf5a commit c3459fa
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ internal enum ExperienceRendererError: Error {
@available(iOS 13.0, *)
internal class ExperienceRenderer: ExperienceRendering, StateMachineOwning {

// Conformance to `StateMachineOwning`.
/// State machine for `RenderContext.modal`
var stateMachine: ExperienceStateMachine?
var renderContext: RenderContext?

private var stateMachines = StateMachineDirectory()
private var potentiallyRenderableExperiences: [RenderContext: [ExperienceData]] = [:]
Expand Down Expand Up @@ -62,6 +64,12 @@ internal class ExperienceRenderer: ExperienceRendering, StateMachineOwning {
existingFrameView.reset()
}

// If the machine being started is already registered for a different context,
// reset it back to its unregistered state before potentially showing new content.
if owner.stateMachine != nil, let frameView = owner as? AppcuesFrameView {
frameView.reset()
}

owner.stateMachine = ExperienceStateMachine(container: container)
stateMachines[ownerFor: context] = owner
if let pendingExperiences = potentiallyRenderableExperiences[context] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import Foundation

internal protocol StateMachineOwning: AnyObject {
var renderContext: RenderContext? { get set }
@available(iOS 13.0, *)
var stateMachine: ExperienceStateMachine? { get set }
}
Expand Down Expand Up @@ -37,7 +38,15 @@ internal class StateMachineDirectory {
stateMachines[key]?.value
}
set(newValue) {
// Enforce uniqueness (a StateMachineOwning may only be registered for a single RenderContext).
if let oldRenderContext = newValue?.renderContext, oldRenderContext != key {
stateMachines.removeValue(forKey: oldRenderContext)
}

stateMachines[key] = WeakStateMachineOwning(newValue)

// Save the current renderContext so it can be easily removed in the above uniqueness check.
newValue?.renderContext = key
}
}

Expand Down
3 changes: 3 additions & 0 deletions Sources/AppcuesKit/Presentation/UI/AppcuesFrameView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ public class AppcuesFrameView: UIView, StateMachineOwning {
case fade
}

// Managed by the StateMachineDirectory
internal var renderContext: RenderContext?

private var _stateMachine: Any?
@available(iOS 13.0, *)
internal var stateMachine: ExperienceStateMachine? {
Expand Down

0 comments on commit c3459fa

Please sign in to comment.