362 lines
11 KiB
Swift
362 lines
11 KiB
Swift
|
|
// AdsEngineManager.swift
|
||
|
|
// Manages all ad engines
|
||
|
|
// Corresponds to AdsEngineManager.kt in Android implementation
|
||
|
|
|
||
|
|
import Foundation
|
||
|
|
import UIKit
|
||
|
|
|
||
|
|
class AdsEngineManager {
|
||
|
|
|
||
|
|
private let viewController: UIViewController
|
||
|
|
|
||
|
|
private var interstitialAdEngines: [Int: InterstitialAdEngine] = [:]
|
||
|
|
private var rewardedAdEngines: [Int: RewardedAdEngine] = [:]
|
||
|
|
private var bannerAdEngines: [Int: BannerAdEngine] = [:]
|
||
|
|
private var mrecAdEngines: [Int: MRecAdEngine] = [:]
|
||
|
|
|
||
|
|
private var supportedAdsSdk: [AdPlatform: GuruAdsSdk] = [:]
|
||
|
|
|
||
|
|
init(viewController: UIViewController) {
|
||
|
|
self.viewController = viewController
|
||
|
|
}
|
||
|
|
|
||
|
|
// MARK: - Logging
|
||
|
|
|
||
|
|
private func logInfo(_ message: String) {
|
||
|
|
Logger.i(tag: "StrategyManager", message: message)
|
||
|
|
}
|
||
|
|
|
||
|
|
private func logError(_ message: String, error: Error? = nil) {
|
||
|
|
Logger.e(tag: "StrategyManager", message: message)
|
||
|
|
}
|
||
|
|
|
||
|
|
// MARK: - SDK Management
|
||
|
|
|
||
|
|
internal func addAdsSdk(_ adsSdk: GuruAdsSdk) {
|
||
|
|
supportedAdsSdk[adsSdk.adPlatform] = adsSdk
|
||
|
|
}
|
||
|
|
|
||
|
|
private func getAdsSdk(adPlatform: AdPlatform) -> GuruAdsSdk? {
|
||
|
|
return supportedAdsSdk[adPlatform]
|
||
|
|
}
|
||
|
|
|
||
|
|
// MARK: - Interstitial Engine Methods
|
||
|
|
|
||
|
|
private func createDefaultInterstitialAdEngine(
|
||
|
|
id: Int,
|
||
|
|
config: DefaultInterstitialConfig
|
||
|
|
) -> DefaultInterstitialAdEngine? {
|
||
|
|
if let adSdk = getAdsSdk(adPlatform: AdPlatform.fromName(config.adPlatform))?.obtainInterstitialAd(
|
||
|
|
adConfig: AdConfig(
|
||
|
|
engineId: id,
|
||
|
|
adUnitId: config.adUnitId,
|
||
|
|
adAmazonSlotId: config.adAmazonSlotId
|
||
|
|
)
|
||
|
|
) {
|
||
|
|
return DefaultInterstitialAdEngine(viewController: viewController, id: id, ad: adSdk)
|
||
|
|
} else {
|
||
|
|
return nil;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private func createMabInterstitialEngine(
|
||
|
|
id: Int,
|
||
|
|
faUnitId: String,
|
||
|
|
config: MabInterstitialConfig
|
||
|
|
) -> MabInterstitialEngine {
|
||
|
|
return MabInterstitialEngine(viewController: viewController, id: id, faUnitId: faUnitId, mabConfig: config) {
|
||
|
|
[weak self] adPlatform, adConfig in
|
||
|
|
self?.getAdsSdk(adPlatform: adPlatform)?.obtainInterstitialAd(adConfig: adConfig)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func getInterstitialAdEngine(id: Int) -> InterstitialAdEngine? {
|
||
|
|
return interstitialAdEngines[id]
|
||
|
|
}
|
||
|
|
|
||
|
|
func createInterstitialAdEngine(adEngineConfig: AdEngineConfig) -> InterstitialAdEngine? {
|
||
|
|
// Potential hashcode collision
|
||
|
|
let id = adEngineConfig.hashCode()
|
||
|
|
logInfo("createInterstitialAdEngine: \(id)")
|
||
|
|
|
||
|
|
|
||
|
|
let engine:InterstitialAdEngine? = getInterstitialAdEngine(id: id) ?? {
|
||
|
|
logInfo("config parsed!, with strategy \(InterstitialStrategy.default.rawValue)")
|
||
|
|
switch adEngineConfig.strategy {
|
||
|
|
case InterstitialStrategy.default.rawValue:
|
||
|
|
guard let config = try? DefaultInterstitialConfig(adEngineConfig.config) else {
|
||
|
|
return nil;
|
||
|
|
}
|
||
|
|
return createDefaultInterstitialAdEngine(
|
||
|
|
id: id,
|
||
|
|
config: config
|
||
|
|
)
|
||
|
|
case InterstitialStrategy.mab.rawValue:
|
||
|
|
guard let config = try? MabInterstitialConfig(adEngineConfig.config) else {
|
||
|
|
return nil;
|
||
|
|
}
|
||
|
|
return createMabInterstitialEngine(id: id, faUnitId: adEngineConfig.faUnitId, config: config)
|
||
|
|
default:
|
||
|
|
// todo forward compatible
|
||
|
|
guard let config = try? DefaultInterstitialConfig(adEngineConfig.config) else {
|
||
|
|
return nil;
|
||
|
|
}
|
||
|
|
return createDefaultInterstitialAdEngine(
|
||
|
|
id: id,
|
||
|
|
config:config
|
||
|
|
)
|
||
|
|
}
|
||
|
|
}()
|
||
|
|
|
||
|
|
if let engine = engine {
|
||
|
|
interstitialAdEngines[id] = engine
|
||
|
|
}
|
||
|
|
|
||
|
|
return engine
|
||
|
|
}
|
||
|
|
|
||
|
|
// MARK: - Rewarded Engine Methods
|
||
|
|
|
||
|
|
private func createDefaultRewardedAdEngine(
|
||
|
|
id: Int,
|
||
|
|
config: DefaultRewardedConfig
|
||
|
|
) -> DefaultRewardedAdEngine? {
|
||
|
|
if let adSdk = getAdsSdk(adPlatform: AdPlatform.fromName(config.adPlatform))?.obtainRewardedAd(
|
||
|
|
adConfig: AdConfig(
|
||
|
|
engineId: id,
|
||
|
|
adUnitId: config.adUnitId,
|
||
|
|
adAmazonSlotId: config.adAmazonSlotId
|
||
|
|
)
|
||
|
|
) {
|
||
|
|
return DefaultRewardedAdEngine(viewController: viewController, id: id, ad: adSdk)
|
||
|
|
} else {
|
||
|
|
return nil;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private func createMabRewardedEngine(
|
||
|
|
id: Int,
|
||
|
|
faUnitId: String,
|
||
|
|
config: MabRewardedConfig
|
||
|
|
) -> MabRewardedEngine {
|
||
|
|
return MabRewardedEngine(viewController: viewController, id: id, faUnitId: faUnitId, mabConfig: config) {
|
||
|
|
[weak self] adPlatform, adConfig in
|
||
|
|
self?.getAdsSdk(adPlatform: adPlatform)?.obtainRewardedAd(adConfig: adConfig)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func getRewardedAdEngine(id: Int) -> RewardedAdEngine? {
|
||
|
|
return rewardedAdEngines[id]
|
||
|
|
}
|
||
|
|
|
||
|
|
func createRewardedAdEngine(adEngineConfig: AdEngineConfig) -> RewardedAdEngine? {
|
||
|
|
let id = adEngineConfig.hashCode()
|
||
|
|
logInfo("createRewardedAdEngine: \(id)")
|
||
|
|
|
||
|
|
let engine = getRewardedAdEngine(id: id) ?? {
|
||
|
|
switch adEngineConfig.strategy {
|
||
|
|
case RewardedStrategy.default.rawValue:
|
||
|
|
guard let config = try? DefaultRewardedConfig(adEngineConfig.config) else {
|
||
|
|
return nil;
|
||
|
|
}
|
||
|
|
return createDefaultRewardedAdEngine(
|
||
|
|
id: id,
|
||
|
|
config: config
|
||
|
|
)
|
||
|
|
case RewardedStrategy.mab.rawValue:
|
||
|
|
guard let config = try? MabRewardedConfig(adEngineConfig.config) else {
|
||
|
|
return nil;
|
||
|
|
}
|
||
|
|
return createMabRewardedEngine(id: id, faUnitId: adEngineConfig.faUnitId, config: config)
|
||
|
|
|
||
|
|
default:
|
||
|
|
guard let config = try? DefaultRewardedConfig(adEngineConfig.config) else {
|
||
|
|
return nil;
|
||
|
|
}
|
||
|
|
return createDefaultRewardedAdEngine(
|
||
|
|
id: id,
|
||
|
|
config: config
|
||
|
|
)
|
||
|
|
}
|
||
|
|
}()
|
||
|
|
|
||
|
|
if let engine = engine {
|
||
|
|
rewardedAdEngines[id] = engine
|
||
|
|
}
|
||
|
|
|
||
|
|
return engine
|
||
|
|
}
|
||
|
|
|
||
|
|
// MARK: - Banner Engine Methods
|
||
|
|
|
||
|
|
private func createDefaultBannerAdEngine(
|
||
|
|
id: Int,
|
||
|
|
config: DefaultBannerConfig
|
||
|
|
) -> DefaultBannerAdEngine? {
|
||
|
|
if let adSdk = getAdsSdk(adPlatform: AdPlatform.fromName(config.adPlatform))?.obtainBannerAd(
|
||
|
|
adConfig: AdConfig(
|
||
|
|
engineId: id,
|
||
|
|
adUnitId: config.adUnitId,
|
||
|
|
adAmazonSlotId: config.adAmazonSlotId
|
||
|
|
)
|
||
|
|
) {
|
||
|
|
return DefaultBannerAdEngine(viewController: viewController, id: id, ad: adSdk)
|
||
|
|
} else {
|
||
|
|
return nil;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func getBannerAdEngine(id: Int) -> BannerAdEngine? {
|
||
|
|
return bannerAdEngines[id]
|
||
|
|
}
|
||
|
|
|
||
|
|
func createBannerAdEngine(adEngineConfig: AdEngineConfig) -> BannerAdEngine? {
|
||
|
|
let id = adEngineConfig.hashCode()
|
||
|
|
logInfo("createBannerAdEngine: \(id)")
|
||
|
|
|
||
|
|
let engine = getBannerAdEngine(id: id) ?? {
|
||
|
|
switch adEngineConfig.strategy {
|
||
|
|
case BannerStrategy.default.rawValue:
|
||
|
|
guard let config = try? DefaultBannerConfig(adEngineConfig.config) else {
|
||
|
|
return nil;
|
||
|
|
}
|
||
|
|
return createDefaultBannerAdEngine(
|
||
|
|
id: id,
|
||
|
|
config: config
|
||
|
|
)
|
||
|
|
|
||
|
|
default:
|
||
|
|
guard let config = try? DefaultBannerConfig(adEngineConfig.config) else {
|
||
|
|
return nil;
|
||
|
|
}
|
||
|
|
return createDefaultBannerAdEngine(
|
||
|
|
id: id,
|
||
|
|
config: config
|
||
|
|
)
|
||
|
|
}
|
||
|
|
}()
|
||
|
|
|
||
|
|
if let engine = engine {
|
||
|
|
bannerAdEngines[id] = engine
|
||
|
|
}
|
||
|
|
|
||
|
|
return engine
|
||
|
|
}
|
||
|
|
|
||
|
|
// MARK: - MRec Engine Methods
|
||
|
|
|
||
|
|
private func createDefaultMRecAdEngine(
|
||
|
|
id: Int,
|
||
|
|
config: DefaultMRecConfig
|
||
|
|
) -> DefaultMRecAdEngine? {
|
||
|
|
if let adSdk = getAdsSdk(adPlatform: AdPlatform.fromName(config.adPlatform))?.obtainMRecAd(
|
||
|
|
adConfig: AdConfig(
|
||
|
|
engineId: id,
|
||
|
|
adUnitId: config.adUnitId,
|
||
|
|
adAmazonSlotId: config.adAmazonSlotId
|
||
|
|
)
|
||
|
|
) {
|
||
|
|
return DefaultMRecAdEngine(viewController: viewController, id: id, ad: adSdk)
|
||
|
|
} else {
|
||
|
|
return nil;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func getMRecAdEngine(id: Int) -> MRecAdEngine? {
|
||
|
|
return mrecAdEngines[id]
|
||
|
|
}
|
||
|
|
|
||
|
|
func createMRecAdEngine(adEngineConfig: AdEngineConfig) -> MRecAdEngine? {
|
||
|
|
let id = adEngineConfig.hashCode()
|
||
|
|
logInfo("createMRecAdEngine: \(id)")
|
||
|
|
|
||
|
|
let engine = getMRecAdEngine(id: id) ?? {
|
||
|
|
switch adEngineConfig.strategy {
|
||
|
|
case BannerStrategy.default.rawValue:
|
||
|
|
guard let config = try? DefaultMRecConfig(adEngineConfig.config) else {
|
||
|
|
return nil;
|
||
|
|
}
|
||
|
|
return createDefaultMRecAdEngine(
|
||
|
|
id: id,
|
||
|
|
config: config
|
||
|
|
)
|
||
|
|
|
||
|
|
default:
|
||
|
|
guard let config = try? DefaultMRecConfig(adEngineConfig.config) else {
|
||
|
|
return nil;
|
||
|
|
}
|
||
|
|
return createDefaultMRecAdEngine(
|
||
|
|
id: id,
|
||
|
|
config: config
|
||
|
|
)
|
||
|
|
}
|
||
|
|
}()
|
||
|
|
|
||
|
|
if let engine = engine {
|
||
|
|
mrecAdEngines[id] = engine
|
||
|
|
}
|
||
|
|
|
||
|
|
return engine
|
||
|
|
}
|
||
|
|
|
||
|
|
func dispatchOrientationUpdate(orientation: ScreenOrientation) {
|
||
|
|
let body: (Any) throws -> Void = { it in
|
||
|
|
(it as? OrientationAware)?.onOrientationUpdate(orientation: orientation)
|
||
|
|
}
|
||
|
|
try? interstitialAdEngines.values.forEach(body)
|
||
|
|
try? bannerAdEngines.values.forEach(body)
|
||
|
|
try? rewardedAdEngines.values.forEach(body)
|
||
|
|
try? mrecAdEngines.values.forEach(body)
|
||
|
|
}
|
||
|
|
|
||
|
|
// for testing only!
|
||
|
|
func clearCachedEngines() {
|
||
|
|
interstitialAdEngines.removeAll()
|
||
|
|
bannerAdEngines.removeAll()
|
||
|
|
rewardedAdEngines.removeAll()
|
||
|
|
mrecAdEngines.removeAll()
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
// MARK: - Hashable Extension for AdEngineConfig
|
||
|
|
|
||
|
|
extension AdEngineConfig: Hashable {
|
||
|
|
func hashCode() -> Int {
|
||
|
|
return hashValue
|
||
|
|
}
|
||
|
|
public static func == (lhs: AdEngineConfig, rhs: AdEngineConfig) -> Bool {
|
||
|
|
return lhs.strategy == rhs.strategy
|
||
|
|
&& (lhs.config as NSDictionary).isEqual(to: rhs.config)
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public func hash(into hasher: inout Hasher) {
|
||
|
|
hasher.combine(strategy)
|
||
|
|
for (key, value) in config {
|
||
|
|
hasher.combine(key)
|
||
|
|
if let hashableValue = value as? (any Hashable) {
|
||
|
|
hasher.combine(hashableValue)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// MARK: - Hashable Extensions
|
||
|
|
|
||
|
|
extension Int {
|
||
|
|
func hashCode() -> Int {
|
||
|
|
return self
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
extension String {
|
||
|
|
func hashCode() -> Int {
|
||
|
|
var h: Int = 0
|
||
|
|
for c in self.unicodeScalars {
|
||
|
|
h = 31 &* h &+ Int(c.value)
|
||
|
|
}
|
||
|
|
return h
|
||
|
|
}
|
||
|
|
}
|