Skip to content

Commit

Permalink
2.22.0 Release
Browse files Browse the repository at this point in the history
  • Loading branch information
Nimbus Deploy committed Sep 25, 2024
1 parent bcd9fc1 commit f5308e3
Show file tree
Hide file tree
Showing 7 changed files with 661 additions and 17 deletions.
40 changes: 23 additions & 17 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ let package = Package(
.library(
name: "NimbusGAMKit",
targets: ["NimbusGAMKit"]),
.library(
name: "NimbusAdMobKit",
targets: ["NimbusAdMobKit"]),
.library(
name: "NimbusGoogleKit",
targets: ["NimbusGoogleKit"]),
Expand Down Expand Up @@ -65,7 +68,7 @@ let package = Package(
.package(url: "https://github.com/Vungle/VungleAdsSDK-SwiftPackageManager.git", from: "7.2.1"),
.package(
url: "https://github.com/googleads/swift-package-manager-google-mobile-ads.git",
"9.12.0"..<"12.0.0"
"11.7.0"..<"13.0.0"
),
.package(
url: "https://github.com/googleads/swift-package-manager-google-interactive-media-ads-ios.git",
Expand Down Expand Up @@ -106,6 +109,9 @@ let package = Package(
.target(
name: "NimbusGAMKit",
dependencies: ["NimbusTarget", .GoogleMobileAds]),
.target(
name: "NimbusAdMobKit",
dependencies: ["NimbusTarget", .GoogleMobileAds]),
.target(
name: "NimbusGoogleKit",
dependencies: ["NimbusTarget", .GoogleMobileAds]),
Expand All @@ -130,8 +136,8 @@ let package = Package(
checksum: "0b4df7fa4b0923abe87b0fbff67c22c6f1157784fb841d7d288abaec3a94b850"),
.binaryTarget(
name: "OMSDK_Adsbynimbus",
url: "https://adsbynimbus-public.s3.amazonaws.com/iOS/external/omsdk/1.4.12/OMSDK_Adsbynimbus-1.4.12.zip",
checksum: "7de37819dcd06a02cb116d3dea9fce9427cd8f09055625abd3b87388b08aecc1"),
url: "https://adsbynimbus-public.s3.amazonaws.com/iOS/external/omsdk/1.5.0/OMSDK_Adsbynimbus-1.5.0.zip",
checksum: "d8f4701cac276f1c813192d4b2583017b0f1049e8b02c48fda82ce60a8a93ca2"),
.binaryTarget(
name: "DTBiOSSDK",
url: "https://mdtb-sdk-packages.s3.us-west-2.amazonaws.com/iOS_APS_SDK/APS_iOS_SDK-4.9.7.zip",
Expand Down Expand Up @@ -174,30 +180,30 @@ extension Target.Dependency {
package.targets += [
.binaryTarget(
name: "NimbusCoreKit",
url: "https://adsbynimbus-public.s3.amazonaws.com/iOS/sdks/2.21.1/NimbusCoreKit-2.21.1.zip",
checksum: "08c23bfdbc9ab25b3eb0994b2635b414285a28a234ed5a0cc54984e56a58c471"),
url: "https://adsbynimbus-public.s3.amazonaws.com/iOS/sdks/2.22.0/NimbusCoreKit-2.22.0.zip",
checksum: "e13c41968299ed4bae7ad59fb23b1d48cc8436778f558ef5afb04e2dd0fc66b8"),
.binaryTarget(
name: "NimbusKit",
url: "https://adsbynimbus-public.s3.amazonaws.com/iOS/sdks/2.21.1/NimbusKit-2.21.1.zip",
checksum: "abda2aff7b861ef8e865916e1bbf0c4b4e1fc025b2911f4040daa1e8eeb08cdb"),
url: "https://adsbynimbus-public.s3.amazonaws.com/iOS/sdks/2.22.0/NimbusKit-2.22.0.zip",
checksum: "f03e9a95d602415afec7824dc4ce1f222c54d9158be4320e502f565b3d0c5df8"),
.binaryTarget(
name: "NimbusRequestKit",
url: "https://adsbynimbus-public.s3.amazonaws.com/iOS/sdks/2.21.1/NimbusRequestKit-2.21.1.zip",
checksum: "e7864508fa747c0ae7950a389b7782b8779315ca0e0906e1d6f8e4270c6f62f6"),
url: "https://adsbynimbus-public.s3.amazonaws.com/iOS/sdks/2.22.0/NimbusRequestKit-2.22.0.zip",
checksum: "6aac8d24331a3a308f0795f55fe301ab691e3e0020f40e8da16603d2c2454a3b"),
.binaryTarget(
name: "NimbusRenderKit",
url: "https://adsbynimbus-public.s3.amazonaws.com/iOS/sdks/2.21.1/NimbusRenderKit-2.21.1.zip",
checksum: "d1cefaa81428d657988f89ce8bc761934c0b07d8bbe385b4cb00aea935d0223e"),
url: "https://adsbynimbus-public.s3.amazonaws.com/iOS/sdks/2.22.0/NimbusRenderKit-2.22.0.zip",
checksum: "03e97ddae1d2ee96675be067dc5e54818a9e7cd5eaf468e27f2ab04419c5ef29"),
.binaryTarget(
name: "NimbusRenderStaticKit",
url: "https://adsbynimbus-public.s3.amazonaws.com/iOS/sdks/2.21.1/NimbusRenderStaticKit-2.21.1.zip",
checksum: "c482a2992cd559e6fc0a27e677e97d11ac53f234d4dff350e58795fe56688ec4"),
url: "https://adsbynimbus-public.s3.amazonaws.com/iOS/sdks/2.22.0/NimbusRenderStaticKit-2.22.0.zip",
checksum: "a63836464882c1cf199f78d34f3d270db183d95c0fe0cfd36a6e0fe6d4de2baa"),
.binaryTarget(
name: "NimbusRenderVideoKit",
url: "https://adsbynimbus-public.s3.amazonaws.com/iOS/sdks/2.21.1/NimbusRenderVideoKit-2.21.1.zip",
checksum: "4333e60583fe3a73f5ed7348ba0497809816d336aba37c967163e5b2ce8bf5bf"),
url: "https://adsbynimbus-public.s3.amazonaws.com/iOS/sdks/2.22.0/NimbusRenderVideoKit-2.22.0.zip",
checksum: "d923a868b16beea72750d936b43d8b4dee183146a1b4ac9f791fea01802478fc"),
.binaryTarget(
name: "NimbusRenderVASTKit",
url: "https://adsbynimbus-public.s3.amazonaws.com/iOS/sdks/2.21.1/NimbusRenderVASTKit-2.21.1.zip",
checksum: "08e0633bc1cbfcab9d06b9cad5698358c69371fdfc101529590a3c0a0563e4d8"),
url: "https://adsbynimbus-public.s3.amazonaws.com/iOS/sdks/2.22.0/NimbusRenderVASTKit-2.22.0.zip",
checksum: "58c68c334731908490277829012dbf4d4ed19595aeee4287f62bbc4f37e83c44"),
]
27 changes: 27 additions & 0 deletions Sources/NimbusAdMobKit/Render/Helpers/NimbusAdMobAdType.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// NimbusAdMobAdType.swift
// NimbusAdMobKit
// Created on 9/4/24
// Copyright © 2024 Nimbus Advertising Solutions Inc. All rights reserved.
//

