You've already forked Commercialization.tapadn
Add iOS support for TapADN package
This commit is contained in:
@@ -366,6 +366,10 @@ namespace Dirichlet.Mediation
|
||||
private readonly IDirichletPlatformBridge bridge;
|
||||
private static readonly object RewardAutoSessionLock = new object();
|
||||
private static readonly Dictionary<string, AutoRewardVideoSession> RewardAutoSessions = new Dictionary<string, AutoRewardVideoSession>(StringComparer.Ordinal);
|
||||
private static readonly object InterstitialAutoSessionLock = new object();
|
||||
private static readonly Dictionary<string, AutoInterstitialSession> InterstitialAutoSessions = new Dictionary<string, AutoInterstitialSession>(StringComparer.Ordinal);
|
||||
private static readonly object SplashAutoSessionLock = new object();
|
||||
private static readonly Dictionary<string, AutoSplashSession> SplashAutoSessions = new Dictionary<string, AutoSplashSession>(StringComparer.Ordinal);
|
||||
|
||||
public static DirichletAdNative Create() => DirichletAdManager.CreateAdNative();
|
||||
|
||||
@@ -478,7 +482,7 @@ namespace Dirichlet.Mediation
|
||||
|
||||
/// <summary>
|
||||
/// Shows an interstitial ad with automatic load-and-show logic.
|
||||
/// Android only - iOS receives OnError with not_supported.
|
||||
/// Android uses the native AutoAd API; iOS/editor use a load-then-show fallback without native cache.
|
||||
/// </summary>
|
||||
public void ShowInterstitialAutoAd(DirichletAdRequest request, IDirichletInterstitialAutoAdListener listener)
|
||||
{
|
||||
@@ -487,13 +491,17 @@ namespace Dirichlet.Mediation
|
||||
return;
|
||||
}
|
||||
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
bridge.ShowInterstitialAutoAd(request, listener);
|
||||
#else
|
||||
ShowInterstitialLoadAndShowInternal(request, listener);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows a banner ad with automatic load + rotation logic. Container is created internally and
|
||||
/// anchored at the bottom of the screen by default. Use <see cref="DirichletAdRequest.Builder.WithSlideInterval"/>
|
||||
/// to control rotation interval. Android only - iOS receives OnError with not_supported.
|
||||
/// to control rotation interval. Native auto rotation is currently Android only.
|
||||
/// </summary>
|
||||
public void ShowBannerAutoAd(DirichletAdRequest request, IDirichletBannerAutoAdListener listener)
|
||||
{
|
||||
@@ -516,7 +524,7 @@ namespace Dirichlet.Mediation
|
||||
|
||||
/// <summary>
|
||||
/// Shows a splash ad with automatic load logic. Container is a fullscreen overlay created internally.
|
||||
/// Android only - iOS receives OnError with not_supported.
|
||||
/// Android uses the native AutoAd API; iOS/editor use a load-then-show fallback without native cache.
|
||||
/// </summary>
|
||||
public void ShowSplashAutoAd(DirichletAdRequest request, IDirichletSplashAutoAdListener listener)
|
||||
{
|
||||
@@ -533,7 +541,11 @@ namespace Dirichlet.Mediation
|
||||
return;
|
||||
}
|
||||
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
bridge.ShowSplashAutoAd(request, options ?? new DirichletAdShowOptions(), listener);
|
||||
#else
|
||||
ShowSplashLoadAndShowInternal(request, options ?? new DirichletAdShowOptions(), listener);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -566,6 +578,7 @@ namespace Dirichlet.Mediation
|
||||
var session = new AutoRewardVideoSession(sessionId, ad, listener);
|
||||
RegisterRewardAutoSession(session);
|
||||
ad.SetInteractionListener(session);
|
||||
ad.ShowFailed += session.OnShowFailed;
|
||||
|
||||
// Load succeeded; show immediately.
|
||||
var shown = ad.Show();
|
||||
@@ -580,6 +593,66 @@ namespace Dirichlet.Mediation
|
||||
});
|
||||
}
|
||||
|
||||
private void ShowInterstitialLoadAndShowInternal(DirichletAdRequest request, IDirichletInterstitialAutoAdListener listener)
|
||||
{
|
||||
LoadInterstitialAd(
|
||||
request,
|
||||
ad =>
|
||||
{
|
||||
if (ad == null)
|
||||
{
|
||||
listener?.OnError(new DirichletError("invalid_ad", "Load callback returned null ad"));
|
||||
return;
|
||||
}
|
||||
|
||||
var sessionId = Guid.NewGuid().ToString("N");
|
||||
var session = new AutoInterstitialSession(sessionId, ad, listener);
|
||||
RegisterInterstitialAutoSession(session);
|
||||
ad.SetInteractionListener(session);
|
||||
ad.ShowFailed += session.OnShowFailed;
|
||||
|
||||
var shown = ad.Show();
|
||||
if (!shown)
|
||||
{
|
||||
session.FailAndDispose(new DirichletError("show_failed", "ShowInterstitialAd returned false"));
|
||||
}
|
||||
},
|
||||
error =>
|
||||
{
|
||||
listener?.OnError(error ?? new DirichletError("load_failed", "LoadInterstitialAd failed"));
|
||||
});
|
||||
}
|
||||
|
||||
private void ShowSplashLoadAndShowInternal(DirichletAdRequest request, DirichletAdShowOptions options, IDirichletSplashAutoAdListener listener)
|
||||
{
|
||||
LoadSplashAd(
|
||||
request,
|
||||
ad =>
|
||||
{
|
||||
if (ad == null)
|
||||
{
|
||||
listener?.OnError(new DirichletError("invalid_ad", "Load callback returned null ad"));
|
||||
return;
|
||||
}
|
||||
|
||||
var sessionId = Guid.NewGuid().ToString("N");
|
||||
var session = new AutoSplashSession(sessionId, ad, listener);
|
||||
RegisterSplashAutoSession(session);
|
||||
ad.SetInteractionListener(session);
|
||||
ad.ShowFailed += session.OnShowFailed;
|
||||
|
||||
var shown = ad.Show();
|
||||
if (!shown)
|
||||
{
|
||||
session.FailAndDispose(new DirichletError("show_failed", "ShowSplashAd returned false"));
|
||||
}
|
||||
},
|
||||
error =>
|
||||
{
|
||||
listener?.OnError(error ?? new DirichletError("load_failed", "LoadSplashAd failed"));
|
||||
});
|
||||
}
|
||||
|
||||
private static bool ValidateRequest(DirichletAdRequest request, Action<DirichletError> onFailure)
|
||||
{
|
||||
if (request == null)
|
||||
@@ -628,6 +701,58 @@ namespace Dirichlet.Mediation
|
||||
}
|
||||
}
|
||||
|
||||
private static void RegisterInterstitialAutoSession(AutoInterstitialSession session)
|
||||
{
|
||||
if (session == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock (InterstitialAutoSessionLock)
|
||||
{
|
||||
InterstitialAutoSessions[session.SessionId] = session;
|
||||
}
|
||||
}
|
||||
|
||||
private static void UnregisterInterstitialAutoSession(string sessionId)
|
||||
{
|
||||
if (string.IsNullOrEmpty(sessionId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock (InterstitialAutoSessionLock)
|
||||
{
|
||||
InterstitialAutoSessions.Remove(sessionId);
|
||||
}
|
||||
}
|
||||
|
||||
private static void RegisterSplashAutoSession(AutoSplashSession session)
|
||||
{
|
||||
if (session == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock (SplashAutoSessionLock)
|
||||
{
|
||||
SplashAutoSessions[session.SessionId] = session;
|
||||
}
|
||||
}
|
||||
|
||||
private static void UnregisterSplashAutoSession(string sessionId)
|
||||
{
|
||||
if (string.IsNullOrEmpty(sessionId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock (SplashAutoSessionLock)
|
||||
{
|
||||
SplashAutoSessions.Remove(sessionId);
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class AutoRewardVideoSession : IDirichletRewardAdInteractionListener
|
||||
{
|
||||
public string SessionId { get; }
|
||||
@@ -684,6 +809,11 @@ namespace Dirichlet.Mediation
|
||||
listener?.OnRewardVerify(args);
|
||||
}
|
||||
|
||||
public void OnShowFailed(DirichletError error)
|
||||
{
|
||||
FailAndDispose(error ?? new DirichletError("show_error", "Reward video ad failed to show"));
|
||||
}
|
||||
|
||||
public void FailAndDispose(DirichletError error)
|
||||
{
|
||||
if (disposed)
|
||||
@@ -707,6 +837,8 @@ namespace Dirichlet.Mediation
|
||||
|
||||
try
|
||||
{
|
||||
ad.ShowFailed -= OnShowFailed;
|
||||
ad.SetInteractionListener(null);
|
||||
ad?.Destroy();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -715,6 +847,176 @@ namespace Dirichlet.Mediation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class AutoInterstitialSession : IDirichletInterstitialAdInteractionListener
|
||||
{
|
||||
public string SessionId { get; }
|
||||
|
||||
private readonly DirichletInterstitialAd ad;
|
||||
private readonly IDirichletInterstitialAutoAdListener listener;
|
||||
private bool disposed;
|
||||
|
||||
public AutoInterstitialSession(string sessionId, DirichletInterstitialAd ad, IDirichletInterstitialAutoAdListener listener)
|
||||
{
|
||||
SessionId = string.IsNullOrEmpty(sessionId) ? Guid.NewGuid().ToString("N") : sessionId;
|
||||
this.ad = ad ?? throw new ArgumentNullException(nameof(ad));
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public void OnAdShow()
|
||||
{
|
||||
if (disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
listener?.OnAdShow();
|
||||
}
|
||||
|
||||
public void OnAdClick()
|
||||
{
|
||||
if (disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
listener?.OnAdClick();
|
||||
}
|
||||
|
||||
public void OnAdClose()
|
||||
{
|
||||
if (disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
listener?.OnAdClose();
|
||||
Dispose();
|
||||
}
|
||||
|
||||
public void OnShowFailed(DirichletError error)
|
||||
{
|
||||
FailAndDispose(error ?? new DirichletError("show_error", "Interstitial ad failed to show"));
|
||||
}
|
||||
|
||||
public void FailAndDispose(DirichletError error)
|
||||
{
|
||||
if (disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
listener?.OnError(error ?? new DirichletError("unknown_error", "Unknown error"));
|
||||
Dispose();
|
||||
}
|
||||
|
||||
private void Dispose()
|
||||
{
|
||||
if (disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
disposed = true;
|
||||
UnregisterInterstitialAutoSession(SessionId);
|
||||
|
||||
try
|
||||
{
|
||||
ad.ShowFailed -= OnShowFailed;
|
||||
ad.SetInteractionListener(null);
|
||||
ad?.Destroy();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogWarning($"[Dirichlet] Auto interstitial ad Destroy failed: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class AutoSplashSession : IDirichletSplashAdInteractionListener
|
||||
{
|
||||
public string SessionId { get; }
|
||||
|
||||
private readonly DirichletSplashAd ad;
|
||||
private readonly IDirichletSplashAutoAdListener listener;
|
||||
private bool disposed;
|
||||
|
||||
public AutoSplashSession(string sessionId, DirichletSplashAd ad, IDirichletSplashAutoAdListener listener)
|
||||
{
|
||||
SessionId = string.IsNullOrEmpty(sessionId) ? Guid.NewGuid().ToString("N") : sessionId;
|
||||
this.ad = ad ?? throw new ArgumentNullException(nameof(ad));
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public void OnAdShow()
|
||||
{
|
||||
if (disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
listener?.OnAdShow();
|
||||
}
|
||||
|
||||
public void OnAdClick()
|
||||
{
|
||||
if (disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
listener?.OnAdClick();
|
||||
}
|
||||
|
||||
public void OnAdClose()
|
||||
{
|
||||
if (disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
listener?.OnAdClose();
|
||||
Dispose();
|
||||
}
|
||||
|
||||
public void OnShowFailed(DirichletError error)
|
||||
{
|
||||
FailAndDispose(error ?? new DirichletError("show_error", "Splash ad failed to show"));
|
||||
}
|
||||
|
||||
public void FailAndDispose(DirichletError error)
|
||||
{
|
||||
if (disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
listener?.OnError(error ?? new DirichletError("unknown_error", "Unknown error"));
|
||||
Dispose();
|
||||
}
|
||||
|
||||
private void Dispose()
|
||||
{
|
||||
if (disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
disposed = true;
|
||||
UnregisterSplashAutoSession(SessionId);
|
||||
|
||||
try
|
||||
{
|
||||
ad.ShowFailed -= OnShowFailed;
|
||||
ad.SetInteractionListener(null);
|
||||
ad?.Destroy();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogWarning($"[Dirichlet] Auto splash ad Destroy failed: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1189,7 +1491,7 @@ namespace Dirichlet.Mediation
|
||||
|
||||
/// <summary>
|
||||
/// Listener interface for auto interstitial ad callbacks.
|
||||
/// Android only - iOS will receive OnError with not_supported error.
|
||||
/// Android uses native auto cache; iOS/editor can emulate load-then-show.
|
||||
/// </summary>
|
||||
public interface IDirichletInterstitialAutoAdListener
|
||||
{
|
||||
@@ -1201,7 +1503,7 @@ namespace Dirichlet.Mediation
|
||||
|
||||
/// <summary>
|
||||
/// Listener interface for auto banner ad callbacks.
|
||||
/// Android only - iOS will receive OnError with not_supported error.
|
||||
/// Native auto rotation is Android only.
|
||||
/// </summary>
|
||||
public interface IDirichletBannerAutoAdListener
|
||||
{
|
||||
@@ -1213,7 +1515,7 @@ namespace Dirichlet.Mediation
|
||||
|
||||
/// <summary>
|
||||
/// Listener interface for auto splash ad callbacks.
|
||||
/// Android only - iOS will receive OnError with not_supported error.
|
||||
/// Android uses native auto cache; iOS/editor can emulate load-then-show.
|
||||
/// </summary>
|
||||
public interface IDirichletSplashAutoAdListener
|
||||
{
|
||||
@@ -1226,7 +1528,7 @@ namespace Dirichlet.Mediation
|
||||
/// <summary>
|
||||
/// Listener interface for auto reward video ad callbacks.
|
||||
/// Used with ShowRewardVideoAutoAd which combines load and show into one operation.
|
||||
/// Android only - iOS will receive OnError with not_supported error.
|
||||
/// Android uses native auto cache; iOS/editor can emulate load-then-show.
|
||||
/// </summary>
|
||||
public interface IDirichletRewardVideoAutoAdListener
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user