Refactoring
Code refactoring to address comments
MODIFY
adapters/Unity/UnityAdapter/GADMAdapterUnity.m
adapters/Unity/UnityAdapter/GADMAdapterUnity.m
if (_bannerAd != nil) {
[_bannerAd stopBeingDelegate];
}
- [[GADMAdapterUnitySingleton sharedInstance].placementsInUse removeObject:[self getPlacementID]];
- [UnityAds removeDelegate:self];
+ [[GADMAdapterUnitySingleton sharedInstance] stopTrackingDelegate:self];
}
#pragma mark Interstitial Methods
NSError *error = GADUnityErrorWithDescription(@"Game ID and Placement ID cannot be nil.");
[strongConnector adapter:self didFailAd:error];
return;
- } else if ([[GADMAdapterUnitySingleton sharedInstance].placementsInUse containsObject:_placementID]) {
- NSString *errorMsg = @"An ad is already loading for placement ID: ";
- errorMsg = [errorMsg stringByAppendingString:_placementID];
- NSError *error = GADUnityErrorWithDescription(errorMsg);
- [strongConnector adapter:self didFailAd:error];
- return;
}
- UnitySingletonCompletion completeBlock = ^(UnityAdsError *error, NSString *message) {
- if(error) {
- if (strongConnector) {
- NSError *errorWithDescription = GADUnityErrorWithDescription(message);
- [strongConnector adapter:self didFailAd:errorWithDescription];
- }
- [[GADMAdapterUnitySingleton sharedInstance].placementsInUse removeObject:[self getPlacementID]];
- return;
- }
-
- [[GADMAdapterUnitySingleton sharedInstance].placementsInUse addObject:[self getPlacementID]];
- [UnityAds addDelegate:self];
- [UnityAds load:[self getPlacementID]];
- };
-
- [[GADMAdapterUnitySingleton sharedInstance] initializeWithGameID:_gameID
- completeBlock:completeBlock];
+ [[GADMAdapterUnitySingleton sharedInstance] requestInterstitialAdWithDelegate:self];
}
- (void)presentInterstitialFromRootViewController:(UIViewController *)rootViewController {
- [[GADMAdapterUnitySingleton sharedInstance].placementsInUse removeObject:_placementID];
- [UnityAds show:rootViewController placementId:_placementID];
+ [_networkConnector adapterWillPresentInterstitial:self];
+ [[GADMAdapterUnitySingleton sharedInstance] presentInterstitialAdForViewController:rootViewController delegate:self];
}
#pragma mark Banner Methods
NSError *errorWithDescription = GADUnityErrorWithDescription(errorMsg);
[strongNetworkConnector adapter:self didFailAd:errorWithDescription];
}
- [[GADMAdapterUnitySingleton sharedInstance].placementsInUse removeObject:placementID];
}
}
}
if (state == kUnityAdsFinishStateCompleted) {
[strongNetworkConnector adapterDidDismissInterstitial:self];
} else if (state == kUnityAdsFinishStateError) {
- [strongNetworkConnector adapterWillPresentInterstitial:self];
[strongNetworkConnector adapterDidDismissInterstitial:self];
} else if (state == kUnityAdsFinishStateSkipped) {
[strongNetworkConnector adapterDidDismissInterstitial:self];
}
}
- [[GADMAdapterUnitySingleton sharedInstance].placementsInUse removeObject:placementID];
- [UnityAds removeDelegate:self];
}
}
}
- (void)unityAdsDidError:(UnityAdsError)error withMessage:(NSString *)message {
- //do nothing.
+ id<GADMAdNetworkConnector> strongNetworkConnector = _networkConnector;
+ if (strongNetworkConnector) {
+ if (error == kUnityAdsErrorNotInitialized) {
+ NSError *errorWithDescription = GADUnityErrorWithDescription(message);
+ [strongNetworkConnector adapter:self didFailAd:errorWithDescription];
+ } else {
+ [strongNetworkConnector adapterWillDismissInterstitial:self];
+ [strongNetworkConnector adapterDidDismissInterstitial:self];
+ }
+ }
}
- (void)unityAdsDidStart:(nonnull NSString *)placementID {
- id<GADMAdNetworkConnector> strongNetworkConnector = _networkConnector;
- if (strongNetworkConnector && [placementID isEqualToString:_placementID]) {
- [strongNetworkConnector adapterWillPresentInterstitial:self];
- }
+ //nothing to do
}
@end

