// GuruMaxAdsSdk.swift // Main SDK class for MAX integration // Corresponds to GuruMaxAdsSdk.kt in Android implementation import UIKit import AppLovinSDK import DTBiOSSDK import GuruConsent import FBAudienceNetwork import OpenWrapSDK import InMobiSDK import TradPlusAds import MobileFuseSDK public class GuruMaxAdsSdk: GuruAdsSdk { private static var instance: GuruMaxAdsSdk? private var initialized = false private static var interstitialAds: [String: GuruMaxInterstitialAd] = [:] private static var rewardedAds: [String: GuruMaxRewardedAd] = [:] private static var bannerAds: [String: GuruMaxBannerAd] = [:] private static var mrecAds: [String: GuruMaxMRecAd] = [:] private let viewController: UIViewController private init(viewController: UIViewController) { self.viewController = viewController } public static func obtain(viewController: UIViewController) -> GuruAdsSdk { if let existingInstance = instance { return existingInstance } let newInstance = GuruMaxAdsSdk(viewController: viewController) instance = newInstance return newInstance } private func logDebug(_ message: String) { Logger.d(tag: "GuruMaxAdsSdk", message: message) } private func logInfo(_ message: String) { Logger.i(tag: "GuruMaxAdsSdk", message: message) } private func logWarn(_ message: String) { Logger.w(tag: "GuruMaxAdsSdk", message: message) } public var adPlatform: AdPlatform { return AdPlatform.max } public func initialize(adsProfile: AdsProfile) async -> Bool { return await internalInitialize(adsProfile: adsProfile) // return true } private func internalInitialize(adsProfile: AdsProfile) async -> Bool { guard !initialized else { logWarn("SDK already initialized! Ignoring.") return false } guard !adsProfile.maxSdkKey.isEmpty else { logWarn("maxSdkKey is empty") return false } initialized = true // Initialize Amazon SDK if needed if let amazonAppId = adsProfile.amazonAppId, !amazonAppId.isEmpty { // In a real implementation, you would initialize Amazon SDK here logInfo("Would initialize Amazon SDK with ID: \(amazonAppId)") } // Configure PubMatic if needed if let pubmaticStoreUrl = adsProfile.pubmaticStoreUrl, !pubmaticStoreUrl.isEmpty { // In a real implementation, you would configure PubMatic here logInfo("Would configure PubMatic with store URL: \(pubmaticStoreUrl)") } let amazonAppId = adsProfile.amazonAppId ?? "" if (!amazonAppId.isEmpty) { DTBAds.sharedInstance().setAppKey(amazonAppId) DTBAds.sharedInstance().setAdNetworkInfo(DTBAdNetworkInfo.init(networkName: DTBADNETWORK_MAX)) DTBAds.sharedInstance().mraidCustomVersions = ["1.0", "2.0", "3.0"] DTBAds.sharedInstance().mraidPolicy = CUSTOM_MRAID DTBAds.sharedInstance().useGeoLocation = true if (adsProfile.debugMode) { DTBAds.sharedInstance().setLogLevel(DTBLogLevelAll) } // DTBAds.sharedInstance().testMode = true } // Update UID2 token if available if let uid2Token = adsProfile.uid2Token { updateUid2Token(uid2Token) } if(!(adsProfile.pubmaticStoreUrl?.isEmpty ?? true)){ let appInfo = POBApplicationInfo() appInfo.storeURL = URL(string: adsProfile.pubmaticStoreUrl!)! OpenWrapSDK.setApplicationInfo(appInfo) } let maxSdkKey = adsProfile.maxSdkKey NSLog("===> [\(ALMediationProviderMAX)]maxSdkKey: \(maxSdkKey)") let initConfig = ALSdkInitializationConfiguration(sdkKey: maxSdkKey) { builder in builder.mediationProvider = ALMediationProviderMAX let segments = adsProfile.segments.segments if(!segments.isEmpty) { builder.segmentCollection = MASegmentCollection { segmentsBuilder in for seg in segments { if (seg.key <= 0 || seg.values.isEmpty) { continue } segmentsBuilder.add(MASegment(key: NSNumber(value: seg.key), values: seg.values.map { NSNumber(value: $0) })) NSLog("segment.key:\(seg.key) \(seg.values)") } } } } // Initialize the AppLovin SDK let sdk = ALSdk.shared() // Set user ID if available if !adsProfile.userId.isEmpty { sdk.settings.userIdentifier = adsProfile.userId logDebug("Set userId \(adsProfile.userId) success") } else { logDebug("userId is null") } // Set custom parameters sdk.settings.isVerboseLoggingEnabled = adsProfile.debugMode sdk.settings.isMuted = true sdk.settings.setExtraParameterForKey("enable_black_screen_fixes", value: "true") return await withCheckedContinuation(isolation: MainActor.shared) { continuation in // Initialize AppLovin SDK do { sdk.initialize(with: initConfig){ [weak self] configuration in guard let self = self else { continuation.resume(returning: false) return } self.logDebug("AppLovinSdk initialized successfully") // Initialize TP Creative Key if needed if !adsProfile.tpCreativeKey.isEmpty { DispatchQueue.main.async { self.logWarn("tpCreativeKey \(adsProfile.tpCreativeKey)") // In a real implementation, you would initialize GuardManager here } } continuation.resume(returning: true) } } catch { continuation.resume(returning: false) } } } private func updateUid2Token(_ uid2Token: String?) { guard let uid2Token = uid2Token, !uid2Token.isEmpty else { return } // In a real implementation, you would set the UID2 token to various ad networks logDebug("Set uid2Token success \(uid2Token)") // Define UID2 API constant let UID2_API = "uidapi.com" // Update for InMobi let jsonObject = ["uidapi.com": uid2Token] // In a real implementation, you would use this with InMobiSdk // Update for PubMatic // In a real implementation, you would use this with PubMatic SDK // Update for TradPlus // In a real implementation, you would use this with TradPlus SDK // Update for MobileFuse // In a real implementation, you would use this with MobileFuse SDK } public func obtainInterstitialAd(adConfig: AdConfig) -> GuruInterstitialAd { if let existingAd = Self.interstitialAds[adConfig.cacheKey] { return existingAd } let newAd = GuruMaxInterstitialAd(viewController: viewController, adConfig: adConfig) Self.interstitialAds[adConfig.cacheKey] = newAd return newAd } public func obtainRewardedAd(adConfig: AdConfig) -> GuruRewardedAd { if let existingAd = Self.rewardedAds[adConfig.cacheKey] { return existingAd } let newAd = GuruMaxRewardedAd(viewController: viewController, adConfig: adConfig) Self.rewardedAds[adConfig.cacheKey] = newAd return newAd } public func obtainBannerAd(adConfig: AdConfig) -> GuruBannerAd { if let existingAd = Self.bannerAds[adConfig.cacheKey] { return existingAd } let newAd = GuruMaxBannerAd(viewController: viewController, adConfig: adConfig) Self.bannerAds[adConfig.cacheKey] = newAd return newAd } public func obtainMRecAd(adConfig: AdConfig) -> GuruMRecAd { if let existingAd = Self.mrecAds[adConfig.cacheKey] { return existingAd } let newAd = GuruMaxMRecAd(viewController: viewController, adConfig: adConfig) Self.mrecAds[adConfig.cacheKey] = newAd return newAd } public func processCrossAction(action: AdsCrossAction) -> Bool { // Implement cross-platform actions as needed return true } }