Skip to content

Commit 46a712f

Browse files
[interactive_media_ads] Adds initial iOS implementation (flutter#7063)
iOS implementation for flutter#134228
1 parent b20d2c5 commit 46a712f

File tree

69 files changed

+10301
-164
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+10301
-164
lines changed

packages/interactive_media_ads/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# 0.1.1
2+
3+
* Adds iOS implementation.
4+
* Adds support for setting the layout direction of the `AdDisplayContainer`.
5+
16
## 0.1.0+2
27

38
* Bumps androidx.annotation:annotation from 1.7.1 to 1.8.1.

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

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

2727
override fun setAdTagUrl(pigeon_instance: AdsRequest, adTagUrl: String) {
28+
// Ensure adTag can append a custom parameter.
29+
require(adTagUrl.contains("?"))
30+
require(!adTagUrl.contains("#"))
31+
2832
pigeon_instance.adTagUrl = "$adTagUrl&request_agent=Flutter-IMA-$pluginVersion"
2933
}
3034

packages/interactive_media_ads/android/src/test/kotlin/dev/flutter/packages/interactive_media_ads/AdsRequestProxyApiTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ class AdsRequestProxyApiTest {
1616
val api = TestProxyApiRegistrar().getPigeonApiAdsRequest()
1717

1818
val instance = mock<AdsRequest>()
19-
api.setAdTagUrl(instance, "adTag")
19+
api.setAdTagUrl(instance, "adTag?")
2020

2121
verify(instance).adTagUrl =
22-
"adTag&request_agent=Flutter-IMA-${AdsRequestProxyApi.pluginVersion}"
22+
"adTag?&request_agent=Flutter-IMA-${AdsRequestProxyApi.pluginVersion}"
2323
}
2424

2525
@Test

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

Lines changed: 167 additions & 4 deletions
Large diffs are not rendered by default.

packages/interactive_media_ads/example/ios/Runner.xcworkspace/contents.xcworkspacedata

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/interactive_media_ads/example/ios/Runner/AppDelegate.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import Flutter
66
import UIKit
77

8-
@UIApplicationMain
8+
@main
99
@objc class AppDelegate: FlutterAppDelegate {
1010
override func application(
1111
_ application: UIApplication,
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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 XCTest
7+
8+
@testable import interactive_media_ads
9+
10+
final class AdDisplayContainerTests: XCTestCase {
11+
func testPigeonDefaultConstructor() {
12+
let registrar = TestProxyApiRegistrar()
13+
let api = registrar.apiDelegate.pigeonApiIMAAdDisplayContainer(registrar)
14+
15+
let instance = try? api.pigeonDelegate.pigeonDefaultConstructor(
16+
pigeonApi: api, adContainer: UIView(), adContainerViewController: UIViewController())
17+
18+
XCTAssertNotNil(instance)
19+
}
20+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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+
final class AdErrorTests: XCTestCase {
12+
func testType() {
13+
let registrar = TestProxyApiRegistrar()
14+
let api = registrar.apiDelegate.pigeonApiIMAAdError(registrar)
15+
16+
let instance = TestAdError.customInit()
17+
18+
let value = try? api.pigeonDelegate.type(pigeonApi: api, pigeonInstance: instance)
19+
20+
XCTAssertEqual(value, .loadingFailed)
21+
}
22+
23+
func testCode() {
24+
let registrar = TestProxyApiRegistrar()
25+
let api = registrar.apiDelegate.pigeonApiIMAAdError(registrar)
26+
27+
let instance = TestAdError.customInit()
28+
29+
let value = try? api.pigeonDelegate.code(pigeonApi: api, pigeonInstance: instance)
30+
31+
XCTAssertEqual(value, .apiError)
32+
}
33+
34+
func testMessage() {
35+
let registrar = TestProxyApiRegistrar()
36+
let api = registrar.apiDelegate.pigeonApiIMAAdError(registrar)
37+
38+
let instance = TestAdError.customInit()
39+
40+
let value = try? api.pigeonDelegate.message(pigeonApi: api, pigeonInstance: instance)
41+
42+
XCTAssertEqual(value, "message")
43+
}
44+
}
45+
46+
class TestAdError: IMAAdError {
47+
// Workaround to subclass an Objective-C class that has an `init` constructor with NS_UNAVAILABLE
48+
static func customInit() -> IMAAdError {
49+
let instance =
50+
TestAdError.perform(NSSelectorFromString("new")).takeRetainedValue() as! TestAdError
51+
return instance
52+
}
53+
54+
override var type: IMAErrorType {
55+
return .adLoadingFailed
56+
}
57+
58+
override var code: IMAErrorCode {
59+
return .API_ERROR
60+
}
61+
62+
override var message: String? {
63+
return "message"
64+
}
65+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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+
final class AdEventTests: XCTestCase {
12+
func testType() {
13+
let registrar = TestProxyApiRegistrar()
14+
let api = registrar.apiDelegate.pigeonApiIMAAdEvent(registrar)
15+
16+
let instance = TestAdEvent.customInit()
17+
18+
let value = try? api.pigeonDelegate.type(pigeonApi: api, pigeonInstance: instance)
19+
20+
XCTAssertEqual(value, .adBreakEnded)
21+
}
22+
23+
func testMessage() {
24+
let registrar = TestProxyApiRegistrar()
25+
let api = registrar.apiDelegate.pigeonApiIMAAdEvent(registrar)
26+
27+
let instance = TestAdEvent.customInit()
28+
29+
let value = try? api.pigeonDelegate.typeString(pigeonApi: api, pigeonInstance: instance)
30+
31+
XCTAssertEqual(value, "message")
32+
}
33+
}
34+
35+
class TestAdEvent: IMAAdEvent {
36+
// Workaround to subclass an Objective-C class that has an `init` constructor with NS_UNAVAILABLE
37+
static func customInit() -> TestAdEvent {
38+
let instance =
39+
TestAdEvent.perform(NSSelectorFromString("new")).takeRetainedValue() as! TestAdEvent
40+
return instance
41+
}
42+
43+
override var type: IMAAdEventType {
44+
return .AD_BREAK_ENDED
45+
}
46+
47+
override var typeString: String {
48+
return "message"
49+
}
50+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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+
final class AdLoadingErrorTests: XCTestCase {
12+
func testAdError() {
13+
let registrar = TestProxyApiRegistrar()
14+
let api = registrar.apiDelegate.pigeonApiIMAAdLoadingErrorData(registrar)
15+
16+
let instance = TestAdLoadingErrorData.customInit()
17+
18+
let value = try? api.pigeonDelegate.adError(pigeonApi: api, pigeonInstance: instance)
19+
20+
XCTAssertTrue(value is TestAdError)
21+
}
22+
}
23+
24+
class TestAdLoadingErrorData: IMAAdLoadingErrorData {
25+
// Workaround to subclass an Objective-C class that has an `init` constructor with NS_UNAVAILABLE
26+
static func customInit() -> TestAdLoadingErrorData {
27+
let instance =
28+
TestAdLoadingErrorData.perform(NSSelectorFromString("new")).takeRetainedValue()
29+
as! TestAdLoadingErrorData
30+
return instance
31+
}
32+
33+
override var adError: IMAAdError {
34+
return TestAdError.customInit()
35+
}
36+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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+
final class AdsLoadedDataTests: XCTestCase {
12+
func testAdsManager() {
13+
let registrar = TestProxyApiRegistrar()
14+
let api = registrar.apiDelegate.pigeonApiIMAAdsLoadedData(registrar)
15+
16+
let instance = TestAdsLoadedData.customInit()
17+
18+
let value = try? api.pigeonDelegate.adsManager(pigeonApi: api, pigeonInstance: instance)
19+
20+
XCTAssertTrue(value is TestAdsManager)
21+
}
22+
}
23+
24+
class TestAdsLoadedData: IMAAdsLoadedData {
25+
// Workaround to subclass an Objective-C class that has an `init` constructor with NS_UNAVAILABLE
26+
static func customInit() -> TestAdsLoadedData {
27+
let instance =
28+
TestAdsLoadedData.perform(NSSelectorFromString("new")).takeRetainedValue()
29+
as! TestAdsLoadedData
30+
return instance
31+
}
32+
33+
override var adsManager: IMAAdsManager? {
34+
return TestAdsManager.customInit()
35+
}
36+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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+
final class AdsLoaderDelegateTests: XCTestCase {
12+
func testPigeonDefaultConstructor() {
13+
let registrar = TestProxyApiRegistrar()
14+
let api = registrar.apiDelegate.pigeonApiIMAAdsLoaderDelegate(registrar)
15+
16+
let instance = try? api.pigeonDelegate.pigeonDefaultConstructor(pigeonApi: api)
17+
18+
XCTAssertTrue(instance is AdsLoaderDelegateImpl)
19+
}
20+
21+
func testAdLoaderLoadedWith() {
22+
let api = TestAdsLoaderDelegateApi()
23+
let instance = AdsLoaderDelegateImpl(api: api)
24+
25+
let adsLoader = IMAAdsLoader(settings: nil)
26+
let data = TestAdsLoadedData()
27+
instance.adsLoader(adsLoader, adsLoadedWith: data)
28+
29+
XCTAssertEqual(api.adLoaderLoadedWithArgs, [adsLoader, data])
30+
}
31+
32+
func testAdsLoaderFailedWithErrorData() {
33+
let api = TestAdsLoaderDelegateApi()
34+
let instance = AdsLoaderDelegateImpl(api: api)
35+
36+
let adsLoader = IMAAdsLoader(settings: nil)
37+
let error = TestAdLoadingErrorData.customInit()
38+
instance.adsLoader(adsLoader, failedWith: error)
39+
40+
XCTAssertEqual(api.adsLoaderFailedWithErrorDataArgs, [adsLoader, error])
41+
}
42+
}
43+
44+
class TestAdsLoaderDelegateApi: PigeonApiProtocolIMAAdsLoaderDelegate {
45+
var adLoaderLoadedWithArgs: [AnyHashable?]? = nil
46+
var adsLoaderFailedWithErrorDataArgs: [AnyHashable?]? = nil
47+
48+
func adLoaderLoadedWith(
49+
pigeonInstance pigeonInstanceArg: IMAAdsLoaderDelegate, loader loaderArg: IMAAdsLoader,
50+
adsLoadedData adsLoadedDataArg: IMAAdsLoadedData,
51+
completion: @escaping (Result<Void, PigeonError>) -> Void
52+
) {
53+
adLoaderLoadedWithArgs = [loaderArg, adsLoadedDataArg]
54+
}
55+
56+
func adsLoaderFailedWithErrorData(
57+
pigeonInstance pigeonInstanceArg: IMAAdsLoaderDelegate, loader loaderArg: IMAAdsLoader,
58+
adErrorData adErrorDataArg: IMAAdLoadingErrorData,
59+
completion: @escaping (Result<Void, PigeonError>) -> Void
60+
) {
61+
adsLoaderFailedWithErrorDataArgs = [loaderArg, adErrorDataArg]
62+
}
63+
}

0 commit comments

Comments
 (0)