diff --git a/Podfile b/Podfile index 41390d7..19eb559 100644 --- a/Podfile +++ b/Podfile @@ -18,7 +18,7 @@ target 'WOKA' do # Google Ads pod 'Google-Mobile-Ads-SDK' - + #JwPlayer # pod 'JWPlayerKit' diff --git a/WOKA.xcodeproj/project.pbxproj b/WOKA.xcodeproj/project.pbxproj index 254618b..fd37fe7 100644 --- a/WOKA.xcodeproj/project.pbxproj +++ b/WOKA.xcodeproj/project.pbxproj @@ -111,6 +111,7 @@ 527AC6FD2C173A5100434FB7 /* SongListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527AC6FB2C173A5100434FB7 /* SongListCell.swift */; }; 527AC6FE2C173A5100434FB7 /* SongListCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 527AC6FC2C173A5100434FB7 /* SongListCell.xib */; }; 527AC7012C182DCE00434FB7 /* TimeStringToSeconds.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527AC7002C182DCE00434FB7 /* TimeStringToSeconds.swift */; }; + 5282DB292C92D73B00465BA1 /* GoogleInteractiveMediaAds in Frameworks */ = {isa = PBXBuildFile; productRef = 5282DB282C92D73B00465BA1 /* GoogleInteractiveMediaAds */; }; 528BEF602C2C372900FFDAB8 /* ContinueWatchingVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 528BEF5F2C2C372900FFDAB8 /* ContinueWatchingVC.swift */; }; 528E5F1B2C24531200E33E4E /* SeasonListingDM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 528E5F1A2C24531200E33E4E /* SeasonListingDM.swift */; }; 528E5F222C24660F00E33E4E /* SeasonCategoryCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 528E5F202C24660F00E33E4E /* SeasonCategoryCell.swift */; }; @@ -776,6 +777,7 @@ 528F26F22C6B7BD1003E4D99 /* OneSignalInAppMessages in Frameworks */, 9CBA53102C89A2680046735C /* FirebasePerformance in Frameworks */, 521CB1002C493DB80085BDF8 /* JWPlayerKit in Frameworks */, + 5282DB292C92D73B00465BA1 /* GoogleInteractiveMediaAds in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2038,6 +2040,7 @@ 9CBA530F2C89A2680046735C /* FirebasePerformance */, 9CF6980A2C89A324006007EF /* Lottie */, 9CF6980E2C8AFFBF006007EF /* SDWebImage */, + 5282DB282C92D73B00465BA1 /* GoogleInteractiveMediaAds */, ); productName = WOKA; productReference = 523ED25A2BDA2BC700CFED02 /* WOKA.app */; @@ -2142,6 +2145,7 @@ 9CBA530A2C89A2680046735C /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, 9CF698092C89A324006007EF /* XCRemoteSwiftPackageReference "lottie-spm" */, 9CF6980D2C8AFFBF006007EF /* XCRemoteSwiftPackageReference "SDWebImage" */, + 5282DB272C92D73B00465BA1 /* XCRemoteSwiftPackageReference "swift-package-manager-google-interactive-media-ads-ios" */, ); productRefGroup = 523ED25B2BDA2BC700CFED02 /* Products */; projectDirPath = ""; @@ -3106,6 +3110,14 @@ version = 4.19.1; }; }; + 5282DB272C92D73B00465BA1 /* XCRemoteSwiftPackageReference "swift-package-manager-google-interactive-media-ads-ios" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/googleads/swift-package-manager-google-interactive-media-ads-ios"; + requirement = { + branch = main; + kind = branch; + }; + }; 528F26EC2C6B7BD1003E4D99 /* XCRemoteSwiftPackageReference "OneSignal-XCFramework" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/OneSignal/OneSignal-XCFramework"; @@ -3154,6 +3166,11 @@ package = 521CB0FE2C493DB80085BDF8 /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */; productName = JWPlayerKit; }; + 5282DB282C92D73B00465BA1 /* GoogleInteractiveMediaAds */ = { + isa = XCSwiftPackageProductDependency; + package = 5282DB272C92D73B00465BA1 /* XCRemoteSwiftPackageReference "swift-package-manager-google-interactive-media-ads-ios" */; + productName = GoogleInteractiveMediaAds; + }; 528F26ED2C6B7BD1003E4D99 /* OneSignalExtension */ = { isa = XCSwiftPackageProductDependency; package = 528F26EC2C6B7BD1003E4D99 /* XCRemoteSwiftPackageReference "OneSignal-XCFramework" */; diff --git a/WOKA/Main/JWPlayerManager.swift b/WOKA/Main/JWPlayerManager.swift index 0e30241..2c85507 100644 --- a/WOKA/Main/JWPlayerManager.swift +++ b/WOKA/Main/JWPlayerManager.swift @@ -102,6 +102,96 @@ class JWPlayerManager { return } + // Create the ad break +// let adBreakBuilder = JWAdBreakBuilder() +// .offset(.preroll()) +// .tags([URL(string: "https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/single_preroll_skippable&sz=640x480&ciu_szs=300x250%2C728x90&gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&impl=s&correlator=")!]) +// +// +// +// guard let adBreak = try? adBreakBuilder.build() else { +// print("Ad error") +// // Handle build error +// return +// } +// +// // Create the ad config +// let adConfigBuilder = JWImaAdvertisingConfigBuilder() +// .schedule([adBreak]) +// guard let adConfig = try? adConfigBuilder.build() else { +// // Handle build error +// return +// } +// let adBreakBuilder1 = JWAdBreakBuilder() +// .offset(.preroll()) +// .tags([URL(string: "https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/single_preroll_skippable&sz=640x480&ciu_szs=300x250%2C728x90&gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&impl=s&correlator=")!]) +// guard let adBreak1 = try? adBreakBuilder1.build() else { +// // Handle build error +// return +// } + +// let adBreakBuilder = JWAdBreakBuilder() +// .offset(.preroll()) +// .tags([URL(string: generateAdTagUrl())!]) +// guard let adBreak = try? adBreakBuilder.build() else { +// print("Ad error") +// // Handle build error +// return +// } + + // Create an ad break for 30% into the video + let adBreakBuilder2 = JWAdBreakBuilder() + .offset(.from(string: "pre")!) + + .tags([URL(string: generateAdTagUrl())!]) + + guard let adBreak2 = try? adBreakBuilder2.build() else { + print("Ad error 1") + // Handle build error + return + } + + // Create an ad break for 30% into the video + let adBreakBuilder1 = JWAdBreakBuilder() +// .offset(.midroll(percent: 50)) + .offset(.from(string: "20%")!) + .tags([URL(string: generateAdTagUrl())!]) + + guard let adBreak1 = try? adBreakBuilder1.build() else { + print("Ad error 2") + // Handle build error + return + } + + let adBreakBuilder3 = JWAdBreakBuilder() +// .offset(.midroll(percent: 50)) + .offset(.from(string: "50%")!) + .tags([URL(string: generateAdTagUrl())!]) + + guard let adBreak3 = try? adBreakBuilder3.build() else { + print("Ad error 2") + // Handle build error + return + } + + // Create an ad break for 30% into the video +// let adBreakBuilder3 = JWAdBreakBuilder() +// .offset(.postroll()) +// .tags([URL(string: "https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/single_preroll_skippable&sz=640x480&ciu_szs=300x250%2C728x90&gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&impl=s&correlator=60")!]) +// +// guard let adBreak3 = try? adBreakBuilder3.build() else { +// // Handle build error +// return +// } + + let adConfigBuilder = JWImaAdvertisingConfigBuilder() + .schedule([adBreak1,adBreak3]) + guard let adConfig = try? adConfigBuilder.build() else { + + // Handle build error + return + } + let finalConfig : JWPlayerConfiguration? switch contentType{ @@ -114,6 +204,8 @@ class JWPlayerManager { finalConfig = try JWPlayerConfigurationBuilder() .playlist(items: items) .autostart(false) + .advertising(adConfig) +// .playerId("X57dFDmV") .build() case .trailer: finalConfig = try JWPlayerConfigurationBuilder() @@ -127,7 +219,7 @@ class JWPlayerManager { .autostart(false) .build() } - + DispatchQueue.main.async { playerVC.videoIndex = startIndex playerVC.contentType = contentType @@ -154,3 +246,8 @@ class JWPlayerManager { } } } + +func generateAdTagUrl() -> String { + let correlatorValue = Int(Date().timeIntervalSince1970 * 1000) + return "https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/single_preroll_skippable&sz=640x480&ciu_szs=300x250,728x90&gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&impl=s&correlator=\(correlatorValue)" +} diff --git a/WOKA/Theme/Controller/PlayerVC.swift b/WOKA/Theme/Controller/PlayerVC.swift index f666f51..c68c951 100644 --- a/WOKA/Theme/Controller/PlayerVC.swift +++ b/WOKA/Theme/Controller/PlayerVC.swift @@ -430,6 +430,68 @@ extension PlayerVC { } } +// MARK: - Handle ADs + +extension PlayerVC{ + // Reports when an event is emitted by the player. +// override func jwplayer(_ player: JWPlayer, adEvent event: JWAdEvent) { +// super.jwplayer(player, adEvent: event) +// +// switch event.type { +// case .adBreakStart: +// print("The ad break has begun") +// case .schedule: +// print("The ad(s) has been scheduled") +// case .request: +// print("The ad has been requested") +// case .started: +// print("The ad playback has started") +// case .impression: +// print("The ad impression has been fulfilled") +// case .meta: +// print("The ad metadata is ready") +// case .clicked: +// print("The ad has been tapped") +// case .pause: +// print("The ad playback has been paused") +// case .play: +// print("The ad playback has been resumed") +// case .skipped: +// print("The ad has been skipped") +// case .complete: +// print("The ad playback has finished") +// case .adBreakEnd: +// print("The ad break has finished") +// default: +// break +// } +// } +// +// // This method is triggered when a time event fires for a currently playing ad. +// override func onAdTimeEvent(_ time: JWTimeData) { +// super.onAdTimeEvent(time) +// +// // If you are not interested in the ad time data, avoid overriding this method due to performance reasons. +// } +// +// // When the player encounters an ad warning within the SDK, this method is called on the delegate. +// // Ad warnings do not prevent the ad from continuing to play. +// override func jwplayer(_ player: JWPlayer, encounteredAdWarning code: UInt, message: String) { +// super.jwplayer(player, encounteredAdWarning: code, message: message) +// +// print("An ad warning has been encountered: (\(code))-\(message)") +// } +// +// // When the player encounters an ad error within the SDK, this method is called on the delegate. +// // Ad errors prevent ads from playing, but do not prevent media playback from continuing. +// override func jwplayer(_ player: JWPlayer, encounteredAdError code: UInt, message: String) { +// super.jwplayer(player, encounteredAdError: code, message: message) +// +// print("An ad error has been encountered: (\(code))-\(message)") +// } +} + + // MARK: - JWPlayerViewController Delegate Functions extension PlayerVC { diff --git a/WOKA/Theme/ViewModel/ThemeOneVM.swift b/WOKA/Theme/ViewModel/ThemeOneVM.swift index 56ed94a..e9d2ddb 100644 --- a/WOKA/Theme/ViewModel/ThemeOneVM.swift +++ b/WOKA/Theme/ViewModel/ThemeOneVM.swift @@ -545,11 +545,34 @@ class ThemeOneVM{ .title(title) .build() + // Create the ad break + let adBreakBuilder = JWAdBreakBuilder() + .offset(.preroll()) + .tags([URL(string: "https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/single_preroll_skippable&sz=640x480&ciu_szs=300x250%2C728x90&gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&impl=s&correlator=")!]) + + + + guard let adBreak = try? adBreakBuilder.build() else { + print("Ad error") + // Handle build error + return + } + + // Create the ad config + let adConfigBuilder = JWImaAdvertisingConfigBuilder() + .schedule([adBreak]) + guard let adConfig = try? adConfigBuilder.build() else { + // Handle build error + return + } + // Create a JWPlayerConfiguration let config = try JWPlayerConfigurationBuilder() .playlist(items: [item]) - .preload(JWPreload(rawValue: 20) ?? .none) +// .preload(JWPreload(rawValue: 20) ?? .none) .autostart(true) + .advertising(adConfig) + .playerId("X57dFDmV") .build() vc.config = config diff --git a/WOKA/WebSeries/Controller/WebSeriesVC.swift b/WOKA/WebSeries/Controller/WebSeriesVC.swift index 6c019ef..11d5679 100644 --- a/WOKA/WebSeries/Controller/WebSeriesVC.swift +++ b/WOKA/WebSeries/Controller/WebSeriesVC.swift @@ -6,7 +6,6 @@ // import UIKit -import GoogleMobileAds protocol ReloadSeriesFavLike{ func updateRows(index : Int, type : FavCellCLick, isFav : Bool? , isLike : Bool?, id : Int?) @@ -107,25 +106,6 @@ class WebSeriesVC: UIViewController { super.viewDidLayoutSubviews() vm.updateTableHeight() - var bannerView = GADBannerView() - - let viewWidth = headerView.frame.inset(by: headerView.safeAreaInsets).width - - // Here the current interface orientation is used. Use - // GADLandscapeAnchoredAdaptiveBannerAdSizeWithWidth or - // GADPortraitAnchoredAdaptiveBannerAdSizeWithWidth if you prefer to load an ad of a - // particular orientation, - let adaptiveSize = GADPortraitAnchoredAdaptiveBannerAdSizeWithWidth(viewWidth) - bannerView = GADBannerView(adSize: adaptiveSize) - - bannerView.center = headerView.center - - bannerView.frame = CGRect(x: 0, y: 0, width: headerView.frame.width, height: headerView.frame.height) - headerView.addSubview(bannerView) - bannerView.adUnitID = K.GoogleAdIDs.themeTwo - bannerView.rootViewController = self - bannerView.load(GADRequest()) - bannerView.layoutIfNeeded() } // MARK: - Tap Handler diff --git a/WOKA/WebSeries/ViewModel/WebSeriesVM.swift b/WOKA/WebSeries/ViewModel/WebSeriesVM.swift index f5fc5ea..2fd0dce 100644 --- a/WOKA/WebSeries/ViewModel/WebSeriesVM.swift +++ b/WOKA/WebSeries/ViewModel/WebSeriesVM.swift @@ -7,6 +7,7 @@ import Foundation import Alamofire +import GoogleMobileAds class WebSeriesVM{ @@ -114,7 +115,25 @@ class WebSeriesVM{ } } }else{ + var bannerView = GADBannerView() + + let viewWidth = vc.headerView.frame.inset(by: vc.headerView.safeAreaInsets).width + + // Here the current interface orientation is used. Use + // GADLandscapeAnchoredAdaptiveBannerAdSizeWithWidth or + // GADPortraitAnchoredAdaptiveBannerAdSizeWithWidth if you prefer to load an ad of a + // particular orientation, + let adaptiveSize = GADPortraitAnchoredAdaptiveBannerAdSizeWithWidth(viewWidth) + bannerView = GADBannerView(adSize: adaptiveSize) + bannerView.center = vc.headerView.center + + bannerView.frame = CGRect(x: 0, y: 0, width: vc.headerView.frame.width, height: vc.headerView.frame.height) + vc.headerView.addSubview(bannerView) + bannerView.adUnitID = K.GoogleAdIDs.themeTwo + bannerView.rootViewController = self.vc + bannerView.load(GADRequest()) + bannerView.layoutIfNeeded() } }