Skip to content

Commit e47b3d8

Browse files
[interactive_media_ads] Adds internal wrapper for iOS native IMAAdPodInfo (#8429)
1 parent 9c9006f commit e47b3d8

File tree

11 files changed

+495
-7
lines changed

11 files changed

+495
-7
lines changed

packages/interactive_media_ads/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.2.3+6
2+
3+
* Adds internal wrapper for iOS native `IMAAdPodInfo`.
4+
15
## 0.2.3+5
26

37
* Bumps gradle-plugin to 2.1.0.

packages/interactive_media_ads/android/src/main/kotlin/dev/flutter/packages/interactive_media_ads/AdsRequestProxyApi.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class AdsRequestProxyApi(override val pigeonRegistrar: ProxyApiRegistrar) :
2121
*
2222
* This must match the version in pubspec.yaml.
2323
*/
24-
const val pluginVersion = "0.2.3+5"
24+
const val pluginVersion = "0.2.3+6"
2525
}
2626

2727
override fun setAdTagUrl(pigeon_instance: AdsRequest, adTagUrl: String) {

packages/interactive_media_ads/example/ios/Runner.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
8F599BBD2C332CFE0090A0DF /* ContentPlayheadTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F599BBC2C332CFE0090A0DF /* ContentPlayheadTests.swift */; };
2323
8F599BBF2C3335B40090A0DF /* ViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F599BBE2C3335B40090A0DF /* ViewControllerTests.swift */; };
2424
8F8382A32CBDB4A4007F28E0 /* CompanionAdProxyApiTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F8382A22CBDB4A4007F28E0 /* CompanionAdProxyApiTests.swift */; };
25+
8F9035362D00D9A1004F6450 /* AdPodInfoProxyAPITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F9035352D00D9A1004F6450 /* AdPodInfoProxyAPITests.swift */; };
2526
8F977DCF2C2B99C600A90D4B /* AdDisplayContainerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F977DCE2C2B99C600A90D4B /* AdDisplayContainerTests.swift */; };
2627
8F977DD32C2BA15100A90D4B /* TestProxyApiRegistrar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F977DD22C2BA15100A90D4B /* TestProxyApiRegistrar.swift */; };
2728
8F977DD52C2C777600A90D4B /* AdErrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F977DD42C2C777600A90D4B /* AdErrorTests.swift */; };
@@ -83,6 +84,7 @@
8384
8F599BBC2C332CFE0090A0DF /* ContentPlayheadTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentPlayheadTests.swift; sourceTree = "<group>"; };
8485
8F599BBE2C3335B40090A0DF /* ViewControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewControllerTests.swift; sourceTree = "<group>"; };
8586
8F8382A22CBDB4A4007F28E0 /* CompanionAdProxyApiTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompanionAdProxyApiTests.swift; sourceTree = "<group>"; };
87+
8F9035352D00D9A1004F6450 /* AdPodInfoProxyAPITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdPodInfoProxyAPITests.swift; sourceTree = "<group>"; };
8688
8F977DCE2C2B99C600A90D4B /* AdDisplayContainerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdDisplayContainerTests.swift; sourceTree = "<group>"; };
8789
8F977DD22C2BA15100A90D4B /* TestProxyApiRegistrar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestProxyApiRegistrar.swift; sourceTree = "<group>"; };
8890
8F977DD42C2C777600A90D4B /* AdErrorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdErrorTests.swift; sourceTree = "<group>"; };
@@ -144,6 +146,7 @@
144146
8F8382A22CBDB4A4007F28E0 /* CompanionAdProxyApiTests.swift */,
145147
8FFF0C172CC1A7F300A7CB98 /* CompanionAdSlotProxyApiTests.swift */,
146148
8FFF0C192CC1A97B00A7CB98 /* CompanionDelegateProxyApiTests.swift */,
149+
8F9035352D00D9A1004F6450 /* AdPodInfoProxyAPITests.swift */,
147150
);
148151
path = RunnerTests;
149152
sourceTree = "<group>";
@@ -426,6 +429,7 @@
426429
8F599BB92C332A320090A0DF /* AdsRenderingSettingsTests.swift in Sources */,
427430
8F977DD52C2C777600A90D4B /* AdErrorTests.swift in Sources */,
428431
8F599BB12C2DD1FD0090A0DF /* AdsManagerTests.swift in Sources */,
432+
8F9035362D00D9A1004F6450 /* AdPodInfoProxyAPITests.swift in Sources */,
429433
8F977DDB2C2C8D2E00A90D4B /* AdsLoadedDataTests.swift in Sources */,
430434
);
431435
runOnlyForDeploymentPostprocessing = 0;
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import Flutter
6+
import GoogleInteractiveMediaAds
7+
import XCTest
8+
9+
@testable import interactive_media_ads
10+
11+
class AdPodInfoProxyAPITests: XCTestCase {
12+
func testAdPosition() {
13+
let registrar = TestProxyApiRegistrar()
14+
let api = registrar.apiDelegate.pigeonApiIMAAdPodInfo(registrar)
15+
16+
let instance = TestAdPodInfo.customInit()
17+
let value = try? api.pigeonDelegate.adPosition(pigeonApi: api, pigeonInstance: instance)
18+
19+
XCTAssertEqual(value, Int64(instance.adPosition))
20+
}
21+
22+
func testMaxDuration() {
23+
let registrar = TestProxyApiRegistrar()
24+
let api = registrar.apiDelegate.pigeonApiIMAAdPodInfo(registrar)
25+
26+
let instance = TestAdPodInfo.customInit()
27+
let value = try? api.pigeonDelegate.maxDuration(pigeonApi: api, pigeonInstance: instance)
28+
29+
XCTAssertEqual(value, instance.maxDuration)
30+
}
31+
32+
func testPodIndex() {
33+
let registrar = TestProxyApiRegistrar()
34+
let api = registrar.apiDelegate.pigeonApiIMAAdPodInfo(registrar)
35+
36+
let instance = TestAdPodInfo.customInit()
37+
let value = try? api.pigeonDelegate.podIndex(pigeonApi: api, pigeonInstance: instance)
38+
39+
XCTAssertEqual(value, Int64(instance.podIndex))
40+
}
41+
42+
func testTimeOffset() {
43+
let registrar = TestProxyApiRegistrar()
44+
let api = registrar.apiDelegate.pigeonApiIMAAdPodInfo(registrar)
45+
46+
let instance = TestAdPodInfo.customInit()
47+
let value = try? api.pigeonDelegate.timeOffset(pigeonApi: api, pigeonInstance: instance)
48+
49+
XCTAssertEqual(value, instance.timeOffset)
50+
}
51+
52+
func testTotalAds() {
53+
let registrar = TestProxyApiRegistrar()
54+
let api = registrar.apiDelegate.pigeonApiIMAAdPodInfo(registrar)
55+
56+
let instance = TestAdPodInfo.customInit()
57+
let value = try? api.pigeonDelegate.totalAds(pigeonApi: api, pigeonInstance: instance)
58+
59+
XCTAssertEqual(value, Int64(instance.totalAds))
60+
}
61+
62+
func testIsBumper() {
63+
let registrar = TestProxyApiRegistrar()
64+
let api = registrar.apiDelegate.pigeonApiIMAAdPodInfo(registrar)
65+
66+
let instance = TestAdPodInfo.customInit()
67+
let value = try? api.pigeonDelegate.isBumper(pigeonApi: api, pigeonInstance: instance)
68+
69+
XCTAssertEqual(value, instance.isBumper)
70+
}
71+
}
72+
73+
class TestAdPodInfo: IMAAdPodInfo {
74+
// Workaround to subclass an Objective-C class that has an `init` constructor with NS_UNAVAILABLE
75+
static func customInit() -> TestAdPodInfo {
76+
let instance =
77+
TestAdPodInfo.perform(NSSelectorFromString("new")).takeRetainedValue() as! TestAdPodInfo
78+
return instance
79+
}
80+
81+
override var adPosition: Int {
82+
return 5
83+
}
84+
85+
override var maxDuration: TimeInterval {
86+
return 2.0
87+
}
88+
89+
override var podIndex: Int {
90+
return 3
91+
}
92+
93+
override var timeOffset: TimeInterval {
94+
return 6.0
95+
}
96+
97+
override var totalAds: Int {
98+
return 7
99+
}
100+
101+
override var isBumper: Bool {
102+
return false
103+
}
104+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import Foundation
6+
import GoogleInteractiveMediaAds
7+
8+
/// ProxyApi implementation for `IMAAdPodInfo`.
9+
///
10+
/// This class may handle instantiating native object instances that are attached to a Dart instance
11+
/// or handle method calls on the associated native class or an instance of that class.
12+
class AdPodInfoProxyAPIDelegate: PigeonApiDelegateIMAAdPodInfo {
13+
func adPosition(pigeonApi: PigeonApiIMAAdPodInfo, pigeonInstance: IMAAdPodInfo) throws -> Int64 {
14+
return Int64(pigeonInstance.adPosition)
15+
}
16+
17+
func maxDuration(pigeonApi: PigeonApiIMAAdPodInfo, pigeonInstance: IMAAdPodInfo) throws -> Double
18+
{
19+
return pigeonInstance.maxDuration
20+
}
21+
22+
func podIndex(pigeonApi: PigeonApiIMAAdPodInfo, pigeonInstance: IMAAdPodInfo) throws -> Int64 {
23+
return Int64(pigeonInstance.podIndex)
24+
}
25+
26+
func timeOffset(pigeonApi: PigeonApiIMAAdPodInfo, pigeonInstance: IMAAdPodInfo) throws -> Double {
27+
return pigeonInstance.timeOffset
28+
}
29+
30+
func totalAds(pigeonApi: PigeonApiIMAAdPodInfo, pigeonInstance: IMAAdPodInfo) throws -> Int64 {
31+
return Int64(pigeonInstance.totalAds)
32+
}
33+
34+
func isBumper(pigeonApi: PigeonApiIMAAdPodInfo, pigeonInstance: IMAAdPodInfo) throws -> Bool {
35+
return pigeonInstance.isBumper
36+
}
37+
}

packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/AdsRequestProxyAPIDelegate.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class AdsRequestProxyAPIDelegate: PigeonApiDelegateIMAAdsRequest {
1313
/// The current version of the `interactive_media_ads` plugin.
1414
///
1515
/// This must match the version in pubspec.yaml.
16-
static let pluginVersion = "0.2.3+5"
16+
static let pluginVersion = "0.2.3+6"
1717

1818
func pigeonDefaultConstructor(
1919
pigeonApi: PigeonApiIMAAdsRequest, adTagUrl: String, adDisplayContainer: IMAAdDisplayContainer,

packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/InteractiveMediaAdsLibrary.g.swift

Lines changed: 122 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright 2013 The Flutter Authors. All rights reserved.
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
4-
// Autogenerated from Pigeon (v22.6.2), do not edit directly.
4+
// Autogenerated from Pigeon (v22.7.2), do not edit directly.
55
// See also: https://pub.dev/packages/pigeon
66

77
import Foundation
@@ -457,6 +457,10 @@ protocol InteractiveMediaAdsLibraryPigeonProxyApiDelegate {
457457
/// `IMACompanionDelegate` to the Dart `InstanceManager` and make calls to Dart.
458458
func pigeonApiIMACompanionDelegate(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar)
459459
-> PigeonApiIMACompanionDelegate
460+
/// An implementation of [PigeonApiIMAAdPodInfo] used to add a new Dart instance of
461+
/// `IMAAdPodInfo` to the Dart `InstanceManager` and make calls to Dart.
462+
func pigeonApiIMAAdPodInfo(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar)
463+
-> PigeonApiIMAAdPodInfo
460464
}
461465

462466
extension InteractiveMediaAdsLibraryPigeonProxyApiDelegate {
@@ -844,6 +848,17 @@ private class InteractiveMediaAdsLibraryPigeonInternalProxyApiCodecReaderWriter:
844848
return
845849
}
846850

851+
if let instance = value as? IMAAdPodInfo {
852+
pigeonRegistrar.apiDelegate.pigeonApiIMAAdPodInfo(pigeonRegistrar).pigeonNewInstance(
853+
pigeonInstance: instance
854+
) { _ in }
855+
super.writeByte(128)
856+
super.writeValue(
857+
pigeonRegistrar.instanceManager.identifierWithStrongReference(
858+
forInstance: instance as AnyObject)!)
859+
return
860+
}
861+
847862
if let instance = value as AnyObject?,
848863
pigeonRegistrar.instanceManager.containsInstance(instance)
849864
{
@@ -3564,7 +3579,7 @@ final class PigeonApiIMACompanionAdSlot: PigeonApiProtocolIMACompanionAdSlot {
35643579
pigeonDefaultConstructorChannel.setMessageHandler(nil)
35653580
}
35663581
let sizeChannel = FlutterBasicMessageChannel(
3567-
name: "dev.flutter.pigeon.interactive_media_ads.IMACompanionAdSlot.pigeon_defaultConstructor",
3582+
name: "dev.flutter.pigeon.interactive_media_ads.IMACompanionAdSlot.size",
35683583
binaryMessenger: binaryMessenger, codec: codec)
35693584
if let api = api {
35703585
sizeChannel.setMessageHandler { message, reply in
@@ -3822,3 +3837,108 @@ final class PigeonApiIMACompanionDelegate: PigeonApiProtocolIMACompanionDelegate
38223837
}
38233838

38243839
}
3840+
protocol PigeonApiDelegateIMAAdPodInfo {
3841+
/// The position of this ad within an ad pod.
3842+
///
3843+
/// Will be 1 for standalone ads.
3844+
func adPosition(pigeonApi: PigeonApiIMAAdPodInfo, pigeonInstance: IMAAdPodInfo) throws -> Int64
3845+
/// The maximum duration of the pod in seconds.
3846+
///
3847+
/// For unknown duration, -1 is returned.
3848+
func maxDuration(pigeonApi: PigeonApiIMAAdPodInfo, pigeonInstance: IMAAdPodInfo) throws -> Double
3849+
/// Returns the index of the ad pod.
3850+
///
3851+
/// Client side: For a preroll pod, returns 0. For midrolls, returns 1, 2,…,
3852+
/// N. For a postroll pod, returns -1. Defaults to 0 if this ad is not part of
3853+
/// a pod, or this pod is not part of a playlist.
3854+
///
3855+
/// DAI VOD: Returns the index of the ad pod. For a preroll pod, returns 0.
3856+
/// For midrolls, returns 1, 2,…,N. For a postroll pod, returns N+1…N+X.
3857+
/// Defaults to 0 if this ad is not part of a pod, or this pod is not part of
3858+
/// a playlist.
3859+
///
3860+
/// DAI live stream: For a preroll pod, returns 0. For midrolls, returns the
3861+
/// break ID. Returns -2 if pod index cannot be determined (internal error).
3862+
func podIndex(pigeonApi: PigeonApiIMAAdPodInfo, pigeonInstance: IMAAdPodInfo) throws -> Int64
3863+
/// The position of the pod in the content in seconds.
3864+
///
3865+
/// Pre-roll returns 0, post-roll returns -1 and mid-rolls return the
3866+
/// scheduled time of the pod.
3867+
func timeOffset(pigeonApi: PigeonApiIMAAdPodInfo, pigeonInstance: IMAAdPodInfo) throws -> Double
3868+
/// Total number of ads in the pod this ad belongs to.
3869+
///
3870+
/// Will be 1 for standalone ads.
3871+
func totalAds(pigeonApi: PigeonApiIMAAdPodInfo, pigeonInstance: IMAAdPodInfo) throws -> Int64
3872+
/// Specifies whether the ad is a bumper.
3873+
///
3874+
/// Bumpers are short videos used to open and close ad breaks.
3875+
func isBumper(pigeonApi: PigeonApiIMAAdPodInfo, pigeonInstance: IMAAdPodInfo) throws -> Bool
3876+
}
3877+
3878+
protocol PigeonApiProtocolIMAAdPodInfo {
3879+
}
3880+
3881+
final class PigeonApiIMAAdPodInfo: PigeonApiProtocolIMAAdPodInfo {
3882+
unowned let pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar
3883+
let pigeonDelegate: PigeonApiDelegateIMAAdPodInfo
3884+
init(
3885+
pigeonRegistrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar,
3886+
delegate: PigeonApiDelegateIMAAdPodInfo
3887+
) {
3888+
self.pigeonRegistrar = pigeonRegistrar
3889+
self.pigeonDelegate = delegate
3890+
}
3891+
///Creates a Dart instance of IMAAdPodInfo and attaches it to [pigeonInstance].
3892+
func pigeonNewInstance(
3893+
pigeonInstance: IMAAdPodInfo, completion: @escaping (Result<Void, PigeonError>) -> Void
3894+
) {
3895+
if pigeonRegistrar.ignoreCallsToDart {
3896+
completion(
3897+
.failure(
3898+
PigeonError(
3899+
code: "ignore-calls-error",
3900+
message: "Calls to Dart are being ignored.", details: "")))
3901+
return
3902+
}
3903+
if pigeonRegistrar.instanceManager.containsInstance(pigeonInstance as AnyObject) {
3904+
completion(.success(Void()))
3905+
return
3906+
}
3907+
let pigeonIdentifierArg = pigeonRegistrar.instanceManager.addHostCreatedInstance(
3908+
pigeonInstance as AnyObject)
3909+
let adPositionArg = try! pigeonDelegate.adPosition(
3910+
pigeonApi: self, pigeonInstance: pigeonInstance)
3911+
let maxDurationArg = try! pigeonDelegate.maxDuration(
3912+
pigeonApi: self, pigeonInstance: pigeonInstance)
3913+
let podIndexArg = try! pigeonDelegate.podIndex(pigeonApi: self, pigeonInstance: pigeonInstance)
3914+
let timeOffsetArg = try! pigeonDelegate.timeOffset(
3915+
pigeonApi: self, pigeonInstance: pigeonInstance)
3916+
let totalAdsArg = try! pigeonDelegate.totalAds(pigeonApi: self, pigeonInstance: pigeonInstance)
3917+
let isBumperArg = try! pigeonDelegate.isBumper(pigeonApi: self, pigeonInstance: pigeonInstance)
3918+
let binaryMessenger = pigeonRegistrar.binaryMessenger
3919+
let codec = pigeonRegistrar.codec
3920+
let channelName: String =
3921+
"dev.flutter.pigeon.interactive_media_ads.IMAAdPodInfo.pigeon_newInstance"
3922+
let channel = FlutterBasicMessageChannel(
3923+
name: channelName, binaryMessenger: binaryMessenger, codec: codec)
3924+
channel.sendMessage(
3925+
[
3926+
pigeonIdentifierArg, adPositionArg, maxDurationArg, podIndexArg, timeOffsetArg, totalAdsArg,
3927+
isBumperArg,
3928+
] as [Any?]
3929+
) { response in
3930+
guard let listResponse = response as? [Any?] else {
3931+
completion(.failure(createConnectionError(withChannelName: channelName)))
3932+
return
3933+
}
3934+
if listResponse.count > 1 {
3935+
let code: String = listResponse[0] as! String
3936+
let message: String? = nilOrValue(listResponse[1])
3937+
let details: String? = nilOrValue(listResponse[2])
3938+
completion(.failure(PigeonError(code: code, message: message, details: details)))
3939+
} else {
3940+
completion(.success(Void()))
3941+
}
3942+
}
3943+
}
3944+
}

packages/interactive_media_ads/ios/interactive_media_ads/Sources/interactive_media_ads/ProxyApiDelegate.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,4 +145,10 @@ open class ProxyApiDelegate: InteractiveMediaAdsLibraryPigeonProxyApiDelegate {
145145
return PigeonApiIMACompanionDelegate(
146146
pigeonRegistrar: registrar, delegate: CompanionDelegateProxyAPIDelegate())
147147
}
148+
149+
func pigeonApiIMAAdPodInfo(_ registrar: InteractiveMediaAdsLibraryPigeonProxyApiRegistrar)
150+
-> PigeonApiIMAAdPodInfo
151+
{
152+
return PigeonApiIMAAdPodInfo(pigeonRegistrar: registrar, delegate: AdPodInfoProxyAPIDelegate())
153+
}
148154
}

0 commit comments

Comments
 (0)