MODIFY
adapters/Unity/UnityAdapter/GADMAdapterUnityBannerAd.m
adapters/Unity/UnityAdapter/GADMAdapterUnityBannerAd.m
if (![UnityAds isInitialized]) {
NSString *gameID = [strongConnector.credentials[kGADMAdapterUnityGameID] copy];
-
- UnitySingletonCompletion completeBlock = ^(UnityAdsError *error, NSString *message) {
- if(error) {
- if (strongConnector && strongAdapter) {
- [strongConnector adapter:strongAdapter didFailAd:GADUnityErrorWithDescription(message)];
- }
- return;
- }
- };
-
- [[GADMAdapterUnitySingleton sharedInstance] initializeWithGameID:gameID
- completeBlock:completeBlock];
+ [[GADMAdapterUnitySingleton sharedInstance] initializeWithGameID:gameID];
}
_placementID = [strongConnector.credentials[kGADMAdapterUnityPlacementID] copy];

MODIFY
adapters/Unity/UnityAdapter/GADMAdapterUnityRewardedAd.m
adapters/Unity/UnityAdapter/GADMAdapterUnityRewardedAd.m
_placementID = [_adConfiguration.credentials.settings objectForKey:kGADMAdapterUnityPlacementID];
NSLog(@"Requesting unity rewarded ad with placement: %@", _placementID);
+ GADMAdapterUnityRewardedAd __weak *weakSelf = self;
+
if (!_gameID || !_placementID) {
if (_adLoadCompletionHandler) {
NSError *error = GADUnityErrorWithDescription(@"Game ID and Placement ID cannot be nil.");
_adLoadCompletionHandler = nil;
}
return;
- } else if ([[GADMAdapterUnitySingleton sharedInstance].placementsInUse containsObject:_placementID]) {
- if (_adLoadCompletionHandler) {
- NSString *errorMsg = @"An ad is already loading for placement ID: ";
- errorMsg = [errorMsg stringByAppendingString:_placementID];
- NSError *error = GADUnityErrorWithDescription(errorMsg);
- _adLoadCompletionHandler(nil, error);
- _adLoadCompletionHandler = nil;
- }
- return;
}
if (![UnityAds isSupported]) {
}
return;
}
- GADMAdapterUnityRewardedAd *__weak weakSelf = self;
- UnitySingletonCompletion completeBlock = ^(UnityAdsError *error, NSString *message) {
- GADMAdapterUnityRewardedAd *strongSelf = weakSelf;
- if (!strongSelf) {
- [[GADMAdapterUnitySingleton sharedInstance].placementsInUse removeObject:[self getPlacementID]];
- return;
- }
- if (error) {
- NSError *errorWithDescription = GADUnityErrorWithDescription(message);
- strongSelf->_adLoadCompletionHandler(nil, errorWithDescription);
- [[GADMAdapterUnitySingleton sharedInstance].placementsInUse removeObject:[self getPlacementID]];
- return;
- }
-
- [[GADMAdapterUnitySingleton sharedInstance].placementsInUse addObject:[self getPlacementID]];
- [UnityAds addDelegate:strongSelf];
- [UnityAds load:[strongSelf getPlacementID]];
- };
-
- [[GADMAdapterUnitySingleton sharedInstance] initializeWithGameID:_gameID
- completeBlock:completeBlock];
+ [[GADMAdapterUnitySingleton sharedInstance] requestRewardedAdWithDelegate:weakSelf];
}
- (void)presentFromViewController:(nonnull UIViewController *)viewController {
- [[GADMAdapterUnitySingleton sharedInstance].placementsInUse removeObject:_placementID];
- [UnityAds show:viewController placementId:_placementID];
id<GADMediationRewardedAdEventDelegate> strongDelegate = _adEventDelegate;
if (strongDelegate) {
[strongDelegate willPresentFullScreenView];
}
+ [[GADMAdapterUnitySingleton sharedInstance] presentRewardedAdForViewController:viewController delegate:self];
}
#pragma mark GADMAdapterUnityDataProvider Methods
#pragma mark - Unity Delegate Methods
- (void)unityAdsDidError:(UnityAdsError)error withMessage:(nonnull NSString *)message {
- //do nothing.
+ if (error == kUnityAdsErrorNotInitialized) {
+ if (_adLoadCompletionHandler) {
+ NSError *errorWithDescription = GADUnityErrorWithDescription(message);
+ _adLoadCompletionHandler(nil, errorWithDescription);
+ _adLoadCompletionHandler = nil;
+ }
+ } else {
+ if (_adEventDelegate) {
+ NSError *errorWithDescription = GADUnityErrorWithDescription(message);
+ [_adEventDelegate didFailToPresentWithError:errorWithDescription];
+ }
+ }
}
- (void)unityAdsDidFinish:(nonnull NSString *)placementID
NSError *presentError = GADUnityErrorWithDescription(@"Finish State Error");
[strongDelegate didFailToPresentWithError:presentError];
}
+ [strongDelegate willDismissFullScreenView];
[strongDelegate didDismissFullScreenView];
}
- [[GADMAdapterUnitySingleton sharedInstance].placementsInUse removeObject:placementID];
- [UnityAds removeDelegate:self];
}
}
NSError *errorWithDescription = GADUnityErrorWithDescription(errorMsg);
_adLoadCompletionHandler(nil, errorWithDescription);
}
- [[GADMAdapterUnitySingleton sharedInstance].placementsInUse removeObject:placementID];
}
}
}