import Foundation
import NimbusKit

enum NimbusAdMobAdType {
case banner
case native
case interstitial
case rewarded

init?(ad: NimbusAd, isBlocking: Bool) {
switch ad.auctionType {
case .static: self = isBlocking ? .interstitial : .banner
case .video: self = isBlocking ? .rewarded : .banner
case .native:
if !isBlocking { self = .native }
else { return nil }
@unknown default: return nil
}
}
}
257 changes: 257 additions & 0 deletions Sources/NimbusAdMobKit/Render/NimbusAdMobAdController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
//
// NimbusAdMobAdController.swift
// NimbusAdMobKit
// Created on 9/3/24
// Copyright © 2024 Nimbus Advertising Solutions Inc. All rights reserved.
//

import UIKit
import NimbusKit
import GoogleMobileAds

struct NimbusAdMobError: NimbusError {
let message: String

public var errorDescription: String? {
"AdMob controller error: \(message)"
}
}

final class NimbusAdMobAdController: NSObject {

enum AdState: String {
case notLoaded, loaded, presented
}

// MARK: - Properties

// MARK: AdController properties
weak var internalDelegate: AdControllerDelegate?
weak var delegate: AdControllerDelegate?

var friendlyObstructions: [UIView]?
var isClickProtectionEnabled = true
var volume = 0

// MARK: Internal properties
private let ad: NimbusAd
private let logger: Logger
private let isBlocking: Bool
private weak var container: UIView?
private weak var adPresentingViewController: UIViewController?
private weak var adRendererDelegate: NimbusAdMobAdRendererDelegate?
private var started = false
private var adState = AdState.notLoaded
private lazy var adType: NimbusAdMobAdType? = {
NimbusAdMobAdType(ad: ad, isBlocking: isBlocking)
}()

// MARK: AdMob properties
private var bannerAd: GADBannerView?
private var interstitialAd: GADInterstitialAd?
private var rewardedAd: GADRewardedAd?
private var nativeAdLoader: GADAdLoader?
private var nativeAd: GADNativeAd?

init(ad: NimbusAd,
container: UIView,
logger: Logger,
delegate: AdControllerDelegate,
isBlocking: Bool,
adPresentingViewController: UIViewController?,
adRendererDelegate: NimbusAdMobAdRendererDelegate? = nil) {

self.ad = ad
self.container = container
self.logger = logger
self.delegate = delegate
self.isBlocking = isBlocking
self.adPresentingViewController = adPresentingViewController
self.adRendererDelegate = adRendererDelegate
}

func load() {
guard let adType else {
forwardNimbusError(NimbusRenderError.adUnsupportedAuctionType(auctionType: ad.auctionType, network: ad.network))
return
}

switch adType {
case .banner:
let bannerAd = GADBannerView()
bannerAd.translatesAutoresizingMaskIntoConstraints = false
bannerAd.rootViewController = adPresentingViewController
bannerAd.delegate = self
self.bannerAd = bannerAd
self.adState = .loaded
bannerAd.load(withAdResponseString: ad.markup)
presentIfNeeded()
case .interstitial:
GADInterstitialAd.load(withAdResponseString: ad.markup) { [weak self] gadInterstitial, error in
if let gadInterstitial {
self?.interstitialAd = gadInterstitial
self?.interstitialAd?.fullScreenContentDelegate = self
self?.adState = .loaded
self?.presentIfNeeded()
} else {
let message: String
if let error { message = error.localizedDescription }
else { message = "Received neither an AdMob interstitial ad nor an error." }

self?.forwardNimbusError(NimbusAdMobError(message: message))
}
}
case .rewarded:
GADRewardedAd.load(withAdResponseString: ad.markup) { [weak self] gadRewarded, error in
if let gadRewarded {
self?.rewardedAd = gadRewarded
self?.rewardedAd?.fullScreenContentDelegate = self
self?.adState = .loaded
self?.presentIfNeeded()
} else {
let message: String
if let error { message = error.localizedDescription }
else { message = "Received neither an AdMob rewarded ad nor an error." }

self?.forwardNimbusError(NimbusAdMobError(message: message))
}
}
case .native:
guard let _ = adRendererDelegate else {
forwardNimbusError(NimbusAdMobError(message: "NimbusAdMobAdRendererDelegate must be set to render native ads"))
return
}

nativeAdLoader = GADAdLoader(rootViewController: adPresentingViewController)
nativeAdLoader?.delegate = self
nativeAdLoader?.load(withAdResponseString: ad.markup)
}
}

func presentIfNeeded() {
guard started, adState == .loaded else { return }

adState = .presented

if let bannerAd, let container {
container.addSubview(bannerAd)

NSLayoutConstraint.activate([
bannerAd.leadingAnchor.constraint(equalTo: container.safeAreaLayoutGuide.leadingAnchor),
bannerAd.trailingAnchor.constraint(equalTo: container.safeAreaLayoutGuide.trailingAnchor),
bannerAd.topAnchor.constraint(equalTo: container.safeAreaLayoutGuide.topAnchor),
bannerAd.bottomAnchor.constraint(equalTo: container.safeAreaLayoutGuide.bottomAnchor)
])
} else if let nativeAd, let container, let adRendererDelegate {
let nativeAdView = adRendererDelegate.nativeAdViewForRendering(container: container, nativeAd: nativeAd)
container.addSubview(nativeAdView)

NSLayoutConstraint.activate([
nativeAdView.leadingAnchor.constraint(equalTo: container.safeAreaLayoutGuide.leadingAnchor),
nativeAdView.trailingAnchor.constraint(equalTo: container.safeAreaLayoutGuide.trailingAnchor),
nativeAdView.topAnchor.constraint(equalTo: container.safeAreaLayoutGuide.topAnchor),
nativeAdView.bottomAnchor.constraint(equalTo: container.safeAreaLayoutGuide.bottomAnchor)
])
} else if let interstitialAd {
interstitialAd.present(fromRootViewController: adPresentingViewController)
} else if let rewardedAd {
rewardedAd.present(fromRootViewController: adPresentingViewController) { [weak self] in
self?.logger.log("AdMob Event: user earned reward", level: .debug)
self?.forwardNimbusEvent(.completed)
}
}
}

private func forwardNimbusEvent(_ event: NimbusEvent) {
internalDelegate?.didReceiveNimbusEvent(controller: self, event: event)
delegate?.didReceiveNimbusEvent(controller: self, event: event)
}

private func forwardNimbusError(_ error: NimbusError) {
internalDelegate?.didReceiveNimbusError(controller: self, error: error)
delegate?.didReceiveNimbusError(controller: self, error: error)
}
}

