diff --git a/android/src/main/kotlin/com/example/union_ad_ssgf/splashad/SplashAdView.kt b/android/src/main/kotlin/com/example/union_ad_ssgf/splashad/SplashAdView.kt index cf29500..bea3d66 100644 --- a/android/src/main/kotlin/com/example/union_ad_ssgf/splashad/SplashAdView.kt +++ b/android/src/main/kotlin/com/example/union_ad_ssgf/splashad/SplashAdView.kt @@ -47,6 +47,7 @@ internal class SplashAdView( } private fun loadSplashAd() { + LogUtil.e("codeId: $codeId , fetchDelay: $fetchDelay") splashAD = SplashAD(activity, codeId, this, fetchDelay) mContainer?.removeAllViews() splashAD?.fetchAdOnly() @@ -64,7 +65,7 @@ internal class SplashAdView( channel?.invokeMethod("onClose", "") } - //广告加载失败,error 对象包含了错误码和错误信息,错误码的详细内容可以参考文档第5章 + // 广告加载失败,error 对象包含了错误码和错误信息,错误码的详细内容可以参考文档第5章 override fun onNoAD(p0: AdError?) { LogUtil.e("开屏广告加载失败 ${p0?.errorCode} ${p0?.errorMsg}") var map: MutableMap = mutableMapOf("code" to p0?.errorCode, "message" to p0?.errorMsg) diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index bd5d45d..a707b4b 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -24,7 +24,6 @@ if (flutterVersionName == null) { android { namespace = "com.example.union_ad_ssgf_example" - // namespace = "com.zero.flutter_qq_ads_example" compileSdk = flutter.compileSdkVersion ndkVersion = flutter.ndkVersion @@ -34,7 +33,7 @@ android { } defaultConfig { - applicationId = "com.example.union_ad_ssgf_example" + applicationId = "com.example.union_ad_ssgf_example" minSdk = flutter.minSdkVersion targetSdk = flutter.targetSdkVersion versionCode = flutterVersionCode.toInteger() diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 5a47b50..6d40936 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -1,4 +1,5 @@ - + showSplashAd(context) async { MaterialPageRoute( builder: (_) { return SplashPage( - isBidding: false, + isBidding: true, androidId: AdsConfig.androidSplashId, iosId: AdsConfig.iosSplashId, ); diff --git a/example/lib/main.dart b/example/lib/main.dart index b25241a..a831046 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -37,7 +37,7 @@ class _MyAppState extends State { androidId: AdsConfig.androidAppId, iosId: AdsConfig.iosAppId, debug: true, // 是否显示日志log - personalized: FlutterTencentadPersonalized.show, // 是否显示个性化推荐广告 + personalized: FlutterTencentadPersonalized.close, // 是否显示个性化推荐广告 channelId: FlutterTencentadChannel.tencent, //渠道id ); debugPrint("广告SDK 初始化${result ? '成功' : '失败'}"); diff --git a/example/lib/splash_page.dart b/example/lib/splash_page.dart index 142c220..f563e08 100644 --- a/example/lib/splash_page.dart +++ b/example/lib/splash_page.dart @@ -26,14 +26,13 @@ class _SplashPageState extends State { Widget build(BuildContext context) { return Scaffold( body: Container( - color: Colors.red, child: FlutterUnionAd.splashAdView( // android广告id androidId: widget.androidId, // ios广告id iosId: widget.iosId, // 设置开屏广告从请求到展示所花的最大时长(并不是指广告曝光时长),取值范围为[1500, 5000]ms - fetchDelay: 3000, + fetchDelay: 5000, // 下载二次确认弹窗 默认false downloadConfirm: true, // 是否开启竞价 默认不开启 diff --git a/ios/Classes/Event/FAQAdErrorEvent.swift b/ios/Classes/Event/FAQAdErrorEvent.swift deleted file mode 100644 index ed12de5..0000000 --- a/ios/Classes/Event/FAQAdErrorEvent.swift +++ /dev/null @@ -1,32 +0,0 @@ -// -// FAQAdErrorEvent.swift -// Pods -// -// Created by Jin on 10/23/24. -// -import Foundation - -// 广告错误事件 -class FAQAdErrorEvent: FAQAdEvent { - // 错误码 - var errCode: NSNumber - - // 错误信息 - var errMsg: String - - // 构造广告错误事件 - init(adId: String, errCode: NSNumber, errMsg: String) { - self.errCode = errCode - self.errMsg = errMsg - super.init(adId: adId, action: "onAdError") // 假设 onAdError 是一个字符串 - } - - // 转换为字典 - override func toMap() -> [String: Any] { - var errData = super.toMap() // 获取父类字典 - errData["errCode"] = errCode // 添加错误代码 - errData["errMsg"] = errMsg // 添加错误信息 - return errData // 返回完整的字典 - } -} - diff --git a/ios/Classes/Event/FAQAdEvent.swift b/ios/Classes/Event/FAQAdEvent.swift deleted file mode 100644 index b892eab..0000000 --- a/ios/Classes/Event/FAQAdEvent.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// FAQAdEvent.swift -// Pods -// -// Created by Jin on 10/23/24. -// - -import Foundation - -// 通知 -class FAQAdEvent { - // 广告 id - var adId: String - // 操作 - var action: String - - // 初始化方法 - 构造广告事件 - init(adId: String, action: String) { - self.adId = adId - self.action = action - } - - // 转换为 Map 操作 - func toMap() -> [String: Any] { - return ["adId": adId, "action": action] - } -} diff --git a/ios/Classes/Event/FAQAdEventAction.swift b/ios/Classes/Event/FAQAdEventAction.swift deleted file mode 100644 index 24160c1..0000000 --- a/ios/Classes/Event/FAQAdEventAction.swift +++ /dev/null @@ -1,43 +0,0 @@ -// -// FAQAdEventAction.swift -// Pods -// -// Created by Jin on 10/23/24. -// - -import Foundation - -//广告事件操作常量 - -// 广告错误 -let onAdError = "onAdError" - -// 广告加载成功 -let onAdLoaded = "onAdLoaded" - -// 广告填充 -let onAdPresent = "onAdPresent" - -// 广告曝光 -let onAdExposure = "onAdExposure" - -// 广告关闭(计时结束或者用户点击关闭) -let onAdClosed = "onAdClosed" - -// 广告点击 -let onAdClicked = "onAdClicked" - -// 广告跳过 -let onAdSkip = "onAdSkip" - -// 广告播放或计时完毕 -let onAdComplete = "onAdComplete" - -// 获得广告激励 -let onAdReward = "onAdReward" - -// 广告事件操作类 -class FAQAdEventAction: NSObject { - // 可以在此处添加广告事件操作的方法 -} - diff --git a/ios/Classes/Event/FAQAdRewardEvent.swift b/ios/Classes/Event/FAQAdRewardEvent.swift deleted file mode 100644 index e5f9084..0000000 --- a/ios/Classes/Event/FAQAdRewardEvent.swift +++ /dev/null @@ -1,36 +0,0 @@ -// -// FAQAdRewardEvent.swift -// Pods -// -// Created by Jin on 10/23/24. -// - -import Foundation - -// 广告激励事件 -class FAQAdRewardEvent: FAQAdEvent { - // 服务端验证唯一id - var transId: String - // 服务端验证的自定义信息 - var customData: String - // 服务端验证的用户信息 - var userId: String - - // 构造广告激励事件 - init(adId: String, transId: String, customData: String, userId: String) { - self.transId = transId - self.customData = customData - self.userId = userId - super.init(adId: adId, action: onAdReward) // 假设 onAdReward 是一个常量 - } - - // 转换为字典 - override func toMap() -> [String: Any] { - var errData = super.toMap() // 获取父类字典 - errData["transId"] = transId // 添加 transId - errData["customData"] = customData // 添加 customData - errData["userId"] = userId // 添加 userId - return errData // 返回完整的字典 - } -} - diff --git a/ios/Classes/Page/FAQBaseAdPage.swift b/ios/Classes/Page/FAQBaseAdPage.swift index 9bf968b..ac6ccc7 100644 --- a/ios/Classes/Page/FAQBaseAdPage.swift +++ b/ios/Classes/Page/FAQBaseAdPage.swift @@ -1,9 +1,3 @@ -// -// FAQBaseAdPage.swift -// Pods -// -// Created by Jin on 10/23/24. -// import Flutter import UIKit diff --git a/ios/Classes/Page/FAQRewardVideoPage.swift b/ios/Classes/Page/FAQRewardVideoPage.swift index 4cc258f..83031bb 100644 --- a/ios/Classes/Page/FAQRewardVideoPage.swift +++ b/ios/Classes/Page/FAQRewardVideoPage.swift @@ -1,12 +1,5 @@ -// -// FAQRewardVideoPage.swift -// Pods -// -// Created by Jin on 10/23/24. -// - -import UIKit import Flutter +import UIKit // 激励视频页面 class FAQRewardVideoPage: FAQBaseAdPage, GDTRewardedVideoAdDelegate { @@ -22,13 +15,14 @@ class FAQRewardVideoPage: FAQBaseAdPage, GDTRewardedVideoAdDelegate { guard let arguments = call.arguments as? [String: Any], let customData = arguments["customData"] as? String, let userId = arguments["userId"] as? String, - let playMuted = arguments["playMuted"] as? Bool else { + let playMuted = arguments["playMuted"] as? Bool + else { return } - + self.customData = customData self.userId = userId - + // 初始化激励视频广告 self.rvad = GDTRewardVideoAd(placementId: self.posId) self.rvad?.delegate = self @@ -91,12 +85,16 @@ class FAQRewardVideoPage: FAQBaseAdPage, GDTRewardedVideoAdDelegate { self.sendErrorEvent(errCode: (error as NSError).code, errMsg: error.localizedDescription) } - func gdt_rewardVideoAdDidRewardEffective(_ rewardedVideoAd: GDTRewardVideoAd, info: [AnyHashable: Any]) { + func gdt_rewardVideoAdDidRewardEffective( + _ rewardedVideoAd: GDTRewardVideoAd, info: [AnyHashable: Any] + ) { print(#function) if let transId = info["GDT_TRANS_ID"] as? String { print("播放达到激励条件 transid: \(transId)") // 发送激励事件 - let event = FAQAdRewardEvent(adId: self.posId, transId: transId, customData: self.customData!, userId: self.userId!) + let event = FAQAdRewardEvent( + adId: self.posId, transId: transId, customData: self.customData!, + userId: self.userId!) self.sendEvent(event) } } diff --git a/ios/Classes/Page/FAQSplashPage.swift b/ios/Classes/Page/FAQSplashPage.swift index e5c1c7e..ba11309 100644 --- a/ios/Classes/Page/FAQSplashPage.swift +++ b/ios/Classes/Page/FAQSplashPage.swift @@ -1,10 +1,3 @@ -// -// FAQSplashPage.swift -// Pods -// -// Created by Jin on 10/23/24. -// - import UIKit import Flutter diff --git a/ios/Classes/UnionAdSsgf-Bridging-Header.h b/ios/Classes/UnionAdSsgf-Bridging-Header.h deleted file mode 100644 index 90ebc83..0000000 --- a/ios/Classes/UnionAdSsgf-Bridging-Header.h +++ /dev/null @@ -1,5 +0,0 @@ -#import -#import -#import -#import -#import diff --git a/ios/Classes/UnionAdSsgfPlugin.h b/ios/Classes/UnionAdSsgfPlugin.h new file mode 100644 index 0000000..0efbaad --- /dev/null +++ b/ios/Classes/UnionAdSsgfPlugin.h @@ -0,0 +1,4 @@ +#import + +@interface UnionAdSsgfPlugin : NSObject +@end diff --git a/ios/Classes/UnionAdSsgfPlugin.m b/ios/Classes/UnionAdSsgfPlugin.m new file mode 100644 index 0000000..cc56786 --- /dev/null +++ b/ios/Classes/UnionAdSsgfPlugin.m @@ -0,0 +1,66 @@ +#import "UnionAdSsgfPlugin.h" +#import "GDTSDKConfig.h" +#import "UnionAdSsgfEvent.h" +#import "RewardAd.h" +#import "TLogUtil.h" +#import "InsertAd.h" +#import "SplashAd.h" +#import "BannerAd.h" +#import "NativeAd.h" + +@implementation UnionAdSsgfPlugin ++ (void)registerWithRegistrar:(NSObject*)registrar { + FlutterMethodChannel* channel = [FlutterMethodChannel + methodChannelWithName:@"flutter_union_ad" + binaryMessenger:[registrar messenger]]; + UnionAdSsgfPlugin* instance = [[UnionAdSsgfPlugin alloc] init]; + [registrar addMethodCallDelegate:instance channel:channel]; + //注册event + [[UnionAdSsgfEvent sharedInstance] initEvent:registrar]; + //注册splash + [registrar registerViewFactory:[[SplashAdFactory alloc] initWithMessenger:registrar.messenger] withId:@"com.example.union_ad_ssgf/SplashAdView"]; + //注册banner + [registrar registerViewFactory:[[BannerAdFactory alloc] initWithMessenger:registrar.messenger] withId:@"com.example.union_ad_ssgf/BannerAdView"]; + //注册native + [registrar registerViewFactory:[[NaitveAdFactory alloc] initWithMessenger:registrar.messenger] withId:@"com.example.union_ad_ssgf/NativeExpressAdView"]; + +} + +- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { + if ([@"register" isEqualToString:call.method]) { + NSString *appId = call.arguments[@"iosId"]; + BOOL debug = [call.arguments[@"debug"] boolValue]; + BOOL isInit = [GDTSDKConfig initWithAppId:appId]; + NSInteger personalized = [call.arguments[@"personalized"] intValue]; + NSInteger channelId = [call.arguments[@"channelId"] intValue]; + //关闭个性化推荐 + [GDTSDKConfig setPersonalizedState:personalized]; + //渠道id + [GDTSDKConfig setChannel:channelId]; + [[TLogUtil sharedInstance] debug:debug]; + result([NSNumber numberWithBool:isInit]); + }else if([@"getSDKVersion" isEqualToString:call.method]){ + NSString *version = [GDTSDKConfig sdkVersion]; + result(version); + //预加载激励广告 + }else if([@"loadRewardVideoAd" isEqualToString:call.method]){ + [[RewardAd sharedInstance] initAd:call.arguments]; + result(@YES); + //显示激励广告 + }else if([@"showRewardVideoAd" isEqualToString:call.method]){ + [[RewardAd sharedInstance] showAd:call.arguments]; + result(@YES); + //预加载插屏广告 + }else if([@"loadInterstitialAD" isEqualToString:call.method]){ + [[InsertAd sharedInstance] initAd:call.arguments]; + result(@YES); + ////展示插屏广告 + }else if([@"showInterstitialAD" isEqualToString:call.method]){ + [[InsertAd sharedInstance] showAd:call.arguments]; + result(@YES); + } else { + result(FlutterMethodNotImplemented); + } +} + +@end diff --git a/ios/Classes/UnionAdSsgfPlugin.swift b/ios/Classes/UnionAdSsgfPlugin.swift deleted file mode 100644 index b68fb22..0000000 --- a/ios/Classes/UnionAdSsgfPlugin.swift +++ /dev/null @@ -1,142 +0,0 @@ -import Flutter -import AppTrackingTransparency -import AdSupport - - -public class UnionAdSsgfPlugin: NSObject, FlutterPlugin ,FlutterStreamHandler{ - static var methodName = "union_ad_ssgf_method" - static var eventName = "union_ad_ssgf_event" - - var splashAd: FAQSplashPage? - var rewardAd: FAQRewardVideoPage? - var sink:FlutterEventSink? - - public static func register(with registrar: FlutterPluginRegistrar) { - let methodChannel = FlutterMethodChannel(name: methodName, binaryMessenger: registrar.messenger()); - let eventChannel = FlutterEventChannel(name: eventName, binaryMessenger: registrar.messenger()); - let instance = UnionAdSsgfPlugin(); - registrar.addMethodCallDelegate(instance, channel: methodChannel); - eventChannel.setStreamHandler(instance); - } - - public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { - switch call.method { - case "getPlatformVersion": - getPlatformVersion(call: call, result: result) - case "requestIDFA": - requestIDFA(call: call, result: result) - case "initAd": // 初始化 - initAd(call:call, result: result); - case "setPersonalizedState": // 设置广告个性化 - setPersonalizedState(call:call, result: result); - case "showSplashAd": // 开屏广告 - showSplashAd(call:call, result: result); - case "showRewardVideoAd": // 激励广告 - showRewardVideoAd(call:call, result: result); - default: - result(FlutterMethodNotImplemented) - } - } - - // 版本号 - public func getPlatformVersion(call: FlutterMethodCall, result: @escaping FlutterResult) { - result("iOS " + UIDevice.current.systemVersion) - } - - // 初始化广告 - public func initAd(call: FlutterMethodCall, result: @escaping FlutterResult) { - if let arguments = call.arguments as? [String: Any], - let appId = arguments["appId"] as? String { - print("App ID: \(appId)") - // 初始化插件 - let initSuccess = GDTSDKConfig.initWithAppId(appId) - print("初始化插件 initSuccess: \(initSuccess)") - result(NSNumber(value: initSuccess)) - GDTSDKConfig.start {success, error in - // 返回结果 - result(true) - if success { - result(NSNumber(value: true)) - } else { - result(NSNumber(value: false)) - if let error = error { - print("FlutterQqAdsPlugin initAd error: \(error.localizedDescription)") - } - } - } - } else { - print("appId not found or invalid type.") - result(NSNumber(value: false)) // 处理无效的 appId - } - } - - - // 透明权限 - public func requestIDFA(call: FlutterMethodCall, result: @escaping FlutterResult) { - if #available(iOS 14, *) { - ATTrackingManager.requestTrackingAuthorization { status in - let requestResult = (status == .authorized) - print("requestIDFA: \(requestResult ? "YES" : "NO")") - result(requestResult) - } - } else { - result(true) - } - } - - // 设置广告个性化 - public func setPersonalizedState(call: FlutterMethodCall, result: @escaping FlutterResult) { - if let arguments = call.arguments as? [String: Any], - let state = arguments["state"] as? Int { - print("Set State : \(state)") - GDTSDKConfig.setPersonalizedState(state) - result(NSNumber(value: true)) - } else { - print("appId not found or invalid type.") - result(NSNumber(value: false)) // 处理无效的 appId - } - } - - // 开屏广告 - public func showSplashAd(call: FlutterMethodCall, result: FlutterResult) { - // 初始化 FAQSplashPage 实例 - self.splashAd = FAQSplashPage() - if(self.sink != nil){ - print("--------------->>>>> showSplashAd"); - self.splashAd?.showAd(call: call, eventSink: self.sink!) - result(true) - }else{ - result(NSNumber(value: false)) - } - } - - // 激励广告 - public func showRewardVideoAd(call: FlutterMethodCall, result: FlutterResult) { - // 初始化 FAQRewardVideoPage 实例 - self.rewardAd = FAQRewardVideoPage(); - if(self.sink != nil){ - self.rewardAd?.showAd(call: call, eventSink: self.sink!) - result(NSNumber(value: true)) - }else{ - result(NSNumber(value: false)) - } - } - - // 设置事件接收器 - public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? { - self.sink = events - return nil - } - - // 清空事件接收器 - public func onCancel(withArguments arguments: Any?) -> FlutterError? { - self.sink = nil; - return nil; - } - - // 添加事件 - private func addEvent(_ event: NSObject) { - self.sink?(event) - } - -} diff --git a/ios/Classes/banner/BannerAd.h b/ios/Classes/banner/BannerAd.h new file mode 100644 index 0000000..6430acc --- /dev/null +++ b/ios/Classes/banner/BannerAd.h @@ -0,0 +1,21 @@ +#import + +#import + +NS_ASSUME_NONNULL_BEGIN +@interface BannerAdFactory : NSObject + +- (instancetype)initWithMessenger:(NSObject*)messager; + +@end + +@interface BannerAd : NSObject + +- (instancetype)initWithWithFrame:(CGRect)frame + viewIdentifier:(int64_t)viewId + arguments:(id _Nullable)args + binaryMessenger:(NSObject*)messenger; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Classes/banner/BannerAd.m b/ios/Classes/banner/BannerAd.m new file mode 100644 index 0000000..c02f435 --- /dev/null +++ b/ios/Classes/banner/BannerAd.m @@ -0,0 +1,187 @@ +#import "BannerAd.h" +#import "GDTUnifiedBannerView.h" +#import "TLogUtil.h" +#import "TUIViewController+getCurrentVC.h" + +#pragma mark - BannerAdFactory + +@implementation BannerAdFactory{ + NSObject*_messenger; +} + +- (instancetype)initWithMessenger:(NSObject *)messager{ + self = [super init]; + if (self) { + _messenger = messager; + } + return self; +} + +-(NSObject *)createArgsCodec{ + return [FlutterStandardMessageCodec sharedInstance]; +} + +-(NSObject *)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id)args{ + BannerAd * bannerAd = [[BannerAd alloc] initWithWithFrame:frame viewIdentifier:viewId arguments:args binaryMessenger:_messenger]; + return bannerAd; +} + +@end + +@interface BannerAd() + +@property (nonatomic, strong) GDTUnifiedBannerView *banner; +@property(nonatomic,strong) UIView *container; +@property(nonatomic,assign) CGRect frame; +@property(nonatomic,assign) NSInteger viewId; +@property(nonatomic,strong) FlutterMethodChannel *channel; +@property(nonatomic,strong) NSString *codeId; +@property(nonatomic,assign) NSInteger viewWidth; +@property(nonatomic,assign) NSInteger viewHeight; +@property(nonatomic,assign) BOOL isBidding; +@end + + +@implementation BannerAd + +- (instancetype)initWithWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id)args binaryMessenger:(NSObject *)messenger{ + if ([super init]) { + NSDictionary *dic = args; + _frame = frame; + _viewId = viewId; + _codeId = dic[@"iosId"]; + _viewWidth =[dic[@"viewWidth"] intValue]; + _viewHeight =[dic[@"viewHeight"] intValue]; + self.isBidding =[dic[@"isBidding"] boolValue]; + NSString* channelName = [NSString stringWithFormat:@"com.example.union_ad_ssgf/BannerAdView_%lld", viewId]; + _channel = [FlutterMethodChannel methodChannelWithName:channelName binaryMessenger:messenger]; + [self.channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { + // 竞价成功 + if ([@"biddingSucceeded" isEqualToString:call.method]) { + NSDictionary *dictionary = @{GDT_M_W_E_COST_PRICE:@([call.arguments[@"expectCostPrice"] intValue]), + GDT_M_W_H_LOSS_PRICE:@([call.arguments[@"highestLossPrice"] intValue]) + }; + [self->_banner sendWinNotificationWithInfo:dictionary]; + NSDictionary *dictionary2 = @{@"width": @(self.banner.frame.size.width),@"height":@(self.banner.frame.size.height)}; + [_channel invokeMethod:@"onShow" arguments:dictionary2 result:nil]; + //竞价失败 + } else if([@"biddingFail" isEqualToString:call.method]) { + NSDictionary *dictionary = @{GDT_M_L_WIN_PRICE:@([call.arguments[@"winPrice"] intValue]), + GDT_M_L_LOSS_REASON:@([call.arguments[@"lossReason"] intValue]), + GDT_M_ADNID: call.arguments[@"adnId"]}; + [self.banner sendWinNotificationWithInfo:dictionary]; + } + }]; + [self loadBannerAd]; + } + return self; +} + +- (UIView*)view{ + return self.container; +} + +-(void)loadBannerAd{ + [_container removeFromSuperview]; + CGRect rect = {CGPointZero, CGSizeMake(_viewWidth, _viewHeight)}; + if(self.banner == nil){ + self.banner = [[GDTUnifiedBannerView alloc] initWithFrame:rect placementId:_codeId viewController:[UIViewController jsd_getCurrentViewController]]; + self.banner.delegate = self; + self.banner.autoSwitchInterval = 30; + } + self.container = self.banner; + [self.banner loadAdAndShow]; +} + +/** + * 请求广告条数据成功后调用 + * 当接收服务器返回的广告数据成功后调用该函数 + */ +- (void)unifiedBannerViewDidLoad:(GDTUnifiedBannerView *)unifiedBannerView{ + [[TLogUtil sharedInstance] print:@"Banner广告数据请求成功"]; + // [[TLogUtil sharedInstance] print:self.banner.eCPMLevel]; + // [[TLogUtil sharedInstance] print:@(self.banner.eCPM)]; + //是否开启竞价 + if(self.isBidding){ + NSDictionary *dictionary = @{@"ecpmLevel":self.banner.eCPMLevel == nil ? @"" : self.banner.eCPMLevel,@"ecpm":@(self.banner.eCPM)}; + [self.channel invokeMethod:@"onECPM" arguments:dictionary result:nil]; + }else{ + // [self.container addSubview:self.banner]; + NSDictionary *dictionary = @{@"width": @(unifiedBannerView.frame.size.width),@"height":@(unifiedBannerView.frame.size.height)}; + [self.channel invokeMethod:@"onShow" arguments:dictionary result:nil]; + } +} + +/** + * 请求广告条数据失败后调用 + * 当接收服务器返回的广告数据失败后调用该函数 + */ +- (void)unifiedBannerViewFailedToLoad:(GDTUnifiedBannerView *)unifiedBannerView error:(NSError *)error{ + [[TLogUtil sharedInstance] print:@"请求广告条数据失败后调用"]; + NSDictionary *dictionary = @{@"code":@(-1),@"message":error.description}; + [_channel invokeMethod:@"onFail" arguments:dictionary result:nil]; +} + +/** + * banner2.0曝光回调 + */ +- (void)unifiedBannerViewWillExpose:(GDTUnifiedBannerView *)unifiedBannerView{ + [[TLogUtil sharedInstance] print:@"banner2.0曝光回调"]; + [_channel invokeMethod:@"onExpose" arguments:nil result:nil]; +} + +/** + * banner2.0点击回调 + */ +- (void)unifiedBannerViewClicked:(GDTUnifiedBannerView *)unifiedBannerView{ + [[TLogUtil sharedInstance] print:@"banner2.0点击回调"]; + [_channel invokeMethod:@"onClick" arguments:nil result:nil]; +} + +/** + * banner2.0广告点击以后即将弹出全屏广告页 + */ +- (void)unifiedBannerViewWillPresentFullScreenModal:(GDTUnifiedBannerView *)unifiedBannerView{ + [[TLogUtil sharedInstance] print:@"banner2.0广告点击以后即将弹出全屏广告页"]; +} + +/** + * banner2.0广告点击以后弹出全屏广告页完毕 + */ +- (void)unifiedBannerViewDidPresentFullScreenModal:(GDTUnifiedBannerView *)unifiedBannerView{ + [[TLogUtil sharedInstance] print:@"banner2.0广告点击以后弹出全屏广告页完毕"]; +} + +/** + * 全屏广告页即将被关闭 + */ +- (void)unifiedBannerViewWillDismissFullScreenModal:(GDTUnifiedBannerView *)unifiedBannerView{ + [[TLogUtil sharedInstance] print:@"全屏广告页即将被关闭"]; +} + +/** + * 全屏广告页已经被关闭 + */ +- (void)unifiedBannerViewDidDismissFullScreenModal:(GDTUnifiedBannerView *)unifiedBannerView{ + [[TLogUtil sharedInstance] print:@"全屏广告页已经被关闭"]; +} + +/** + * 当点击应用下载或者广告调用系统程序打开 + */ +- (void)unifiedBannerViewWillLeaveApplication:(GDTUnifiedBannerView *)unifiedBannerView{ + [[TLogUtil sharedInstance] print:@"当点击应用下载或者广告调用系统程序打开"]; +} + +/** + * banner2.0被用户关闭时调用 + * 会立即关闭当前banner广告,若启用轮播,(刷新间隔 - 当前广告已展示时间)后会展示新的广告 + * 若未启用轮播或不需要再展示,需在回调中将unifiedBannerView从父view移除置nil + */ +- (void)unifiedBannerViewWillClose:(GDTUnifiedBannerView *)unifiedBannerView{ + [[TLogUtil sharedInstance] print:@"banner2.0被用户关闭时调用"]; + [_channel invokeMethod:@"onClose" arguments:nil result:nil]; +} + + +@end diff --git a/ios/Classes/event/UnionAdSsgfEvent.h b/ios/Classes/event/UnionAdSsgfEvent.h new file mode 100644 index 0000000..9ac0fc9 --- /dev/null +++ b/ios/Classes/event/UnionAdSsgfEvent.h @@ -0,0 +1,12 @@ +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface UnionAdSsgfEvent : NSObject ++ (instancetype)sharedInstance; +- (void)initEvent:(NSObject*)registrar; +- (void)sentEvent:(NSDictionary*)arguments; +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Classes/event/UnionAdSsgfEvent.m b/ios/Classes/event/UnionAdSsgfEvent.m new file mode 100644 index 0000000..f4be850 --- /dev/null +++ b/ios/Classes/event/UnionAdSsgfEvent.m @@ -0,0 +1,41 @@ +#import "UnionAdSsgfEvent.h" +#import + +@interface UnionAdSsgfEvent () +@property(nonatomic, strong) FlutterEventSink eventSink; +@end + +@implementation UnionAdSsgfEvent + ++ (instancetype)sharedInstance { + static UnionAdSsgfEvent *myInstance = nil; + if (myInstance == nil) { + myInstance = [[UnionAdSsgfEvent alloc] init]; + } + return myInstance; +} + +- (void)initEvent:(NSObject *)registrar { + FlutterEventChannel *eventChannel = [FlutterEventChannel + eventChannelWithName:@"com.example.union_ad_ssgf/adevent" + binaryMessenger:[registrar messenger]]; + [eventChannel setStreamHandler:self]; +} + +- (void)sentEvent:(NSDictionary *)arguments { + self.eventSink(arguments); +} + +#pragma mark - FlutterStreamHandler +- (FlutterError *_Nullable)onCancelWithArguments:(id _Nullable)arguments { + self.eventSink = nil; + return nil; +} + +- (FlutterError *_Nullable)onListenWithArguments:(id _Nullable)arguments + eventSink: + (nonnull FlutterEventSink)events { + self.eventSink = events; + return nil; +} +@end diff --git a/ios/Classes/insert/InsertAd.h b/ios/Classes/insert/InsertAd.h new file mode 100644 index 0000000..214a619 --- /dev/null +++ b/ios/Classes/insert/InsertAd.h @@ -0,0 +1,11 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface InsertAd : NSObject ++ (instancetype)sharedInstance; +- (void)initAd:(NSDictionary *)arguments; +- (void)showAd:(NSDictionary *)arguments; +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Classes/insert/InsertAd.m b/ios/Classes/insert/InsertAd.m new file mode 100644 index 0000000..17f6f2b --- /dev/null +++ b/ios/Classes/insert/InsertAd.m @@ -0,0 +1,263 @@ +#import "InsertAd.h" +#import "GDTUnifiedInterstitialAd.h" +#import "TLogUtil.h" +#import "TUIViewController+getCurrentVC.h" +#import "UnionAdSsgfEvent.h" + + +@interface InsertAd() + +@property(nonatomic,strong) GDTUnifiedInterstitialAd *interstitialAd; +@property(nonatomic,strong) NSString *codeId; +@property(nonatomic,assign) BOOL isFullScreen; +@property(nonatomic,assign) BOOL isBidding; +@property(nonatomic,strong) UIViewController *currentController; + +@end + + + +@implementation InsertAd + ++ (instancetype)sharedInstance{ + static InsertAd *myInstance = nil; + if(myInstance == nil){ + myInstance = [[InsertAd alloc]init]; + } + return myInstance; +} + +//预加载激励广告 +-(void)initAd:(NSDictionary*)arguments{ + NSDictionary *dic = arguments; + _codeId = dic[@"iosId"]; + _isFullScreen = [dic[@"isFullScreen"] boolValue]; + self.isBidding =[dic[@"isBidding"] boolValue]; + _interstitialAd = [[GDTUnifiedInterstitialAd alloc] initWithPlacementId:_codeId]; + _interstitialAd.delegate = self; + _interstitialAd.videoMuted = false; + _isFullScreen ? [_interstitialAd loadFullScreenAd] : [_interstitialAd loadAd]; +} + +//展示广告 +- (void)showAd:(NSDictionary*)arguments{ + if(self.isBidding){ + BOOL isSuccess = [arguments[@"isSuccess"] boolValue]; + if(isSuccess){ + NSDictionary *dictionary = @{GDT_M_W_E_COST_PRICE:@([arguments[@"expectCostPrice"] intValue]), + GDT_M_W_H_LOSS_PRICE:@([arguments[@"highestLossPrice"] intValue])}; + [self.interstitialAd sendWinNotificationWithInfo:dictionary]; + if(_isFullScreen){ + [_interstitialAd presentFullScreenAdFromRootViewController:[UIViewController jsd_getCurrentViewController]]; + }else{ + [_interstitialAd presentAdFromRootViewController:[UIViewController jsd_getCurrentViewController]]; + } + }else{ + NSDictionary *dictionary = @{GDT_M_L_WIN_PRICE:@([arguments[@"winPrice"] intValue]), + GDT_M_L_LOSS_REASON:@([arguments[@"lossReason"] intValue]), + GDT_M_ADNID: arguments[@"adnId"]}; + [self.interstitialAd sendWinNotificationWithInfo:dictionary]; + } + }else{ + if(_isFullScreen){ + [_interstitialAd presentFullScreenAdFromRootViewController:[UIViewController jsd_getCurrentViewController]]; + }else{ + [_interstitialAd presentAdFromRootViewController:[UIViewController jsd_getCurrentViewController]]; + } + } +} + + +#pragma mark - 广告请求delegate + +/** + * 插屏2.0广告预加载成功回调 + * 当接收服务器返回的广告数据成功且预加载后调用该函数 + */ +- (void)unifiedInterstitialSuccessToLoadAd:(GDTUnifiedInterstitialAd *)unifiedInterstitial{ + [[TLogUtil sharedInstance] print:@"插屏2.0广告预加载成功回调"]; +} + +/** + * 插屏2.0广告预加载失败回调 + * 当接收服务器返回的广告数据失败后调用该函数 + */ +- (void)unifiedInterstitialFailToLoadAd:(GDTUnifiedInterstitialAd *)unifiedInterstitial error:(NSError *)error{ + [[TLogUtil sharedInstance] print:((void)(@"插屏2.0广告预加载失败回调 %@"),error.description)]; + NSDictionary *dictionary = @{@"adType":@"interactAd",@"onAdMethod":@"onFail",@"code":@(-1),@"message":error.description}; + [[UnionAdSsgfEvent sharedInstance] sentEvent:dictionary]; +} + +/** + * 插屏2.0广告视频缓存完成 + */ +- (void)unifiedInterstitialDidDownloadVideo:(GDTUnifiedInterstitialAd *)unifiedInterstitial{ + [[TLogUtil sharedInstance] print:@"插屏2.0广告视频缓存完成"]; +} + +/** + * 插屏2.0广告渲染成功 + * 建议在此回调后展示广告 + */ +- (void)unifiedInterstitialRenderSuccess:(GDTUnifiedInterstitialAd *)unifiedInterstitial{ + [[TLogUtil sharedInstance] print:@"插屏2.0广告渲染成功"]; + //是否开启竞价 + if(self.isBidding){ + NSDictionary *dictionary = @{@"adType":@"interactAd",@"onAdMethod":@"onECPM",@"ecpmLevel":self.interstitialAd.eCPMLevel == nil ? @"" : self.interstitialAd.eCPMLevel,@"ecpm":@(self.interstitialAd.eCPM)}; + [[UnionAdSsgfEvent sharedInstance] sentEvent:dictionary]; + }else{ + NSDictionary *dictionary = @{@"adType":@"interactAd",@"onAdMethod":@"onReady"}; + [[UnionAdSsgfEvent sharedInstance] sentEvent:dictionary]; + } +} + +/** + * 插屏2.0广告渲染失败 + */ +- (void)unifiedInterstitialRenderFail:(GDTUnifiedInterstitialAd *)unifiedInterstitial error:(NSError *)error{ + [[TLogUtil sharedInstance] print:((void)(@"插屏2.0广告渲染失败 %@"),error.description)]; + NSDictionary *dictionary = @{@"adType":@"interactAd",@"onAdMethod":@"onFail",@"code":@(-1),@"message":error.description}; + [[UnionAdSsgfEvent sharedInstance] sentEvent:dictionary]; +} + +/** + * 插屏2.0广告将要展示回调 + * 插屏2.0广告即将展示回调该函数 + */ +- (void)unifiedInterstitialWillPresentScreen:(GDTUnifiedInterstitialAd *)unifiedInterstitial{ + [[TLogUtil sharedInstance] print:@"插屏2.0广告将要展示回调"]; + NSDictionary *dictionary = @{@"adType":@"interactAd",@"onAdMethod":@"onShow"}; + [[UnionAdSsgfEvent sharedInstance] sentEvent:dictionary]; +} + +/** + * 插屏2.0广告视图展示成功回调 + * 插屏2.0广告展示成功回调该函数 + */ +- (void)unifiedInterstitialDidPresentScreen:(GDTUnifiedInterstitialAd *)unifiedInterstitial{ + [[TLogUtil sharedInstance] print:@"插屏2.0广告视图展示成功回调"]; +} + +/** + * 插屏2.0广告视图展示失败回调 + * 插屏2.0广告展示失败回调该函数 + */ +- (void)unifiedInterstitialFailToPresent:(GDTUnifiedInterstitialAd *)unifiedInterstitial error:(NSError *)error{ + [[TLogUtil sharedInstance] print:((void)(@"插屏2.0广告视图展示失败回调 %@"),error.description)]; + NSDictionary *dictionary = @{@"adType":@"interactAd",@"onAdMethod":@"onFail",@"code":@(-1),@"message":error.description}; + [[UnionAdSsgfEvent sharedInstance] sentEvent:dictionary]; +} + +/** + * 插屏2.0广告展示结束回调 + * 插屏2.0广告展示结束回调该函数 + */ +- (void)unifiedInterstitialDidDismissScreen:(GDTUnifiedInterstitialAd *)unifiedInterstitial{ + [[TLogUtil sharedInstance] print:@"插屏2.0广告展示结束回调"]; + NSDictionary *dictionary = @{@"adType":@"interactAd",@"onAdMethod":@"onClose"}; + [[UnionAdSsgfEvent sharedInstance] sentEvent:dictionary]; +} + +/** + * 当点击下载应用时会调用系统程序打开其它App或者Appstore时回调 + */ +- (void)unifiedInterstitialWillLeaveApplication:(GDTUnifiedInterstitialAd *)unifiedInterstitial{ + [[TLogUtil sharedInstance] print:@"插屏2.0点击下载应用时会调用系统程序打开其它App或者Appstore时回调"]; +} + +/** + * 插屏2.0广告曝光回调 + */ +- (void)unifiedInterstitialWillExposure:(GDTUnifiedInterstitialAd *)unifiedInterstitial{ + [[TLogUtil sharedInstance] print:@"插屏2.0广告曝光回调"]; + NSDictionary *dictionary = @{@"adType":@"interactAd",@"onAdMethod":@"onExpose"}; + [[UnionAdSsgfEvent sharedInstance] sentEvent:dictionary]; +} + +/** + * 插屏2.0广告点击回调 + */ +- (void)unifiedInterstitialClicked:(GDTUnifiedInterstitialAd *)unifiedInterstitial{ + [[TLogUtil sharedInstance] print:@"插屏2.0广告点击回调"]; + NSDictionary *dictionary = @{@"adType":@"interactAd",@"onAdMethod":@"onClick"}; + [[UnionAdSsgfEvent sharedInstance] sentEvent:dictionary]; +} + +/** + * 点击插屏2.0广告以后即将弹出全屏广告页 + */ +- (void)unifiedInterstitialAdWillPresentFullScreenModal:(GDTUnifiedInterstitialAd *)unifiedInterstitial{ + [[TLogUtil sharedInstance] print:@"点击插屏2.0广告以后即将弹出全屏广告页"]; +} + +/** + * 点击插屏2.0广告以后弹出全屏广告页 + */ +- (void)unifiedInterstitialAdDidPresentFullScreenModal:(GDTUnifiedInterstitialAd *)unifiedInterstitial{ + [[TLogUtil sharedInstance] print:@"点击插屏2.0广告以后弹出全屏广告页"]; +} + +/** + * 全屏广告页将要关闭 + */ +- (void)unifiedInterstitialAdWillDismissFullScreenModal:(GDTUnifiedInterstitialAd *)unifiedInterstitial{ + [[TLogUtil sharedInstance] print:@"插屏2.0全屏广告页将要关闭"]; +} + +/** + * 全屏广告页被关闭 + */ +- (void)unifiedInterstitialAdDidDismissFullScreenModal:(GDTUnifiedInterstitialAd *)unifiedInterstitial{ + [[TLogUtil sharedInstance] print:@"插屏2.0全屏广告页将要关闭"]; +} + +/** + * 插屏2.0视频广告 player 播放状态更新回调 + */ +- (void)unifiedInterstitialAd:(GDTUnifiedInterstitialAd *)unifiedInterstitial playerStatusChanged:(GDTMediaPlayerStatus)status{ + [[TLogUtil sharedInstance] print:@"插屏2.0视频广告 player 播放状态更新回调"]; +} + +/** + * 插屏2.0视频广告详情页 WillPresent 回调 + */ +- (void)unifiedInterstitialAdViewWillPresentVideoVC:(GDTUnifiedInterstitialAd *)unifiedInterstitial{ + [[TLogUtil sharedInstance] print:@"插屏2.0视频广告详情页 WillPresent 回调"]; +} + +/** + * 插屏2.0视频广告详情页 DidPresent 回调 + */ +- (void)unifiedInterstitialAdViewDidPresentVideoVC:(GDTUnifiedInterstitialAd *)unifiedInterstitial{ + [[TLogUtil sharedInstance] print:@"插屏2.0视频广告详情页 DidPresent 回调"]; +} + +/** + * 插屏2.0视频广告详情页 WillDismiss 回调 + */ +- (void)unifiedInterstitialAdViewWillDismissVideoVC:(GDTUnifiedInterstitialAd *)unifiedInterstitial{ + [[TLogUtil sharedInstance] print:@"插屏2.0视频广告详情页 WillDismiss 回调"]; +} + +/** + * 插屏2.0视频广告详情页 DidDismiss 回调 + */ +- (void)unifiedInterstitialAdViewDidDismissVideoVC:(GDTUnifiedInterstitialAd *)unifiedInterstitial{ + [[TLogUtil sharedInstance] print:@"插屏2.0视频广告详情页 DidDismiss 回调"]; +} + +/** + * 插屏激励广告视频播放达到激励条件回调(只有插屏激励广告位才会有此回调) + + @param unifiedInterstitial GDTUnifiedInterstitialAd 实例 + @param info 包含此次广告行为的一些信息,例如 @{@"GDT_TRANS_ID":@"930f1fc8ac59983bbdf4548ee40ac353"}, 通过@“GDT_TRANS_ID”可获取此次广告行为的交易id + */ +- (void)unifiedInterstitialAdDidRewardEffective:(GDTUnifiedInterstitialAd *)unifiedInterstitial info:(NSDictionary *)info{ + [[TLogUtil sharedInstance] print:@"插屏激励广告视频播放达到激励条件回调(只有插屏激励广告位才会有此回调)"]; + NSString *transId = info[@"GDT_TRANS_ID"]; + NSDictionary *dictionary = @{@"adType":@"interactAd",@"onAdMethod":@"onVerify",@"transId":transId}; + [[UnionAdSsgfEvent sharedInstance] sentEvent:dictionary]; +} + + +@end diff --git a/ios/Classes/native/NativeAd.h b/ios/Classes/native/NativeAd.h new file mode 100644 index 0000000..85bdce2 --- /dev/null +++ b/ios/Classes/native/NativeAd.h @@ -0,0 +1,20 @@ +#import +#import + +NS_ASSUME_NONNULL_BEGIN +@interface NaitveAdFactory : NSObject + +- (instancetype)initWithMessenger:(NSObject*)messager; + +@end + +@interface NativeAd : NSObject + +- (instancetype)initWithWithFrame:(CGRect)frame + viewIdentifier:(int64_t)viewId + arguments:(id _Nullable)args + binaryMessenger:(NSObject*)messenger; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Classes/native/NativeAd.m b/ios/Classes/native/NativeAd.m new file mode 100644 index 0000000..1a1e43e --- /dev/null +++ b/ios/Classes/native/NativeAd.m @@ -0,0 +1,255 @@ + +#import "NativeAd.h" +#import "GDTNativeExpressAd.h" +#import "TLogUtil.h" +#import "TUIViewController+getCurrentVC.h" +#import "GDTNativeExpressAdView.h" + +#pragma mark - NaitveAdFactory + +@implementation NaitveAdFactory{ + NSObject*_messenger; +} + +- (instancetype)initWithMessenger:(NSObject *)messager{ + self = [super init]; + if (self) { + _messenger = messager; + } + return self; +} + +-(NSObject *)createArgsCodec{ + return [FlutterStandardMessageCodec sharedInstance]; +} + +-(NSObject *)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id)args{ + NativeAd * nativeAd = [[NativeAd alloc] initWithWithFrame:frame viewIdentifier:viewId arguments:args binaryMessenger:_messenger]; + return nativeAd; +} +@end + +@interface NativeAd() + +@property (nonatomic, strong) GDTNativeExpressAd *native; +@property (nonatomic, strong) GDTNativeExpressAdView *nativeView; +@property(nonatomic,strong) UIView *container; +@property(nonatomic,assign) CGRect frame; +@property(nonatomic,assign) NSInteger viewId; +@property(nonatomic,strong) FlutterMethodChannel *channel; +@property(nonatomic,strong) NSString *codeId; +@property(nonatomic,assign) NSInteger viewWidth; +@property(nonatomic,assign) NSInteger viewHeight; +@property(nonatomic,assign) BOOL isBidding; +@end + +#pragma mark - NativeAd +@implementation NativeAd + +- (instancetype)initWithWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id)args binaryMessenger:(NSObject *)messenger{ + if ([super init]) { + NSDictionary *dic = args; + _frame = frame; + _viewId = viewId; + _codeId = dic[@"iosId"]; + _viewWidth =[dic[@"viewWidth"] intValue]; + _viewHeight =[dic[@"viewHeight"] intValue]; + self.isBidding =[dic[@"isBidding"] boolValue]; + NSString* channelName = [NSString stringWithFormat:@"com.example.union_ad_ssgf/NativeExpressAdView_%lld", viewId]; + _channel = [FlutterMethodChannel methodChannelWithName:channelName binaryMessenger:messenger]; + [self.channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { + // 竞价成功 + if ([@"biddingSucceeded" isEqualToString:call.method]) { + NSDictionary *dictionary = @{GDT_M_W_E_COST_PRICE:@([call.arguments[@"expectCostPrice"] intValue]), + GDT_M_W_H_LOSS_PRICE:@([call.arguments[@"highestLossPrice"] intValue])}; + [self.native sendWinNotificationWithInfo:dictionary]; + [_container addSubview:self.nativeView]; + [self.nativeView render]; + //竞价失败 + } else if([@"biddingFail" isEqualToString:call.method]) { + NSDictionary *dictionary = @{GDT_M_L_WIN_PRICE:@([call.arguments[@"winPrice"] intValue]), + GDT_M_L_LOSS_REASON:@([call.arguments[@"lossReason"] intValue]), + GDT_M_ADNID: call.arguments[@"adnId"]}; + [self.native sendWinNotificationWithInfo:dictionary]; + } + }]; + _container = [[UIView alloc] initWithFrame:frame]; + [self loadNativeAd]; + } + return self; +} + +- (UIView*)view{ + return _container; +} + +-(void)loadNativeAd{ + [_container removeFromSuperview]; + CGSize size = CGSizeMake(_viewWidth, _viewHeight); + if(_native == nil){ + _native =[[GDTNativeExpressAd alloc] initWithPlacementId:_codeId adSize:size]; + _native.delegate = self; + } + [_native loadAd:1]; +} + +#pragma mark - 广告请求delegate +/** + * 拉取原生模板广告成功 + */ +- (void)nativeExpressAdSuccessToLoad:(GDTNativeExpressAd *)nativeExpressAd views:(NSArray<__kindof GDTNativeExpressAdView *> *)views{ + [[TLogUtil sharedInstance] print:@"拉取原生模板广告成功"]; + if (views.count) { + [views enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + self.nativeView = (GDTNativeExpressAdView *)obj; + self.nativeView.controller = [UIViewController jsd_getCurrentViewController]; + //是否开启竞价 + if(self.isBidding){ + NSDictionary *dictionary = @{@"ecpmLevel":self.nativeView.eCPMLevel == nil ? @"" : self.nativeView.eCPMLevel,@"ecpm":@(self.nativeView.eCPM)}; + [_channel invokeMethod:@"onECPM" arguments:dictionary result:nil]; + }else{ + [_container addSubview:self.nativeView]; + [self.nativeView render]; + } + }]; + } +} + +/** + * 拉取原生模板广告失败 + */ +- (void)nativeExpressAdFailToLoad:(GDTNativeExpressAd *)nativeExpressAd error:(NSError *)error{ + [[TLogUtil sharedInstance] print:(@"拉取原生模板广告失败 %@",error.description)]; + NSDictionary *dictionary = @{@"code":@(-1),@"message":(@"%@",error.description)}; + [_channel invokeMethod:@"onFail" arguments:dictionary result:nil]; +} + + +/** + * 原生模板广告渲染成功, 此时的 nativeExpressAdView.size.height 根据 size.width 完成了动态更新。 + */ +- (void)nativeExpressAdViewRenderSuccess:(GDTNativeExpressAdView *)nativeExpressAdView{ + [[TLogUtil sharedInstance] print:@"原生模板广告渲染成功"]; + NSDictionary *dictionary = @{@"width": @(nativeExpressAdView.frame.size.width),@"height":@(nativeExpressAdView.frame.size.height)}; + [_channel invokeMethod:@"onShow" arguments:dictionary result:nil]; +} + + +/** + * 原生模板广告渲染失败 + */ +- (void)nativeExpressAdViewRenderFail:(GDTNativeExpressAdView *)nativeExpressAdView{ + [[TLogUtil sharedInstance] print:@"原生模板广告渲染失败"]; + NSDictionary *dictionary = @{@"code":@(-1),@"message":@"原生模板广告渲染失败"}; + [_channel invokeMethod:@"onFail" arguments:dictionary result:nil]; +} + + +/** + * 原生模板广告曝光回调 + */ +- (void)nativeExpressAdViewExposure:(GDTNativeExpressAdView *)nativeExpressAdView{ + [[TLogUtil sharedInstance] print:@"原生模板广告曝光回调"]; + [_channel invokeMethod:@"onExpose" arguments:nil result:nil]; +} + + +/** + * 原生模板广告点击回调 + */ +- (void)nativeExpressAdViewClicked:(GDTNativeExpressAdView *)nativeExpressAdView{ + [[TLogUtil sharedInstance] print:@"原生模板广告点击回调"]; + [_channel invokeMethod:@"onClick" arguments:nil result:nil]; +} + + +/** + * 原生模板广告被关闭 + */ +- (void)nativeExpressAdViewClosed:(GDTNativeExpressAdView *)nativeExpressAdView{ + [[TLogUtil sharedInstance] print:@"原生模板广告被关闭"]; + [_channel invokeMethod:@"onClose" arguments:nil result:nil]; +} + + +/** + * 点击原生模板广告以后即将弹出全屏广告页 + */ +- (void)nativeExpressAdViewWillPresentScreen:(GDTNativeExpressAdView *)nativeExpressAdView{ + [[TLogUtil sharedInstance] print:@"点击原生模板广告以后即将弹出全屏广告页"]; +} + + +/** + * 点击原生模板广告以后弹出全屏广告页 + */ +- (void)nativeExpressAdViewDidPresentScreen:(GDTNativeExpressAdView *)nativeExpressAdView{ + [[TLogUtil sharedInstance] print:@"点击原生模板广告以后弹出全屏广告页"]; +} + + +/** + * 全屏广告页将要关闭 + */ +- (void)nativeExpressAdViewWillDismissScreen:(GDTNativeExpressAdView *)nativeExpressAdView{ + [[TLogUtil sharedInstance] print:@"全屏广告页将要关闭"]; +} + + +/** + * 全屏广告页将要关闭 + */ +- (void)nativeExpressAdViewDidDismissScreen:(GDTNativeExpressAdView *)nativeExpressAdView{ + [[TLogUtil sharedInstance] print:@"全屏广告页将要关闭"]; +} + + +/** + * 详解:当点击应用下载或者广告调用系统程序打开时调用 + */ +- (void)nativeExpressAdViewApplicationWillEnterBackground:(GDTNativeExpressAdView *)nativeExpressAdView{ + [[TLogUtil sharedInstance] print:@"详解:当点击应用下载或者广告调用系统程序打开时调用"]; +} + + +/** + * 原生模板视频广告 player 播放状态更新回调 + */ +- (void)nativeExpressAdView:(GDTNativeExpressAdView *)nativeExpressAdView playerStatusChanged:(GDTMediaPlayerStatus)status{ + [[TLogUtil sharedInstance] print:@"原生模板视频广告 player 播放状态更新回调"]; +} + + +/** + * 原生视频模板详情页 WillPresent 回调 + */ +- (void)nativeExpressAdViewWillPresentVideoVC:(GDTNativeExpressAdView *)nativeExpressAdView{ + [[TLogUtil sharedInstance] print:@"原生视频模板详情页 WillPresent 回调"]; +} + + +/** + * 原生视频模板详情页 DidPresent 回调 + */ +- (void)nativeExpressAdViewDidPresentVideoVC:(GDTNativeExpressAdView *)nativeExpressAdView{ + [[TLogUtil sharedInstance] print:@"原生视频模板详情页 DidPresent 回调"]; +} + + +/** + * 原生视频模板详情页 WillDismiss 回调 + */ +- (void)nativeExpressAdViewWillDismissVideoVC:(GDTNativeExpressAdView *)nativeExpressAdView{ + [[TLogUtil sharedInstance] print:@" 原生视频模板详情页 WillDismiss 回调"]; +} + + +/** + * 原生视频模板详情页 DidDismiss 回调 + */ +- (void)nativeExpressAdViewDidDismissVideoVC:(GDTNativeExpressAdView *)nativeExpressAdView;{ + [[TLogUtil sharedInstance] print:@"原生视频模板详情页 DidDismiss 回调"]; +} + + +@end diff --git a/ios/Classes/reward/RewardAd.h b/ios/Classes/reward/RewardAd.h new file mode 100644 index 0000000..5f94be7 --- /dev/null +++ b/ios/Classes/reward/RewardAd.h @@ -0,0 +1,13 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface RewardAd : NSObject + ++ (instancetype)sharedInstance; +- (void)initAd:(NSDictionary *)arguments; +- (void)showAd:(NSDictionary *)arguments; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Classes/reward/RewardAd.m b/ios/Classes/reward/RewardAd.m new file mode 100644 index 0000000..9e4625a --- /dev/null +++ b/ios/Classes/reward/RewardAd.m @@ -0,0 +1,201 @@ +#import "RewardAd.h" +#import "GDTRewardVideoAd.h" +#import "UnionAdSsgfEvent.h" +#import "TLogUtil.h" +#import "TUIViewController+getCurrentVC.h" + +@interface RewardAd() + +@property(nonatomic,strong) GDTRewardVideoAd *reward; +@property(nonatomic,strong) NSString *codeId; +@property(nonatomic,strong) NSString *rewardName; +@property(nonatomic,strong) NSString *rewardAmount; +@property(nonatomic,strong) NSString *userID; +@property(nonatomic,strong) NSString *customData; +@property(nonatomic,assign) BOOL isBidding; +@end + +@implementation RewardAd + ++ (instancetype)sharedInstance{ + static RewardAd *myInstance = nil; + if(myInstance == nil){ + myInstance = [[RewardAd alloc]init]; + } + return myInstance; +} + +//预加载激励广告 +-(void)initAd:(NSDictionary*)arguments{ + NSDictionary *dic = arguments; + _codeId = dic[@"iosId"]; + _rewardName = dic[@"rewardName"]; + _rewardAmount = dic[@"rewardAmount"]; + _userID =dic[@"userID"]; + _customData = dic[@"customData"]; + _reward = [[GDTRewardVideoAd alloc] initWithPlacementId:_codeId]; + _reward.delegate = self; + _reward.videoMuted = dic[@"videoMuted"]; + self.isBidding =[dic[@"isBidding"] boolValue]; + GDTServerSideVerificationOptions *options = [[GDTServerSideVerificationOptions alloc] init]; + options.userIdentifier = _userID; + options.customRewardString = _customData; + _reward.serverSideVerificationOptions = options; + [_reward loadAd]; +} + +//展示广告 +-(void)showAd:(NSDictionary*)arguments{ + if (_reward.expiredTimestamp <= [[NSDate date] timeIntervalSince1970]) { + [[TLogUtil sharedInstance] print:(@"广告已过期,请重新拉取")]; + NSDictionary *dictionary = @{@"adType":@"rewardAd",@"onAdMethod":@"onFail",@"code":@(-1),@"message":@"广告已过期,请重新拉取"}; + [[UnionAdSsgfEvent sharedInstance] sentEvent:dictionary]; + return; + } + if (!_reward.isAdValid) { + [[TLogUtil sharedInstance] print:(@"广告失效,请重新拉取")]; + NSDictionary *dictionary = @{@"adType":@"rewardAd",@"onAdMethod":@"onFail",@"code":@(-1),@"message":@"广告失效,请重新拉取"}; + [[UnionAdSsgfEvent sharedInstance] sentEvent:dictionary]; + return; + } + if(self.isBidding){ + BOOL isSuccess = [arguments[@"isSuccess"] boolValue]; + if(isSuccess){ + NSDictionary *dictionary = @{GDT_M_W_E_COST_PRICE:@([arguments[@"expectCostPrice"] intValue]), + GDT_M_W_H_LOSS_PRICE:@([arguments[@"highestLossPrice"] intValue])}; + [self.reward sendWinNotificationWithInfo:dictionary]; + [self.reward showAdFromRootViewController:[UIViewController jsd_getCurrentViewController]]; + }else{ + NSDictionary *dictionary = @{GDT_M_L_WIN_PRICE:@([arguments[@"winPrice"] intValue]), + GDT_M_L_LOSS_REASON:@([arguments[@"lossReason"] intValue]), + GDT_M_ADNID: arguments[@"adnId"]}; + [self.reward sendWinNotificationWithInfo:dictionary]; + } + }else{ + [self.reward showAdFromRootViewController:[UIViewController jsd_getCurrentViewController]]; + } + +} + +#pragma mark - 广告请求delegate + +/** + 广告数据加载成功回调 + + @param rewardedVideoAd GDTRewardVideoAd 实例 + */ +- (void)gdt_rewardVideoAdDidLoad:(GDTRewardVideoAd *)rewardedVideoAd{ + [[TLogUtil sharedInstance] print:(@"激励广告数据加载成功")]; + //是否开启竞价 + if(self.isBidding){ + NSDictionary *dictionary = @{@"adType":@"rewardAd",@"onAdMethod":@"onECPM",@"ecpmLevel":self.reward.eCPMLevel == nil ? @"" : self.reward.eCPMLevel,@"ecpm":@(self.reward.eCPM)}; + [[UnionAdSsgfEvent sharedInstance] sentEvent:dictionary]; + }else{ + NSDictionary *dictionary = @{@"adType":@"rewardAd",@"onAdMethod":@"onReady"}; + [[UnionAdSsgfEvent sharedInstance] sentEvent:dictionary]; + } + +} + +/** + 视频数据下载成功回调,已经下载过的视频会直接回调 + + @param rewardedVideoAd GDTRewardVideoAd 实例 + */ +- (void)gdt_rewardVideoAdVideoDidLoad:(GDTRewardVideoAd *)rewardedVideoAd{ + [[TLogUtil sharedInstance] print:(@"激励广告视频数据下载成功")]; +} + +/** + 视频播放页即将展示回调 + + @param rewardedVideoAd GDTRewardVideoAd 实例 + */ +- (void)gdt_rewardVideoAdWillVisible:(GDTRewardVideoAd *)rewardedVideoAd{ + [[TLogUtil sharedInstance] print:(@"激励广告视频播放页即将展示回调")]; + NSDictionary *dictionary = @{@"adType":@"rewardAd",@"onAdMethod":@"onShow"}; + [[UnionAdSsgfEvent sharedInstance] sentEvent:dictionary]; +} + +/** + 视频广告曝光回调 + + @param rewardedVideoAd GDTRewardVideoAd 实例 + */ +- (void)gdt_rewardVideoAdDidExposed:(GDTRewardVideoAd *)rewardedVideoAd{ + [[TLogUtil sharedInstance] print:(@"激励广告曝光")]; + NSDictionary *dictionary = @{@"adType":@"rewardAd",@"onAdMethod":@"onExpose"}; + [[UnionAdSsgfEvent sharedInstance] sentEvent:dictionary]; +} + +/** + 视频播放页关闭回调 + + @param rewardedVideoAd GDTRewardVideoAd 实例 + */ +- (void)gdt_rewardVideoAdDidClose:(GDTRewardVideoAd *)rewardedVideoAd{ + [[TLogUtil sharedInstance] print:(@"激励广告关闭")]; + NSDictionary *dictionary = @{@"adType":@"rewardAd",@"onAdMethod":@"onClose"}; + [[UnionAdSsgfEvent sharedInstance] sentEvent:dictionary]; +} + +/** + 视频广告信息点击回调 + + @param rewardedVideoAd GDTRewardVideoAd 实例 + */ +- (void)gdt_rewardVideoAdDidClicked:(GDTRewardVideoAd *)rewardedVideoAd{ + [[TLogUtil sharedInstance] print:(@"激励广告点击")]; + NSDictionary *dictionary = @{@"adType":@"rewardAd",@"onAdMethod":@"onClick"}; + [[UnionAdSsgfEvent sharedInstance] sentEvent:dictionary]; +} + +/** + 视频广告各种错误信息回调 + + @param rewardedVideoAd GDTRewardVideoAd 实例 + @param error 具体错误信息 + */ +- (void)gdt_rewardVideoAd:(GDTRewardVideoAd *)rewardedVideoAd didFailWithError:(NSError *)error{ + [[TLogUtil sharedInstance] print:((void)(@"激励广告错误,%@"),error.description)]; + NSInteger code = error.code; + NSString *message = error.description; + NSDictionary *dictionary = @{@"adType":@"rewardAd",@"onAdMethod":@"onFail",@"code":@(code),@"message":message}; + [[UnionAdSsgfEvent sharedInstance] sentEvent:dictionary]; +} + +/** + 视频广告播放达到激励条件回调 + + @param rewardedVideoAd GDTRewardVideoAd 实例 + */ +- (void)gdt_rewardVideoAdDidRewardEffective:(GDTRewardVideoAd *)rewardedVideoAd GDT_DEPRECATED_MSG_ATTRIBUTE("接口即将废弃,请使用 gdt_rewardVideoAdDidRewardEffective:info:"){ + +} + + +/** + 视频广告播放达到激励条件回调 + + @param rewardedVideoAd GDTRewardVideoAd 实例 + @param info 包含此次广告行为的一些信息,例如 @{@"GDT_TRANS_ID":@"930f1fc8ac59983bbdf4548ee40ac353"}, 通过@“GDT_TRANS_ID”可获取此次广告行为的交易id + */ +- (void)gdt_rewardVideoAdDidRewardEffective:(GDTRewardVideoAd *)rewardedVideoAd info:(NSDictionary *)info{ + [[TLogUtil sharedInstance] print:(@"激励广告视频广告播放达到激励条件")]; + NSString *transId = info[@"GDT_TRANS_ID"]; + NSDictionary *dictionary = @{@"adType":@"rewardAd",@"onAdMethod":@"onVerify",@"transId":transId,@"rewardAmount":_rewardAmount,@"rewardName":_rewardName}; + [[UnionAdSsgfEvent sharedInstance] sentEvent:dictionary]; +} + +/** + 视频广告视频播放完成 + + @param rewardedVideoAd GDTRewardVideoAd 实例 + */ +- (void)gdt_rewardVideoAdDidPlayFinish:(GDTRewardVideoAd *)rewardedVideoAd{ + [[TLogUtil sharedInstance] print:(@"激励广告视频广告视频播放完成")]; + NSDictionary *dictionary = @{@"adType":@"rewardAd",@"onAdMethod":@"onFinish"}; + [[UnionAdSsgfEvent sharedInstance] sentEvent:dictionary]; +} + +@end diff --git a/ios/Classes/splash/SplashAd.h b/ios/Classes/splash/SplashAd.h new file mode 100644 index 0000000..cab0ba5 --- /dev/null +++ b/ios/Classes/splash/SplashAd.h @@ -0,0 +1,22 @@ +#import + +#import + +NS_ASSUME_NONNULL_BEGIN +@interface SplashAdFactory : NSObject + +- (instancetype)initWithMessenger:(NSObject*)messager; + +@end + +@interface SplashAd : NSObject + +- (instancetype)initWithWithFrame:(CGRect)frame + viewIdentifier:(int64_t)viewId + arguments:(id _Nullable)args + binaryMessenger:(NSObject*)messenger; + +@end + +NS_ASSUME_NONNULL_END + diff --git a/ios/Classes/splash/SplashAd.m b/ios/Classes/splash/SplashAd.m new file mode 100644 index 0000000..fb1ada0 --- /dev/null +++ b/ios/Classes/splash/SplashAd.m @@ -0,0 +1,199 @@ +#import "SplashAd.h" +#import "GDTSplashAd.h" +#import "TLogUtil.h" + +@implementation SplashAdFactory{ + NSObject*_messenger; +} + +- (instancetype)initWithMessenger:(NSObject *)messager{ + self = [super init]; + if (self) { + _messenger = messager; + } + return self; +} + +-(NSObject *)createArgsCodec{ + return [FlutterStandardMessageCodec sharedInstance]; +} + +-(NSObject *)createWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id)args{ + SplashAd * splashAd = [[SplashAd alloc] initWithWithFrame:frame viewIdentifier:viewId arguments:args binaryMessenger:_messenger]; + + return splashAd; + +} + +@end + + +@interface SplashAd() + +@property (nonatomic, strong) GDTSplashAd *splash; +@property(nonatomic,strong) UIView *container; +@property(nonatomic,assign) CGRect frame; +@property(nonatomic,assign) NSInteger viewId; +@property(nonatomic,strong) FlutterMethodChannel *channel; +@property(nonatomic,strong) NSString *codeId; +@property(nonatomic,assign) NSInteger fetchDelay; +@property(nonatomic,assign) BOOL isBidding; +@end + +@implementation SplashAd + +- (instancetype)initWithWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id)args binaryMessenger:(NSObject *)messenger{ + if ([super init]) { + NSDictionary *dic = args; + _frame = frame; + _viewId = viewId; + _codeId = dic[@"iosId"]; + _fetchDelay =[dic[@"_fetchDelay"] intValue]; + self.isBidding =[dic[@"isBidding"] boolValue]; + NSString* channelName = [NSString stringWithFormat:@"com.example.union_ad_ssgf/SplashAdView_%lld", viewId]; + _channel = [FlutterMethodChannel methodChannelWithName:channelName binaryMessenger:messenger]; + [self.channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { + // 竞价成功 + if ([@"biddingSucceeded" isEqualToString:call.method]) { + NSDictionary *dictionary = @{GDT_M_W_E_COST_PRICE:@([call.arguments[@"expectCostPrice"] intValue]), + GDT_M_W_H_LOSS_PRICE:@([call.arguments[@"highestLossPrice"] intValue])}; + [self.splash sendWinNotificationWithInfo:dictionary]; + //展示广告 + [self.splash showFullScreenAdInWindow:[UIApplication sharedApplication].keyWindow withLogoImage:nil skipView:nil]; + //竞价失败 + } else if([@"biddingFail" isEqualToString:call.method]) { + NSDictionary *dictionary = @{GDT_M_L_WIN_PRICE:@([call.arguments[@"winPrice"] intValue]), + GDT_M_L_LOSS_REASON:@([call.arguments[@"lossReason"] intValue]), + GDT_M_ADNID: call.arguments[@"adnId"]}; + [self.splash sendWinNotificationWithInfo:dictionary]; + } + }]; + [self loadSplashAd]; + } + return self; +} + +- (UIView*)view{ + return _container; +} + +-(void)loadSplashAd{ + _splash = [[GDTSplashAd alloc] initWithPlacementId:_codeId]; + _splash.delegate = self; + _splash.fetchDelay = _fetchDelay; + [_splash loadFullScreenAd]; +} + +#pragma mark - 广告请求delegate + +/** + * 开屏广告成功展示 + */ +- (void)splashAdSuccessPresentScreen:(GDTSplashAd *)splashAd{ + [[TLogUtil sharedInstance] print:@"开屏广告成功展示"]; + [_channel invokeMethod:@"onShow" arguments:nil result:nil]; +} + +/** + * 开屏广告素材加载成功 + */ +- (void)splashAdDidLoad:(GDTSplashAd *)splashAd{ + [[TLogUtil sharedInstance] print:@"开屏广告素材加载成功"]; + if(!splashAd.isAdValid){ + [[TLogUtil sharedInstance] print:@"开屏广告展示失败"]; + NSDictionary *dictionary = @{@"code":@(-1),@"message":@"广告展示失败"}; + [_channel invokeMethod:@"onFail" arguments:dictionary result:nil]; + return; + } + //是否开启竞价 + if(self.isBidding){ + NSDictionary *dictionary = @{@"ecpmLevel":self.splash.eCPMLevel == nil ? @"" : self.splash.eCPMLevel,@"ecpm":@(self.splash.eCPM)}; + [_channel invokeMethod:@"onECPM" arguments:dictionary result:nil]; + }else{ + [self.splash showFullScreenAdInWindow:[UIApplication sharedApplication].keyWindow withLogoImage:nil skipView:nil]; + } +} + +/** + * 开屏广告展示失败 + */ +- (void)splashAdFailToPresent:(GDTSplashAd *)splashAd withError:(NSError *)error{ + [[TLogUtil sharedInstance] print:@"开屏广告展示失败"]; + NSDictionary *dictionary = @{@"code":@(-1),@"message":((void)(@"广告展示失败%@"),error.description)}; + [_channel invokeMethod:@"onFail" arguments:dictionary result:nil]; +} + +/** + * 应用进入后台时回调 + * 详解: 当点击下载应用时会调用系统程序打开,应用切换到后台 + */ +- (void)splashAdApplicationWillEnterBackground:(GDTSplashAd *)splashAd{ + [[TLogUtil sharedInstance] print:@"应用进入后台时回调"]; +} + +/** + * 开屏广告曝光回调 + */ +- (void)splashAdExposured:(GDTSplashAd *)splashAd{ + [[TLogUtil sharedInstance] print:@" 开屏广告曝光回调"]; + [_channel invokeMethod:@"onExpose" arguments:nil result:nil]; +} + +/** + * 开屏广告点击回调 + */ +- (void)splashAdClicked:(GDTSplashAd *)splashAd{ + [[TLogUtil sharedInstance] print:@"开屏广告点击回调"]; + [_channel invokeMethod:@"onClick" arguments:nil result:nil]; +} + +/** + * 开屏广告将要关闭回调 + */ +- (void)splashAdWillClosed:(GDTSplashAd *)splashAd{ + [[TLogUtil sharedInstance] print:@"开屏广告将要关闭回调"]; + [_channel invokeMethod:@"onClose" arguments:nil result:nil]; +} + +/** + * 开屏广告关闭回调 + */ +- (void)splashAdClosed:(GDTSplashAd *)splashAd{ + [[TLogUtil sharedInstance] print:@"开屏广告关闭回调"]; +} + +/** + * 开屏广告点击以后即将弹出全屏广告页 + */ +- (void)splashAdWillPresentFullScreenModal:(GDTSplashAd *)splashAd{ + [[TLogUtil sharedInstance] print:@"开屏广告点击以后即将弹出全屏广告页"]; +} + +/** + * 开屏广告点击以后弹出全屏广告页 + */ +- (void)splashAdDidPresentFullScreenModal:(GDTSplashAd *)splashAd{ + [[TLogUtil sharedInstance] print:@"开屏广告点击以后弹出全屏广告页"]; +} + +/** + * 点击以后全屏广告页将要关闭 + */ +- (void)splashAdWillDismissFullScreenModal:(GDTSplashAd *)splashAd{ + [[TLogUtil sharedInstance] print:@"点击以后全屏广告页将要关闭"]; +} +/** + * 点击以后全屏广告页已经关闭 + */ +- (void)splashAdDidDismissFullScreenModal:(GDTSplashAd *)splashAd{ + [[TLogUtil sharedInstance] print:@" 点击以后全屏广告页已经关闭"]; +} + +/** + * 开屏广告剩余时间回调 + */ +- (void)splashAdLifeTime:(NSUInteger)time;{ + NSString *timeStr =[NSString stringWithFormat:@"开屏广告剩余时间回调%lu",(unsigned long)time]; + [[TLogUtil sharedInstance] print:timeStr]; +} +@end diff --git a/ios/Classes/utils/TLogUtil.h b/ios/Classes/utils/TLogUtil.h new file mode 100644 index 0000000..79b79ce --- /dev/null +++ b/ios/Classes/utils/TLogUtil.h @@ -0,0 +1,15 @@ +#ifdef DEBUG +#define GLog(...) NSLog(@"%s\n %@\n\n", __func__, [NSString stringWithFormat:__VA_ARGS__]) +#else +#define GLog(...) +#endif + +NS_ASSUME_NONNULL_BEGIN + +@interface TLogUtil : NSObject ++ (instancetype)sharedInstance; +- (void)debug:(BOOL)isDebug; +- (void)print:(NSString *)message; +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Classes/utils/TLogUtil.m b/ios/Classes/utils/TLogUtil.m new file mode 100644 index 0000000..3cf2e88 --- /dev/null +++ b/ios/Classes/utils/TLogUtil.m @@ -0,0 +1,29 @@ +#import +#import "TLogUtil.h" + +@interface TLogUtil() +@property(nonatomic,assign) BOOL isDebug; +@end + + +@implementation TLogUtil + ++ (instancetype)sharedInstance{ + static TLogUtil *myInstance = nil; + if(myInstance == nil){ + myInstance = [[TLogUtil alloc]init]; + } + return myInstance; +} + +- (void)debug:(BOOL)isDebug{ + _isDebug = isDebug; +} + +- (void)print:(NSString *)message{ + if(_isDebug){ + GLog(@"%@", message); + } +} + +@end diff --git a/ios/Classes/utils/TUIViewController+getCurrentVC.h b/ios/Classes/utils/TUIViewController+getCurrentVC.h new file mode 100644 index 0000000..b5416ce --- /dev/null +++ b/ios/Classes/utils/TUIViewController+getCurrentVC.h @@ -0,0 +1,19 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface UIViewController (getCurrentVC) + ++ (UIViewController *)jsd_getCurrentViewController; + ++ (UIViewController *)jsd_getRootViewController; + ++ (UIViewController *)getCurrentVCWithCurrentView:(UIView *)currentView; + ++(UITabBarController *)currentTtabarController; + ++(UINavigationController *)currentTabbarSelectedNavigationController; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Classes/utils/TUIViewController+getCurrentVC.m b/ios/Classes/utils/TUIViewController+getCurrentVC.m new file mode 100644 index 0000000..aaeb750 --- /dev/null +++ b/ios/Classes/utils/TUIViewController+getCurrentVC.m @@ -0,0 +1,89 @@ +#import "TUIViewController+getCurrentVC.h" + +@implementation UIViewController (getCurrentVC) + + ++ (UIViewController *)jsd_getRootViewController{ + + UIWindow* window = [[[UIApplication sharedApplication] delegate] window]; + //NSAssert(window, @"The window is empty"); + return window.rootViewController; +} + ++ (UIViewController *)jsd_getCurrentViewController{ + + UIViewController* currentViewController = [self jsd_getRootViewController]; + BOOL runLoopFind = YES; + while (runLoopFind) { + if (currentViewController.presentedViewController) { + + currentViewController = currentViewController.presentedViewController; + } else if ([currentViewController isKindOfClass:[UINavigationController class]]) { + + UINavigationController* navigationController = (UINavigationController* )currentViewController; + currentViewController = [navigationController.childViewControllers lastObject]; + + } else if ([currentViewController isKindOfClass:[UITabBarController class]]) { + + UITabBarController* tabBarController = (UITabBarController* )currentViewController; + currentViewController = tabBarController.selectedViewController; + } else { + + NSUInteger childViewControllerCount = currentViewController.childViewControllers.count; + if (childViewControllerCount > 0) { + + currentViewController = currentViewController.childViewControllers.lastObject; + + return currentViewController; + } else { + + return currentViewController; + } + } + + } + return currentViewController; +} + ++ (UIViewController *)getCurrentVCWithCurrentView:(UIView *)currentView +{ + for (UIView *next = currentView ; next ; next = next.superview) { + UIResponder *nextResponder = [next nextResponder]; + if ([nextResponder isKindOfClass:[UIViewController class]]) { + return (UIViewController *)nextResponder; + } + } + return nil; +} + + ++(UITabBarController *)currentTtabarController +{ + UIWindow * window = [[UIApplication sharedApplication] keyWindow]; + UIViewController *tabbarController = window.rootViewController; + if ([tabbarController isKindOfClass:[UITabBarController class]]) { + return (UITabBarController *)tabbarController; + } + return nil; +} + ++(UINavigationController *)currentTabbarSelectedNavigationController +{ + UIWindow * window = [[UIApplication sharedApplication] keyWindow]; + UIViewController *rootVC = window.rootViewController; + if ([rootVC isKindOfClass:[UINavigationController class]]) { + return (UINavigationController *)rootVC; + }else if([rootVC isKindOfClass:[UITabBarController class]]){ + UITabBarController *tabarController = [self currentTtabarController]; + UINavigationController *selectedNV = (UINavigationController *)tabarController.selectedViewController; + if ([selectedNV isKindOfClass:[UINavigationController class]]) { + return selectedNV; + } + } + + return nil; +} + + + +@end