MODIFY
adapters/Unity/UnityAdapter/GADMAdapterUnitySingleton.h
adapters/Unity/UnityAdapter/GADMAdapterUnitySingleton.h
#import "GADMAdapterUnityProtocol.h"
-typedef void (^UnitySingletonCompletion)(UnityAdsError *error, NSString *message);
-
@interface GADMAdapterUnitySingleton : NSObject
-@property (nonatomic, strong) UnitySingletonCompletion completeBlock;
-@property NSMutableSet<NSString*>* placementsInUse;
-
/// Shared instance.
+ (instancetype)sharedInstance;
/// Configures a reward-based video ad with provided |gameID| and |adapterDelegate| and returns
/// YES if successful; otherwise returns NO.
-- (void)initializeWithGameID:(NSString *)gameID
- completeBlock:(UnitySingletonCompletion)completeBlock;
+- (void)initializeWithGameID:(NSString *)gameID;
+
+/// Requests a reward-based video ad with |adapterDelegate|.
+- (void)requestRewardedAdWithDelegate:
+(id<GADMAdapterUnityDataProvider, UnityAdsExtendedDelegate>)adapterDelegate;
+
+/// Presents a reward-based video ad for |viewController| with |adapterDelegate|.
+- (void)presentRewardedAdForViewController:(UIViewController *)viewController
+ delegate:
+(id<GADMAdapterUnityDataProvider, UnityAdsExtendedDelegate>)
+adapterDelegate;
+
+/// Configures an interstitial ad with provided |gameID| and |adapterDelegate|.
+- (void)requestInterstitialAdWithDelegate:
+(id<GADMAdapterUnityDataProvider, UnityAdsExtendedDelegate>)adapterDelegate;
+
+/// Presents an interstitial ad for |viewController| with |adapterDelegate|.
+- (void)presentInterstitialAdForViewController:(UIViewController *)viewController
+ delegate:(id<GADMAdapterUnityDataProvider,
+ UnityAdsExtendedDelegate>)adapterDelegate;
+
+/// Tells the adapter to remove itself as a |adapterDelegate|.
+- (void)stopTrackingDelegate:
+(id<GADMAdapterUnityDataProvider, UnityAdsExtendedDelegate>)adapterDelegate;
@end