extension NimbusAdMobAdController: AdController {
var adView: UIView? { bannerAd }

var adDuration: CGFloat { 0 }

func start() {
started = true
presentIfNeeded()
}

func stop() {}

func destroy() {
bannerAd?.removeFromSuperview()
bannerAd = nil
nativeAd = nil
nativeAdLoader = nil
interstitialAd = nil
rewardedAd = nil
}
}

extension NimbusAdMobAdController: GADBannerViewDelegate {
func bannerViewDidRecordImpression(_ bannerView: GADBannerView) {
forwardNimbusEvent(.impression)
}

func bannerViewDidRecordClick(_ bannerView: GADBannerView) {
forwardNimbusEvent(.clicked)
}

func bannerView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: any Error) {
forwardNimbusError(NimbusAdMobError(message: error.localizedDescription))
}
}

extension NimbusAdMobAdController: GADFullScreenContentDelegate {
func adDidRecordImpression(_ ad: any GADFullScreenPresentingAd) {
forwardNimbusEvent(.impression)
}

func adDidRecordClick(_ ad: any GADFullScreenPresentingAd) {
forwardNimbusEvent(.clicked)
}

func ad(_ ad: any GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: any Error) {
forwardNimbusError(NimbusAdMobError(message: error.localizedDescription))
}

func adDidDismissFullScreenContent(_ ad: any GADFullScreenPresentingAd) {
destroy()
forwardNimbusEvent(.destroyed)
}
}

extension NimbusAdMobAdController: GADNativeAdLoaderDelegate {
func adLoader(_ adLoader: GADAdLoader, didReceive nativeAd: GADNativeAd) {
nativeAd.rootViewController = adPresentingViewController
nativeAd.delegate = self
self.nativeAd = nativeAd
self.adState = .loaded
presentIfNeeded()
}

func adLoader(_ adLoader: GADAdLoader, didFailToReceiveAdWithError error: any Error) {
forwardNimbusError(NimbusAdMobError(message: "Failed to receive native ad, error: \(error.localizedDescription)"))
}
}

extension NimbusAdMobAdController: GADNativeAdDelegate {
func nativeAdDidRecordImpression(_ nativeAd: GADNativeAd) {
forwardNimbusEvent(.impression)
}

func nativeAdDidRecordClick(_ nativeAd: GADNativeAd) {
forwardNimbusEvent(.clicked)
}

func nativeAdIsMuted(_ nativeAd: GADNativeAd) {
(container as? NimbusAdView)?.viewabilityTracker?.volume = 0
}
}
Loading

0 comments on commit f5308e3

Please sign in to comment.