// BannerAdEngine.swift // Base class for banner ad engines // Corresponds to BannerAdEngine.kt in Android implementation import Foundation import UIKit public class BannerAdEngine: RelayAdEngine { private(set) var idleState: Idle! private(set) var loadingState: Loading! private(set) var activeState: Active! private(set) var showingState: Showing! public private(set) var hiddenState: Hidden! public var currentStateIdentifier: AdState.Identifier { return (currentState as? AdState)?.stateId ?? AdState.Identifier(name: currentState?.name ?? "unknown") } public override init(viewController: UIViewController, id: Int, adType: AdType, strategyName: String) { super.init(viewController: viewController, id: id, adType: adType, strategyName: strategyName) } public func initialize() { idleState = createIdleState() loadingState = createLoadingState() activeState = createActiveState() showingState = createShowingState() hiddenState = createHiddenState() addState(idleState) addState(loadingState) addState(activeState) addState(showingState, parent: activeState) addState(hiddenState, parent: activeState) setInitialState(idleState) start() } // Methods to be overridden by subclasses public class AdState: State { public let stateId: Identifier public init(name: String, stateId: Identifier) { self.stateId = stateId super.init() } public override var name: String { return stateId.name } public class Identifier: Equatable { public let name: String public init(name: String) { self.name = name } // Pre-defined identifiers public static let IDLE = Identifier(name: "idle") public static let LOADING = Identifier(name: "loading") public static let ACTIVE = Identifier(name: "active") public static let SHOWING = Identifier(name: "showing") public static let HIDDEN = Identifier(name: "hidden") public static func == (lhs: Identifier, rhs: Identifier) -> Bool { return lhs.name == rhs.name } } } public class Idle: AdState { public init() { super.init(name: "[IDLE]", stateId: Identifier.IDLE) } } public class Loading: AdState { public init() { super.init(name: "[LOADING]", stateId: Identifier.LOADING) } } public class Active: AdState { public init() { super.init(name: "[ACTIVE]", stateId: Identifier.ACTIVE) } } public class Showing: AdState { public init() { super.init(name: "[SHOWING]", stateId: Identifier.SHOWING) } } public class Hidden: AdState { public init() { super.init(name: "[HIDDEN]", stateId: Identifier.HIDDEN) } } // Factory methods for creating the states open func createIdleState() -> Idle { return Idle() } open func createLoadingState() -> Loading { return Loading() } open func createActiveState() -> Active { return Active() } open func createShowingState() -> Showing { return Showing() } open func createHiddenState() -> Hidden { return Hidden() } // Abstract methods to be implemented by subclasses internal func requestLoad() { fatalError("Subclass must implement") } internal func requestShow(_ request: BannerShowRequest? = nil) { fatalError("Subclass must implement") } internal func requestHide() { fatalError("Subclass must implement") } internal func requestDestroy() { fatalError("Subclass must implement") } // Public API methods public func show(_ request: BannerShowRequest? = nil) -> Bool { if isCurrent(activeState) || isCurrent(hiddenState) { requestShow(request) return true } return false } public func hide() -> Bool { if isCurrent(showingState) { requestHide() return true } return false } public func load() -> Bool { if isCurrent(idleState) { requestLoad() return true } return false } public func destroy() -> Bool { requestDestroy() return true } }