MODIFY
adapters/Unity/UnityAdapter/GADMAdapterUnitySingleton.m
adapters/Unity/UnityAdapter/GADMAdapterUnitySingleton.m
#import "GADMAdapterUnityConstants.h"
#import "GADMAdapterUnityUtils.h"
-@interface GADMAdapterUnitySingleton () <UnityAdsExtendedDelegate>
+@interface GADMAdapterUnitySingleton () <UnityAdsExtendedDelegate> {
+ /// Array to hold all adapter delegates.
+ NSMapTable *_adapterDelegates;
+
+ /// Connector from unity adapter to send Unity callbacks.
+ __weak id<GADMAdapterUnityDataProvider, UnityAdsExtendedDelegate> _currentShowingUnityDelegate;
+}
@end
- (id)init {
self = [super init];
if (self) {
- self.placementsInUse = [[NSMutableSet alloc] init];
+ _adapterDelegates = [NSMapTable mapTableWithKeyOptions:NSMapTableStrongMemory
+ valueOptions:NSMapTableWeakMemory];
}
return self;
}
-- (void)initializeWithGameID:(NSString *)gameID
- completeBlock:(UnitySingletonCompletion)completeBlock{
+- (void)initializeWithGameID:(NSString *)gameID {
if ([UnityAds isInitialized]) {
- completeBlock(nil, @"UnityAds Initialization Succeeded");
return;
}
- self.completeBlock = completeBlock;
-
+ // Metadata needed by Unity Ads SDK before initialization.
UADSMediationMetaData *mediationMetaData = [[UADSMediationMetaData alloc] init];
[mediationMetaData setName:kGADMAdapterUnityMediationNetworkName];
[mediationMetaData setVersion:kGADMAdapterUnityVersion];
[mediationMetaData set:@"adapter_version" value:[UnityAds getVersion]];
[mediationMetaData commit];
+ // Initializing Unity Ads with |gameID|.
[UnityAds addDelegate:self];
- [UnityAds initialize:gameID testMode:false enablePerPlacementLoad:true];
+ [UnityAds initialize:gameID testMode:NO enablePerPlacementLoad:YES];
+}
+
+- (void)addAdapterDelegate:
+ (id<GADMAdapterUnityDataProvider, UnityAdsExtendedDelegate>)adapterDelegate {
+ @synchronized(_adapterDelegates) {
+ [_adapterDelegates setObject:adapterDelegate forKey:[adapterDelegate getPlacementID]];
+ }
+}
+
+#pragma mark - Rewardbased video ad methods
+
+- (void)requestRewardedAdWithDelegate:
+ (id<GADMAdapterUnityDataProvider, UnityAdsExtendedDelegate>)adapterDelegate {
+ NSString *gameID = [adapterDelegate getGameID];
+ NSString *placementID = [adapterDelegate getPlacementID];
+
+ @synchronized(_adapterDelegates) {
+ if ([_adapterDelegates objectForKey:placementID]) {
+ NSString *message = @"An ad is already loading for placement ID %@";
+ [adapterDelegate unityAdsDidError:kUnityAdsErrorInternalError
+ withMessage:[NSString stringWithFormat:message, placementID]];
+ return;
+ }
+ }
+
+ [self addAdapterDelegate:adapterDelegate];
+
+ if (![UnityAds isInitialized]) {
+ [self initializeWithGameID:gameID];
+ }
+
+ [UnityAds load:placementID];
+}
+
+- (void)presentRewardedAdForViewController:(UIViewController *)viewController
+ delegate:
+ (id<GADMAdapterUnityDataProvider, UnityAdsExtendedDelegate>)
+ adapterDelegate {
+ _currentShowingUnityDelegate = adapterDelegate;
+
+ NSString *placementID = [adapterDelegate getPlacementID];
+ [UnityAds show:viewController placementId:placementID];
+}
+
+#pragma mark - Interstitial ad methods
+
+- (void)requestInterstitialAdWithDelegate:
+ (id<GADMAdapterUnityDataProvider, UnityAdsExtendedDelegate>)adapterDelegate {
+ NSString *gameID = [adapterDelegate getGameID];
+ NSString *placementID = [adapterDelegate getPlacementID];
+
+ @synchronized(_adapterDelegates) {
+ if ([_adapterDelegates objectForKey:placementID]) {
+ NSString *message = @"An ad is already loading for placement ID %@";
+ [adapterDelegate unityAdsDidError:kUnityAdsErrorInternalError
+ withMessage:[NSString stringWithFormat:message, placementID]];
+ return;
+ }
+ }
+
+ [self addAdapterDelegate:adapterDelegate];
+ if (![UnityAds isInitialized]) {
+ [self initializeWithGameID:gameID];
+ }
+
+ [UnityAds load:placementID];
+}
+
+- (void)presentInterstitialAdForViewController:(UIViewController *)viewController
+ delegate:(id<GADMAdapterUnityDataProvider,
+ UnityAdsExtendedDelegate>)adapterDelegate {
+ _currentShowingUnityDelegate = adapterDelegate;
+
+ NSString *placementID = [adapterDelegate getPlacementID];
+ [UnityAds show:viewController placementId:placementID];
}
#pragma mark - Unity Delegate Methods
- (void)unityAdsPlacementStateChanged:(NSString *)placementId
oldState:(UnityAdsPlacementState)oldState
newState:(UnityAdsPlacementState)newState {
- if ((newState == kUnityAdsPlacementStateWaiting || newState == kUnityAdsPlacementStateReady) && self.completeBlock) {
- self.completeBlock(nil, @"UnityAds Initialization Succeeded");
- self.completeBlock = nil;
- }
+ id<GADMAdapterUnityDataProvider, UnityAdsExtendedDelegate> adapterDelegate;
+ @synchronized(_adapterDelegates) {
+ adapterDelegate = [_adapterDelegates objectForKey:placementId];
}
-- (void)unityAdsDidError:(UnityAdsError)error withMessage:(NSString *)message {
- if (error == kUnityAdsErrorNotInitialized || error == kUnityAdsErrorInvalidArgument || error == kUnityAdsErrorInitializedFailed || error == kUnityAdsErrorInitSanityCheckFail) {
- if (self.completeBlock) {
- self.completeBlock(&error, @"Unity Ads Initialization Failed");
- self.completeBlock = nil;
- }
+ if (adapterDelegate) {
+ [adapterDelegate unityAdsPlacementStateChanged:placementId oldState:oldState newState:newState];
}
- return;
}
- (void)unityAdsDidFinish:(NSString *)placementID withFinishState:(UnityAdsFinishState)state {
+ @synchronized(_adapterDelegates) {
+ GADMAdapterUnityMapTableRemoveObjectForKey(_adapterDelegates, placementID);
+ }
+ [_currentShowingUnityDelegate unityAdsDidFinish:placementID withFinishState:state];
}
- (void)unityAdsDidStart:(NSString *)placementID {
+ [_currentShowingUnityDelegate unityAdsDidStart:placementID];
}
- (void)unityAdsReady:(NSString *)placementID {
+ id<GADMAdapterUnityDataProvider, UnityAdsExtendedDelegate> adapterDelegate;
+ @synchronized(_adapterDelegates) {
+ adapterDelegate = [_adapterDelegates objectForKey:placementID];
+ }
+
+ if (adapterDelegate) {
+ [adapterDelegate unityAdsReady:placementID];
+ }
}
- (void)unityAdsDidClick:(NSString *)placementID {
+ [_currentShowingUnityDelegate unityAdsDidClick:placementID];
+}
+
+- (void)unityAdsDidError:(UnityAdsError)error withMessage:(NSString *)message {
+ if (error == kUnityAdsErrorInitSanityCheckFail || error == kUnityAdsErrorNotInitialized || error == kUnityAdsErrorInvalidArgument ||
+ error == kUnityAdsErrorInitializedFailed || error == kUnityAdsErrorAdBlockerDetected) {
+ NSArray *delegates;
+ @synchronized(_adapterDelegates) {
+ delegates = _adapterDelegates.objectEnumerator.allObjects;
+ }
+
+ for (id<UnityAdsExtendedDelegate, UnityAdsExtendedDelegate> delegate in delegates) {
+ [delegate unityAdsDidError:kUnityAdsErrorNotInitialized withMessage:message];
+ }
+
+ @synchronized(_adapterDelegates) {
+ [_adapterDelegates removeAllObjects];
+ }
+ } else {
+ [_currentShowingUnityDelegate unityAdsDidError:error withMessage:message];
+ }
+}
+
+- (void)stopTrackingDelegate:
+ (id<GADMAdapterUnityDataProvider, UnityAdsExtendedDelegate>)adapterDelegate {
+ GADMAdapterUnityMapTableRemoveObjectForKey(_adapterDelegates, [adapterDelegate getPlacementID]);
}
@end

Refactoring

Code refactoring to address comments