1027 строки
40 KiB
Objective-C
1027 строки
40 KiB
Objective-C
//
|
|
// ALLineMediationAdapter.h
|
|
// AppLovinSDK
|
|
//
|
|
// Copyright © 2022 AppLovin Corporation. All rights reserved.
|
|
//
|
|
|
|
#import "ALLineMediationAdapter.h"
|
|
#import <FiveAd/FiveAd.h>
|
|
|
|
#define ADAPTER_VERSION @"2.4.20211028.3"
|
|
|
|
@interface ALLineMediationAdapterInterstitialAdDelegate : NSObject<FADLoadDelegate, FADAdViewEventListener>
|
|
@property (nonatomic, weak) ALLineMediationAdapter *parentAdapter;
|
|
@property (nonatomic, strong) id<MAInterstitialAdapterDelegate> delegate;
|
|
- (instancetype)initWithParentAdapter:(ALLineMediationAdapter *)parentAdapter andNotify:(id<MAInterstitialAdapterDelegate>)delegate;
|
|
@end
|
|
|
|
@interface ALLineMediationAdapterRewardedAdDelegate : NSObject<FADLoadDelegate, FADAdViewEventListener>
|
|
@property (nonatomic, weak) ALLineMediationAdapter *parentAdapter;
|
|
@property (nonatomic, strong) id<MARewardedAdapterDelegate> delegate;
|
|
@property (nonatomic, assign, getter=hasGrantedReward) BOOL grantedReward;
|
|
- (instancetype)initWithParentAdapter:(ALLineMediationAdapter *)parentAdapter andNotify:(id<MARewardedAdapterDelegate>)delegate;
|
|
@end
|
|
|
|
@interface ALLineMediationAdapterAdViewDelegate : NSObject<FADLoadDelegate, FADAdViewEventListener>
|
|
@property (nonatomic, weak) ALLineMediationAdapter *parentAdapter;
|
|
@property (nonatomic, strong) id<MAAdViewAdapterDelegate> delegate;
|
|
@property (nonatomic, strong) MAAdFormat *adFormat;
|
|
- (instancetype)initWithParentAdapter:(ALLineMediationAdapter *)parentAdapter adFormat:(MAAdFormat *)adFormat andNotify:(id<MAAdViewAdapterDelegate>)delegate;
|
|
@end
|
|
|
|
@interface ALLineMediationAdapterNativeAdViewDelegate : NSObject<FADLoadDelegate, FADAdViewEventListener>
|
|
@property (nonatomic, weak) ALLineMediationAdapter *parentAdapter;
|
|
@property (nonatomic, strong) id<MAAdViewAdapterDelegate> delegate;
|
|
@property (nonatomic, strong) MAAdFormat *adFormat;
|
|
@property (nonatomic, strong) NSDictionary<NSString *, id> *serverParameters;
|
|
- (instancetype)initWithParentAdapter:(ALLineMediationAdapter *)parentAdapter adFormat:(MAAdFormat *)adFormat serverParameters:(NSDictionary<NSString *, id> *)serverParameters andNotify:(id<MAAdViewAdapterDelegate>)delegate;
|
|
@end
|
|
|
|
@interface ALLineMediationAdapterNativeAdDelegate : NSObject<FADLoadDelegate, FADAdViewEventListener>
|
|
@property (nonatomic, weak) ALLineMediationAdapter *parentAdapter;
|
|
@property (nonatomic, strong) id<MANativeAdAdapterDelegate> delegate;
|
|
@property (nonatomic, strong) NSDictionary<NSString *, id> *serverParameters;
|
|
- (instancetype)initWithParentAdapter:(ALLineMediationAdapter *)parentAdapter serverParameters:(NSDictionary<NSString *, id> *)serverParameters andNotify:(id<MANativeAdAdapterDelegate>)delegate;
|
|
@end
|
|
|
|
@interface MALineNativeAd : MANativeAd
|
|
@property (nonatomic, weak) ALLineMediationAdapter *parentAdapter;
|
|
- (instancetype)initWithParentAdapter:(ALLineMediationAdapter *)parentAdapter builderBlock:(NS_NOESCAPE MANativeAdBuilderBlock)builderBlock;
|
|
- (instancetype)initWithFormat:(MAAdFormat *)format builderBlock:(NS_NOESCAPE MANativeAdBuilderBlock)builderBlock NS_UNAVAILABLE;
|
|
@end
|
|
|
|
@interface ALLineMediationAdapter()
|
|
|
|
// Interstitial
|
|
@property (nonatomic, strong) ALLineMediationAdapterInterstitialAdDelegate *interstitialDelegate;
|
|
@property (nonatomic, strong) FADInterstitial *interstitialAd;
|
|
|
|
// Rewarded
|
|
@property (nonatomic, strong) ALLineMediationAdapterRewardedAdDelegate *rewardedDelegate;
|
|
@property (nonatomic, strong) FADVideoReward *rewardedAd;
|
|
|
|
// AdView
|
|
@property (nonatomic, strong) ALLineMediationAdapterAdViewDelegate *adViewDelegate;
|
|
@property (nonatomic, strong) ALLineMediationAdapterNativeAdViewDelegate *nativeAdViewDelegate;
|
|
@property (nonatomic, strong) FADAdViewCustomLayout *adView;
|
|
|
|
// Native
|
|
@property (nonatomic, strong) ALLineMediationAdapterNativeAdDelegate *nativeAdDelegate;
|
|
@property (nonatomic, strong) FADNative *nativeAd;
|
|
@end
|
|
|
|
@implementation ALLineMediationAdapter
|
|
|
|
static ALAtomicBoolean *ALLineInitialized;
|
|
|
|
+ (void)initialize
|
|
{
|
|
[super initialize];
|
|
|
|
ALLineInitialized = [[ALAtomicBoolean alloc] init];
|
|
}
|
|
|
|
#pragma mark - MAAdapter Methods
|
|
|
|
- (NSString *)SDKVersion
|
|
{
|
|
return [FADSettings semanticVersion];
|
|
}
|
|
|
|
- (NSString *)adapterVersion
|
|
{
|
|
return ADAPTER_VERSION;
|
|
}
|
|
|
|
- (void)initializeWithParameters:(id<MAAdapterInitializationParameters>)parameters completionHandler:(void (^)(MAAdapterInitializationStatus, NSString *_Nullable))completionHandler
|
|
{
|
|
if ( [ALLineInitialized compareAndSet: NO update: YES] )
|
|
{
|
|
NSString *appId = [parameters.serverParameters al_stringForKey: @"app_id"];
|
|
[self log: @"Initializing Line SDK with app id: %@...", appId];
|
|
|
|
FADConfig *config = [[FADConfig alloc] initWithAppId: appId];
|
|
[config setIsTest: [parameters isTesting]];
|
|
|
|
NSDictionary<NSString *, id> *serverParameters = parameters.serverParameters;
|
|
// Overwritten by `mute_state` setting, unless `mute_state` is disabled
|
|
if ( [serverParameters al_containsValueForKey: @"is_muted"] )
|
|
{
|
|
BOOL muted = [serverParameters al_numberForKey: @"is_muted"].boolValue;
|
|
[config enableSoundByDefault: !muted];
|
|
}
|
|
|
|
//
|
|
// GDPR options
|
|
//
|
|
if ( self.sdk.configuration.consentDialogState == ALConsentDialogStateApplies )
|
|
{
|
|
NSNumber *hasUserConsent = [self privacySettingForSelector: @selector(hasUserConsent) fromParameters: parameters];
|
|
if ( hasUserConsent )
|
|
{
|
|
config.needGdprNonPersonalizedAdsTreatment = hasUserConsent.boolValue ? kFADNeedGdprNonPersonalizedAdsTreatmentFalse : kFADNeedGdprNonPersonalizedAdsTreatmentTrue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// COPPA options
|
|
//
|
|
NSNumber *isAgeRestrictedUser = [self privacySettingForSelector: @selector(isAgeRestrictedUser) fromParameters: parameters];
|
|
if ( isAgeRestrictedUser )
|
|
{
|
|
config.needChildDirectedTreatment = isAgeRestrictedUser.boolValue ? kFADNeedChildDirectedTreatmentTrue : kFADNeedChildDirectedTreatmentFalse;
|
|
}
|
|
|
|
[FADSettings registerConfig: config];
|
|
completionHandler(MAAdapterInitializationStatusInitializedUnknown, nil);
|
|
}
|
|
else
|
|
{
|
|
if ( [FADSettings isConfigRegistered] )
|
|
{
|
|
[self log: @"Line SDK is already initialized"];
|
|
completionHandler(MAAdapterInitializationStatusInitializedUnknown, nil);
|
|
}
|
|
else
|
|
{
|
|
[self log: @"Line SDK still initializing"];
|
|
completionHandler(MAAdapterInitializationStatusInitializing, nil);
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)destroy
|
|
{
|
|
self.interstitialAd = nil;
|
|
self.interstitialDelegate = nil;
|
|
|
|
self.rewardedAd = nil;
|
|
self.rewardedDelegate = nil;
|
|
|
|
self.adView = nil;
|
|
self.adViewDelegate = nil;
|
|
self.nativeAdViewDelegate = nil;
|
|
|
|
self.nativeAd = nil;
|
|
self.nativeAdDelegate = nil;
|
|
}
|
|
|
|
#pragma mark - MAInterstitialAdapter Methods
|
|
|
|
- (void)loadInterstitialAdForParameters:(id<MAAdapterResponseParameters>)parameters andNotify:(id<MAInterstitialAdapterDelegate>)delegate
|
|
{
|
|
NSString *slotId = parameters.thirdPartyAdPlacementIdentifier;
|
|
[self log: @"Loading interstitial ad for slot id: %@...", slotId];
|
|
|
|
self.interstitialDelegate = [[ALLineMediationAdapterInterstitialAdDelegate alloc] initWithParentAdapter: self andNotify: delegate];
|
|
self.interstitialAd = [[FADInterstitial alloc] initWithSlotId: slotId];
|
|
[self.interstitialAd setLoadDelegate: self.interstitialDelegate];
|
|
[self.interstitialAd setAdViewEventListener: self.interstitialDelegate];
|
|
|
|
[self.interstitialAd loadAdAsync];
|
|
}
|
|
|
|
- (void)showInterstitialAdForParameters:(id<MAAdapterResponseParameters>)parameters andNotify:(id<MAInterstitialAdapterDelegate>)delegate
|
|
{
|
|
NSString *slotId = parameters.thirdPartyAdPlacementIdentifier;
|
|
[self log: @"Showing interstitial ad for slot id: %@...", slotId];
|
|
|
|
[self.interstitialAd show];
|
|
}
|
|
|
|
#pragma mark - MARewardedAdapter Methods
|
|
|
|
- (void)loadRewardedAdForParameters:(id<MAAdapterResponseParameters>)parameters andNotify:(id<MARewardedAdapterDelegate>)delegate
|
|
{
|
|
NSString *slotId = parameters.thirdPartyAdPlacementIdentifier;
|
|
[self log: @"Loading rewarded ad for slot id: %@...", slotId];
|
|
|
|
self.rewardedDelegate = [[ALLineMediationAdapterRewardedAdDelegate alloc] initWithParentAdapter: self andNotify: delegate];
|
|
self.rewardedAd = [[FADVideoReward alloc] initWithSlotId: slotId];
|
|
[self.rewardedAd setLoadDelegate: self.rewardedDelegate];
|
|
[self.rewardedAd setAdViewEventListener: self.rewardedDelegate];
|
|
|
|
[self.rewardedAd loadAdAsync];
|
|
}
|
|
|
|
- (void)showRewardedAdForParameters:(id<MAAdapterResponseParameters>)parameters andNotify:(id<MARewardedAdapterDelegate>)delegate
|
|
{
|
|
NSString *slotId = parameters.thirdPartyAdPlacementIdentifier;
|
|
[self log: @"Showing rewarded ad for slot id: %@...", slotId];
|
|
|
|
[self configureRewardForParameters: parameters];
|
|
[self.rewardedAd show];
|
|
}
|
|
|
|
#pragma mark - MAAdViewAdapter Methods
|
|
|
|
- (void)loadAdViewAdForParameters:(id<MAAdapterResponseParameters>)parameters adFormat:(MAAdFormat *)adFormat andNotify:(id<MAAdViewAdapterDelegate>)delegate
|
|
{
|
|
BOOL isNative = [parameters.serverParameters al_boolForKey: @"is_native"];
|
|
NSString *slotId = parameters.thirdPartyAdPlacementIdentifier;
|
|
|
|
[self log: @"Loading %@%@ ad for slot id: %@...", isNative ? @"native " : @"", adFormat.label, slotId];
|
|
|
|
dispatchOnMainQueue(^{
|
|
|
|
if ( isNative )
|
|
{
|
|
self.nativeAdViewDelegate = [[ALLineMediationAdapterNativeAdViewDelegate alloc] initWithParentAdapter: self
|
|
adFormat: adFormat
|
|
serverParameters: parameters.serverParameters
|
|
andNotify: delegate];
|
|
self.nativeAd = [[FADNative alloc] initWithSlotId: slotId videoViewWidth: CGRectGetWidth([UIScreen mainScreen].bounds)];
|
|
[self.nativeAd setLoadDelegate: self.nativeAdViewDelegate];
|
|
[self.nativeAd setAdViewEventListener: self.nativeAdViewDelegate];
|
|
|
|
// We always want to mute banners and MRECs
|
|
[self.nativeAd enableSound: NO];
|
|
|
|
[self.nativeAd loadAdAsync];
|
|
}
|
|
else
|
|
{
|
|
self.adViewDelegate = [[ALLineMediationAdapterAdViewDelegate alloc] initWithParentAdapter: self adFormat: adFormat andNotify: delegate];
|
|
self.adViewDelegate = [[ALLineMediationAdapterAdViewDelegate alloc] initWithParentAdapter: self
|
|
adFormat: adFormat
|
|
andNotify: delegate];
|
|
self.adView = [[FADAdViewCustomLayout alloc] initWithSlotId: slotId width: CGRectGetWidth([UIScreen mainScreen].bounds)];
|
|
[self.adView setLoadDelegate: self.adViewDelegate];
|
|
[self.adView setAdViewEventListener: self.adViewDelegate];
|
|
self.adView.frame = CGRectMake(0, 0, adFormat.size.width, adFormat.size.height);
|
|
|
|
// We always want to mute banners and MRECs
|
|
[self.adView enableSound: NO];
|
|
|
|
[self.adView loadAdAsync];
|
|
}
|
|
});
|
|
}
|
|
|
|
#pragma mark - MANativeAdAdapter Methods
|
|
|
|
- (void)loadNativeAdForParameters:(id<MAAdapterResponseParameters>)parameters andNotify:(id<MANativeAdAdapterDelegate>)delegate
|
|
{
|
|
NSString *slotId = parameters.thirdPartyAdPlacementIdentifier;
|
|
[self log: @"Loading native ad for slot id: %@...", slotId];
|
|
|
|
self.nativeAdDelegate = [[ALLineMediationAdapterNativeAdDelegate alloc] initWithParentAdapter: self
|
|
serverParameters: parameters.serverParameters
|
|
andNotify: delegate];
|
|
dispatchOnMainQueue(^{
|
|
|
|
self.nativeAd = [[FADNative alloc] initWithSlotId: slotId videoViewWidth: CGRectGetWidth([UIScreen mainScreen].bounds)];
|
|
[self.nativeAd setLoadDelegate: self.nativeAdDelegate];
|
|
[self.nativeAd setAdViewEventListener: self.nativeAdDelegate];
|
|
|
|
// We always want to mute banners and MRECs
|
|
[self.nativeAd enableSound: NO];
|
|
|
|
[self.nativeAd loadAdAsync];
|
|
});
|
|
}
|
|
|
|
#pragma mark - Helper Methods
|
|
|
|
+ (MAAdapterError *)toMaxError:(FADErrorCode)lineAdsErrorCode
|
|
{
|
|
MAAdapterError *adapterError = MAAdapterError.unspecified;
|
|
NSString *thirdPartySdkErrorMessage;
|
|
switch ( lineAdsErrorCode )
|
|
{
|
|
case kFADErrorNetworkError:
|
|
adapterError = MAAdapterError.noConnection;
|
|
thirdPartySdkErrorMessage = @"Please try again in a stable network environment.";
|
|
break;
|
|
case kFADErrorCodeNoAd:
|
|
adapterError = MAAdapterError.noFill;
|
|
thirdPartySdkErrorMessage = @"Ad was not ready at display time. Please try again.";
|
|
break;
|
|
case kFADErrorBadAppId:
|
|
adapterError = MAAdapterError.invalidConfiguration;
|
|
thirdPartySdkErrorMessage = @"Check if the OS type, PackageName, and issued AppID registered in FIVE Dashboard and the application settings match. Please be careful about blanks.";
|
|
break;
|
|
case kFADErrorStorageError:
|
|
adapterError = MAAdapterError.unspecified;
|
|
thirdPartySdkErrorMessage = @"There is a problem with the device storage. Please try again with another device.";
|
|
break;
|
|
case kFADErrorInternalError:
|
|
adapterError = MAAdapterError.internalError;
|
|
thirdPartySdkErrorMessage = @"Please contact us.";
|
|
break;
|
|
case kFADErrorInvalidState:
|
|
adapterError = MAAdapterError.invalidLoadState;
|
|
thirdPartySdkErrorMessage = @"There is a problem with the implementation. Please check the following. Whether the initialization process ([FADSettings registerConfig: config]) is executed before the creation of the ad object or loadAdAsync. Are you calling loadAdAsync multiple times for one ad object?";
|
|
break;
|
|
case kFADErrorBadSlotId:
|
|
adapterError = MAAdapterError.invalidConfiguration;
|
|
thirdPartySdkErrorMessage = @"Make sure you are using the SlotID issued on the FIVE Dashboard.";
|
|
break;
|
|
case kFADErrorSuppressed:
|
|
case kFADErrorPlayerError:
|
|
case kFADErrorNone:
|
|
adapterError = MAAdapterError.unspecified;
|
|
thirdPartySdkErrorMessage = @"Please contact us.";
|
|
break;
|
|
}
|
|
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
return [MAAdapterError errorWithCode: adapterError.errorCode
|
|
errorString: adapterError.errorMessage
|
|
thirdPartySdkErrorCode: lineAdsErrorCode
|
|
thirdPartySdkErrorMessage: thirdPartySdkErrorMessage];
|
|
#pragma clang diagnostic pop
|
|
}
|
|
|
|
- (nullable NSNumber *)privacySettingForSelector:(SEL)selector fromParameters:(id<MAAdapterParameters>)parameters
|
|
{
|
|
// Use reflection because compiled adapters have trouble fetching `BOOL` from old SDKs and `NSNumber` from new SDKs (above 6.14.0)
|
|
NSMethodSignature *signature = [[parameters class] instanceMethodSignatureForSelector: selector];
|
|
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature: signature];
|
|
[invocation setSelector: selector];
|
|
[invocation setTarget: parameters];
|
|
[invocation invoke];
|
|
|
|
// Privacy parameters return nullable `NSNumber` on newer SDKs
|
|
if ( ALSdk.versionCode >= 6140000 )
|
|
{
|
|
NSNumber *__unsafe_unretained value;
|
|
[invocation getReturnValue: &value];
|
|
|
|
return value;
|
|
}
|
|
// Privacy parameters return BOOL on older SDKs
|
|
else
|
|
{
|
|
BOOL rawValue;
|
|
[invocation getReturnValue: &rawValue];
|
|
|
|
return @(rawValue);
|
|
}
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation ALLineMediationAdapterInterstitialAdDelegate
|
|
|
|
- (instancetype)initWithParentAdapter:(ALLineMediationAdapter *)parentAdapter andNotify:(id<MAInterstitialAdapterDelegate>)delegate
|
|
{
|
|
self = [super init];
|
|
if ( self )
|
|
{
|
|
self.parentAdapter = parentAdapter;
|
|
self.delegate = delegate;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)fiveAdDidLoad:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Interstitial ad loaded for slot id: %@...", ad.slotId];
|
|
[self.delegate didLoadInterstitialAd];
|
|
}
|
|
|
|
- (void)fiveAd:(id<FADAdInterface>)ad didFailedToReceiveAdWithError:(FADErrorCode)errorCode
|
|
{
|
|
[self.parentAdapter log: @"Interstitial ad failed to load for slot id: %@ with error: %ld", ad.slotId, errorCode];
|
|
MAAdapterError *error = [ALLineMediationAdapter toMaxError: errorCode];
|
|
[self.delegate didFailToLoadInterstitialAdWithError: error];
|
|
}
|
|
|
|
- (void)fiveAd:(id<FADAdInterface>)ad didFailedToShowAdWithError:(FADErrorCode)errorCode
|
|
{
|
|
[self.parentAdapter log: @"Interstitial ad failed to show for slot id: %@ with error: %ld", ad.slotId, errorCode];
|
|
MAAdapterError *error = [MAAdapterError errorWithCode: -4205 errorString: @"Ad Display Failed" thirdPartySdkErrorCode: errorCode thirdPartySdkErrorMessage: @""];
|
|
[self.delegate didFailToDisplayInterstitialAdWithError: error];
|
|
}
|
|
|
|
- (void)fiveAdDidImpression:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Interstitial ad impression tracked for slot id: %@...", ad.slotId];
|
|
[self.delegate didDisplayInterstitialAd];
|
|
}
|
|
|
|
- (void)fiveAdDidClick:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Interstitial ad clicked for slot id: %@...", ad.slotId];
|
|
[self.delegate didClickInterstitialAd];
|
|
}
|
|
|
|
- (void)fiveAdDidStart:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Interstitial ad shown for slot id: %@...", ad.slotId];
|
|
|
|
// NOTE: Called for video-only interstitial ads.
|
|
[self.delegate didDisplayInterstitialAd];
|
|
}
|
|
|
|
- (void)fiveAdDidClose:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Interstitial ad hidden for slot id: %@...", ad.slotId];
|
|
[self.delegate didHideInterstitialAd];
|
|
}
|
|
|
|
- (void)fiveAdDidPause:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Interstitial ad did pause for slot id: %@...", ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidResume:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Interstitial ad did resume for slot id: %@...", ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidViewThrough:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Interstitial ad completed for slot id: %@...", ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidReplay:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Interstitial ad did replay for slot id: %@...", ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidStall:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Interstitial ad did stall for slot id: %@...", ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidRecover:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Interstitial ad did recover for slot id: %@...", ad.slotId];
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation ALLineMediationAdapterRewardedAdDelegate
|
|
|
|
- (instancetype)initWithParentAdapter:(ALLineMediationAdapter *)parentAdapter andNotify:(id<MARewardedAdapterDelegate>)delegate
|
|
{
|
|
self = [super init];
|
|
if ( self )
|
|
{
|
|
self.parentAdapter = parentAdapter;
|
|
self.delegate = delegate;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)fiveAdDidLoad:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Rewarded ad loaded for slot id: %@...", ad.slotId];
|
|
[self.delegate didLoadRewardedAd];
|
|
}
|
|
|
|
- (void)fiveAd:(id<FADAdInterface>)ad didFailedToReceiveAdWithError:(FADErrorCode)errorCode
|
|
{
|
|
[self.parentAdapter log: @"Rewarded ad failed to load for slot id: %@ with error: %ld", ad.slotId, errorCode];
|
|
MAAdapterError *error = [ALLineMediationAdapter toMaxError: errorCode];
|
|
[self.delegate didFailToLoadRewardedAdWithError: error];
|
|
}
|
|
|
|
- (void)fiveAd:(id<FADAdInterface>)ad didFailedToShowAdWithError:(FADErrorCode)errorCode
|
|
{
|
|
[self.parentAdapter log: @"Rewarded ad failed to show for slot id: %@ with error: %ld", ad.slotId, errorCode];
|
|
MAAdapterError *error = [MAAdapterError errorWithCode: -4205 errorString: @"Ad Display Failed" thirdPartySdkErrorCode: errorCode thirdPartySdkErrorMessage: @""];
|
|
[self.delegate didFailToDisplayRewardedAdWithError: error];
|
|
}
|
|
|
|
- (void)fiveAdDidImpression:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Rewarded ad impression tracked for slot id: %@...", ad.slotId];
|
|
[self.delegate didDisplayRewardedAd];
|
|
[self.delegate didStartRewardedAdVideo];
|
|
}
|
|
|
|
- (void)fiveAdDidClick:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Rewarded ad clicked for slot id: %@...", ad.slotId];
|
|
[self.delegate didClickRewardedAd];
|
|
}
|
|
|
|
- (void)fiveAdDidClose:(id<FADAdInterface>)ad
|
|
{
|
|
if ( ad.state != kFADStateError )
|
|
{
|
|
if ( [self hasGrantedReward] || [self.parentAdapter shouldAlwaysRewardUser] )
|
|
{
|
|
MAReward *reward = self.parentAdapter.reward;
|
|
|
|
[self.parentAdapter log: @"Rewarded ad user with reward: %@ for slot id: %@...", reward, ad.slotId];
|
|
[self.delegate didRewardUserWithReward: reward];
|
|
}
|
|
}
|
|
[self.parentAdapter log: @"Rewarded ad hidden for slot id: %@...", ad.slotId];
|
|
[self.delegate didHideRewardedAd];
|
|
}
|
|
|
|
- (void)fiveAdDidStart:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Rewarded ad shown for slot id: %@...", ad.slotId];
|
|
|
|
// NOTE: Called for video-only rewarded ads.
|
|
[self.delegate didDisplayRewardedAd];
|
|
[self.delegate didStartRewardedAdVideo];
|
|
}
|
|
|
|
- (void)fiveAdDidPause:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Rewarded ad did pause for slot id: %@...", ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidResume:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Rewarded ad did resume for slot id: %@...", ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidViewThrough:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Rewarded ad completed for slot id: %@...", ad.slotId];
|
|
[self.delegate didCompleteRewardedAdVideo];
|
|
|
|
// Note: LINE provides rewarded videos longer than 30 secs, e.g. 45 secs, where the user may watch the video for longer than the minimum 30 secs.
|
|
// At the 30 sec mark, LINE shows the close button and considers the reward as granted.
|
|
// Net-net: we do not need to handle the reward logic here; "always_reward_user" should be enabled.
|
|
self.grantedReward = YES;
|
|
}
|
|
|
|
- (void)fiveAdDidReplay:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Rewarded ad did replay for slot id: %@...", ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidStall:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Rewarded ad did stall for slot id: %@...", ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidRecover:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Rewarded ad did recover for slot id: %@...", ad.slotId];
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation ALLineMediationAdapterAdViewDelegate
|
|
|
|
- (instancetype)initWithParentAdapter:(ALLineMediationAdapter *)parentAdapter adFormat:(MAAdFormat *)adFormat andNotify:(id<MAAdViewAdapterDelegate>)delegate
|
|
{
|
|
self = [super init];
|
|
if ( self )
|
|
{
|
|
self.parentAdapter = parentAdapter;
|
|
self.delegate = delegate;
|
|
self.adFormat = adFormat;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)fiveAdDidLoad:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"%@ ad loaded for slot id: %@...", self.adFormat.label, ad.slotId];
|
|
[self.delegate didLoadAdForAdView: self.parentAdapter.adView];
|
|
}
|
|
|
|
- (void)fiveAd:(id<FADAdInterface>)ad didFailedToReceiveAdWithError:(FADErrorCode)errorCode
|
|
{
|
|
[self.parentAdapter log: @"%@ ad failed to load for slot id: %@ with error: %ld", self.adFormat.label, ad.slotId, errorCode];
|
|
MAAdapterError *error = [ALLineMediationAdapter toMaxError: errorCode];
|
|
[self.delegate didFailToLoadAdViewAdWithError: error];
|
|
}
|
|
|
|
- (void)fiveAd:(id<FADAdInterface>)ad didFailedToShowAdWithError:(FADErrorCode)errorCode
|
|
{
|
|
[self.parentAdapter log: @"%@ ad failed to show for slot id: %@ with error: %ld", self.adFormat.label, ad.slotId, errorCode];
|
|
MAAdapterError *error = [MAAdapterError errorWithCode: -4205 errorString: @"Ad Display Failed" thirdPartySdkErrorCode: errorCode thirdPartySdkErrorMessage: @""];
|
|
[self.delegate didFailToDisplayAdViewAdWithError: error];
|
|
}
|
|
|
|
- (void)fiveAdDidImpression:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"%@ ad impression tracked for slot id: %@...", self.adFormat.label, ad.slotId];
|
|
[self.delegate didDisplayAdViewAd];
|
|
}
|
|
|
|
- (void)fiveAdDidClick:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"%@ ad clicked for slot id: %@...", self.adFormat.label, ad.slotId];
|
|
[self.delegate didClickAdViewAd];
|
|
}
|
|
|
|
- (void)fiveAdDidClose:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"%@ ad hidden for slot id: %@...", self.adFormat.label, ad.slotId];
|
|
[self.delegate didHideAdViewAd];
|
|
}
|
|
|
|
- (void)fiveAdDidStart:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"%@ ad shown for slot id: %@...", self.adFormat.label, ad.slotId];
|
|
|
|
// NOTE: Called for video-only adview ads.
|
|
[self.delegate didDisplayAdViewAd];
|
|
}
|
|
|
|
- (void)fiveAdDidPause:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"%@ ad did pause for slot id: %@...", self.adFormat.label, ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidResume:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"%@ ad did resume for slot id: %@...", self.adFormat.label, ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidViewThrough:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"%@ ad completed for slot id: %@...", self.adFormat.label, ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidReplay:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"%@ ad did replay for slot id: %@...", self.adFormat.label, ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidStall:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"%@ ad did stall for slot id: %@...", self.adFormat.label, ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidRecover:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"%@ ad did recover for slot id: %@...", self.adFormat.label, ad.slotId];
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation ALLineMediationAdapterNativeAdViewDelegate
|
|
|
|
- (instancetype)initWithParentAdapter:(ALLineMediationAdapter *)parentAdapter adFormat:(MAAdFormat *)adFormat serverParameters:(NSDictionary<NSString *, id> *)serverParameters andNotify:(id<MAAdViewAdapterDelegate>)delegate
|
|
{
|
|
self = [super init];
|
|
if ( self )
|
|
{
|
|
self.parentAdapter = parentAdapter;
|
|
self.delegate = delegate;
|
|
self.adFormat = adFormat;
|
|
self.serverParameters = serverParameters;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)fiveAdDidLoad:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Native %@ ad loaded for slot id: %@...", self.adFormat.label, ad.slotId];
|
|
[self renderCustomNativeBanner];
|
|
}
|
|
|
|
- (void)fiveAd:(id<FADAdInterface>)ad didFailedToReceiveAdWithError:(FADErrorCode)errorCode
|
|
{
|
|
[self.parentAdapter log: @"Native %@ ad loaded for slot id: %@... with error: %ld", self.adFormat.label, ad.slotId, errorCode];
|
|
MAAdapterError *error = [ALLineMediationAdapter toMaxError: errorCode];
|
|
[self.delegate didFailToLoadAdViewAdWithError: error];
|
|
}
|
|
|
|
- (void)fiveAd:(id<FADAdInterface>)ad didFailedToShowAdWithError:(FADErrorCode)errorCode
|
|
{
|
|
[self.parentAdapter log: @"Native %@ ad showed for slot id: %@... with error: %ld", self.adFormat.label, ad.slotId, errorCode];
|
|
MAAdapterError *error = [MAAdapterError errorWithCode: -4205 errorString: @"Ad Display Failed" thirdPartySdkErrorCode: errorCode thirdPartySdkErrorMessage: @""];
|
|
[self.delegate didFailToDisplayAdViewAdWithError: error];
|
|
}
|
|
|
|
- (void)fiveAdDidImpression:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Native %@ ad impression tracked for slot id: %@...", self.adFormat.label, ad.slotId];
|
|
[self.delegate didDisplayAdViewAd];
|
|
}
|
|
|
|
- (void)fiveAdDidClick:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Native %@ ad clicked for slot id: %@...", self.adFormat.label, ad.slotId];
|
|
[self.delegate didClickAdViewAd];
|
|
}
|
|
|
|
- (void)fiveAdDidClose:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Native %@ ad hidden for slot id: %@...", self.adFormat.label, ad.slotId];
|
|
[self.delegate didHideAdViewAd];
|
|
}
|
|
|
|
- (void)fiveAdDidStart:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Native %@ ad shown for slot id: %@...", self.adFormat.label, ad.slotId];
|
|
|
|
// NOTE: Called for video-only native adview ads.
|
|
[self.delegate didDisplayAdViewAd];
|
|
}
|
|
|
|
- (void)fiveAdDidPause:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Native %@ ad did pause for slot id: %@...", self.adFormat.label, ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidResume:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Native %@ ad did resume for slot id: %@...", self.adFormat.label, ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidViewThrough:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Native %@ ad completed for slot id: %@...", self.adFormat.label, ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidReplay:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Native %@ ad did replay for slot id: %@...", self.adFormat.label, ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidStall:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Native %@ ad did stall for slot id: %@...", self.adFormat.label, ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidRecover:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Native %@ ad did recover for slot id: %@...", self.adFormat.label, ad.slotId];
|
|
}
|
|
|
|
- (void)renderCustomNativeBanner
|
|
{
|
|
[self.parentAdapter.nativeAd loadIconImageAsyncWithBlock:^(UIImage *iconImage) {
|
|
// Ensure UI rendering is done on main queue
|
|
dispatchOnMainQueue(^{
|
|
|
|
FADNative *nativeAd = self.parentAdapter.nativeAd;
|
|
if ( !nativeAd )
|
|
{
|
|
[self.parentAdapter log: @"Ad destroyed before assets finished load"];
|
|
[self.delegate didFailToLoadAdViewAdWithError: MAAdapterError.invalidLoadState];
|
|
|
|
return;
|
|
}
|
|
|
|
MANativeAd *maxNativeAd = [[MANativeAd alloc] initWithFormat: self.adFormat builderBlock:^(MANativeAdBuilder *builder) {
|
|
builder.title = nativeAd.getAdTitle;
|
|
builder.body = nativeAd.getDescriptionText;
|
|
builder.callToAction = nativeAd.getButtonText;
|
|
builder.icon = [[MANativeAdImage alloc] initWithImage: iconImage];
|
|
builder.mediaView = nativeAd.getAdMainView;
|
|
}];
|
|
|
|
// Backend will pass down `vertical` as the template to indicate using a vertical native template
|
|
NSString *templateName = [self.serverParameters al_stringForKey: @"template" defaultValue: @""];
|
|
if ( [templateName containsString: @"vertical"] && ALSdk.versionCode < 6140500 )
|
|
{
|
|
[self.parentAdapter log: @"Vertical native banners are only supported on MAX SDK 6.14.5 and above. Default native template will be used."];
|
|
}
|
|
|
|
MANativeAdView *maxNativeAdView;
|
|
if ( ALSdk.versionCode < 6140000 )
|
|
{
|
|
[self.parentAdapter log: @"Native ads with media views are only supported on MAX SDK version 6.14.0 and above. Default native template will be used."];
|
|
maxNativeAdView = [MANativeAdView nativeAdViewFromAd: maxNativeAd];
|
|
}
|
|
// Fallback case to be removed when backend sends down full template names for vertical native ads
|
|
else if ( [templateName isEqualToString: @"vertical"] )
|
|
{
|
|
NSString *verticalTemplateName = ( self.adFormat == MAAdFormat.leader ) ? @"vertical_leader_template" : @"vertical_media_banner_template";
|
|
maxNativeAdView = [MANativeAdView nativeAdViewFromAd: maxNativeAd withTemplate: verticalTemplateName];
|
|
}
|
|
else
|
|
{
|
|
maxNativeAdView = [MANativeAdView nativeAdViewFromAd: maxNativeAd withTemplate: templateName];
|
|
}
|
|
|
|
NSMutableArray *clickableViews = [NSMutableArray array];
|
|
if ( maxNativeAd.icon && maxNativeAdView.iconImageView )
|
|
{
|
|
[clickableViews addObject: maxNativeAdView.iconImageView];
|
|
}
|
|
if ( maxNativeAd.mediaView && maxNativeAdView.mediaContentView )
|
|
{
|
|
[clickableViews addObject: maxNativeAdView.mediaContentView];
|
|
}
|
|
if ( [maxNativeAd.title al_isValidString] && maxNativeAdView.titleLabel )
|
|
{
|
|
[clickableViews addObject: maxNativeAdView.titleLabel];
|
|
}
|
|
if ( [maxNativeAd.callToAction al_isValidString] && maxNativeAdView.callToActionButton )
|
|
{
|
|
[clickableViews addObject: maxNativeAdView.callToActionButton];
|
|
}
|
|
if ( [maxNativeAd.body al_isValidString] && maxNativeAdView.bodyLabel )
|
|
{
|
|
[clickableViews addObject: maxNativeAdView.bodyLabel];
|
|
}
|
|
|
|
[nativeAd registerViewForInteraction: maxNativeAdView withInformationIconView: maxNativeAdView.iconImageView withClickableViews: clickableViews];
|
|
[self.delegate didLoadAdForAdView: maxNativeAdView];
|
|
});
|
|
}];
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation ALLineMediationAdapterNativeAdDelegate
|
|
|
|
- (instancetype)initWithParentAdapter:(ALLineMediationAdapter *)parentAdapter serverParameters:(NSDictionary<NSString *, id> *)serverParameters andNotify:(id<MANativeAdAdapterDelegate>)delegate
|
|
{
|
|
self = [super init];
|
|
if ( self )
|
|
{
|
|
self.parentAdapter = parentAdapter;
|
|
self.delegate = delegate;
|
|
self.serverParameters = serverParameters;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)fiveAdDidLoad:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Native ad loaded for slot id: %@...", ad.slotId];
|
|
|
|
FADNative *loadedNativeAd = self.parentAdapter.nativeAd;
|
|
if ( !loadedNativeAd )
|
|
{
|
|
[self.parentAdapter log: @"Native ad destroyed before the ad successfully loaded: %@...", ad.slotId];
|
|
[self.delegate didFailToLoadNativeAdWithError: MAAdapterError.invalidLoadState];
|
|
|
|
return;
|
|
}
|
|
|
|
NSString *templateName = [self.serverParameters al_stringForKey: @"template" defaultValue: @""];
|
|
BOOL isTemplateAd = [templateName al_isValidString];
|
|
if ( isTemplateAd && ![loadedNativeAd.getAdTitle al_isValidString] )
|
|
{
|
|
[self.parentAdapter e: @"Native ad (%@) does not have required assets.", loadedNativeAd];
|
|
[self.delegate didFailToLoadNativeAdWithError: [MAAdapterError errorWithCode: -5400 errorString: @"Missing Native Ad Assets"]];
|
|
|
|
return;
|
|
}
|
|
|
|
[loadedNativeAd loadIconImageAsyncWithBlock:^(UIImage *iconImage) {
|
|
// Ensure UI rendering is done on main queue
|
|
dispatchOnMainQueue(^{
|
|
|
|
FADNative *nativeAd = self.parentAdapter.nativeAd;
|
|
if ( !nativeAd )
|
|
{
|
|
[self.parentAdapter log: @"Native ad destroyed before assets finished load for slot id: %@", ad.slotId];
|
|
[self.delegate didFailToLoadNativeAdWithError: MAAdapterError.invalidLoadState];
|
|
|
|
return;
|
|
}
|
|
|
|
MANativeAd *maxNativeAd = [[MALineNativeAd alloc] initWithParentAdapter: self.parentAdapter builderBlock:^(MANativeAdBuilder *builder) {
|
|
builder.title = nativeAd.getAdTitle;
|
|
builder.body = nativeAd.getDescriptionText;
|
|
builder.callToAction = nativeAd.getButtonText;
|
|
builder.icon = [[MANativeAdImage alloc] initWithImage: iconImage];
|
|
builder.mediaView = nativeAd.getAdMainView;
|
|
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wundeclared-selector"
|
|
// Introduced in 10.4.0
|
|
if ( [builder respondsToSelector: @selector(setAdvertiser:)] )
|
|
{
|
|
[builder performSelector: @selector(setAdvertiser:) withObject: nativeAd.getAdvertiserName];
|
|
}
|
|
#pragma clang diagnostic pop
|
|
}];
|
|
|
|
[self.delegate didLoadAdForNativeAd: maxNativeAd withExtraInfo: nil];
|
|
});
|
|
}];
|
|
}
|
|
|
|
- (void)fiveAd:(id<FADAdInterface>)ad didFailedToReceiveAdWithError:(FADErrorCode)errorCode
|
|
{
|
|
[self.parentAdapter log: @"Native ad failed to load for slot id: %@ with error: %ld", ad.slotId, errorCode];
|
|
MAAdapterError *error = [ALLineMediationAdapter toMaxError: errorCode];
|
|
[self.delegate didFailToLoadNativeAdWithError: error];
|
|
}
|
|
|
|
- (void)fiveAdDidImpression:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Native ad impression tracked for slot id: %@...", ad.slotId];
|
|
[self.delegate didDisplayNativeAdWithExtraInfo: nil];
|
|
}
|
|
|
|
- (void)fiveAdDidClick:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Native ad clicked for slot id: %@...", ad.slotId];
|
|
[self.delegate didClickNativeAd];
|
|
}
|
|
|
|
- (void)fiveAdDidClose:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Native ad hidden for slot id: %@...", ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidStart:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Native ad shown for slot id: %@...", ad.slotId];
|
|
|
|
// NOTE: Called for video-only native adview ads.
|
|
[self.delegate didDisplayNativeAdWithExtraInfo: nil];
|
|
}
|
|
|
|
- (void)fiveAdDidPause:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Native ad did pause for slot id: %@...", ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidResume:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Native ad did resume for slot id: %@...", ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidViewThrough:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Native ad completed for slot id: %@...", ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidReplay:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Native ad did replay for slot id: %@...", ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidStall:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Native ad did stall for slot id: %@...", ad.slotId];
|
|
}
|
|
|
|
- (void)fiveAdDidRecover:(id<FADAdInterface>)ad
|
|
{
|
|
[self.parentAdapter log: @"Native ad did recover for slot id: %@...", ad.slotId];
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation MALineNativeAd
|
|
|
|
- (instancetype)initWithParentAdapter:(ALLineMediationAdapter *)parentAdapter builderBlock:(NS_NOESCAPE MANativeAdBuilderBlock)builderBlock
|
|
{
|
|
self = [super initWithFormat: MAAdFormat.native builderBlock: builderBlock];
|
|
if ( self )
|
|
{
|
|
self.parentAdapter = parentAdapter;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)prepareViewForInteraction:(MANativeAdView *)maxNativeAdView
|
|
{
|
|
FADNative *nativeAd = self.parentAdapter.nativeAd;
|
|
if ( !nativeAd )
|
|
{
|
|
[self.parentAdapter e: @"Failed to register native ad views: native ad is nil."];
|
|
return;
|
|
}
|
|
|
|
NSMutableArray *clickableViews = [NSMutableArray array];
|
|
if ( [self.title al_isValidString] && maxNativeAdView.titleLabel )
|
|
{
|
|
[clickableViews addObject: maxNativeAdView.titleLabel];
|
|
}
|
|
if ( [self.body al_isValidString] && maxNativeAdView.bodyLabel )
|
|
{
|
|
[clickableViews addObject: maxNativeAdView.bodyLabel];
|
|
}
|
|
if ( [self.callToAction al_isValidString] && maxNativeAdView.callToActionButton )
|
|
{
|
|
[clickableViews addObject: maxNativeAdView.callToActionButton];
|
|
}
|
|
if ( self.icon && maxNativeAdView.iconImageView )
|
|
{
|
|
[clickableViews addObject: maxNativeAdView.iconImageView];
|
|
}
|
|
if ( self.mediaView && maxNativeAdView.mediaContentView )
|
|
{
|
|
[clickableViews addObject: maxNativeAdView.mediaContentView];
|
|
}
|
|
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wundeclared-selector"
|
|
// Introduced in 10.4.0
|
|
if ( [maxNativeAdView respondsToSelector: @selector(advertiserLabel)] && [self respondsToSelector: @selector(advertiser)] )
|
|
{
|
|
id advertiserLabel = [maxNativeAdView performSelector: @selector(advertiserLabel)];
|
|
id advertiser = [self performSelector: @selector(advertiser)];
|
|
if ( [advertiser al_isValidString] && advertiserLabel )
|
|
{
|
|
[clickableViews addObject: advertiserLabel];
|
|
}
|
|
}
|
|
#pragma clang diagnostic pop
|
|
|
|
dispatchOnMainQueue(^{
|
|
|
|
[nativeAd registerViewForInteraction: maxNativeAdView withInformationIconView: maxNativeAdView.iconImageView withClickableViews: clickableViews];
|
|
});
|
|
}
|
|
|
|
@end
|