From 7e00b0d8868313c1aeed1da76021c1458dc8ed55 Mon Sep 17 00:00:00 2001 From: jjliu15 <58007281+jjliu15@users.noreply.github.com> Date: Tue, 11 Oct 2022 10:59:32 -0700 Subject: [PATCH] Fullscreen close button (#663) * Hide status bar when showing full screen ad on iOS. Fix for https://github.com/googleads/googleads-mobile-flutter/issues/191 --- .github/workflows/google_mobile_ads.yaml | 2 +- .github/workflows/scripts/build-example.sh | 2 + packages/google_mobile_ads/CHANGELOG.md | 1 + .../ios/Classes/FLTAd_Internal.m | 17 ++++++- .../ios/Tests/FLTRewardedAdTest.m | 44 +++++++++++++------ 5 files changed, 51 insertions(+), 15 deletions(-) diff --git a/.github/workflows/google_mobile_ads.yaml b/.github/workflows/google_mobile_ads.yaml index b737a8c45..f3939405c 100644 --- a/.github/workflows/google_mobile_ads.yaml +++ b/.github/workflows/google_mobile_ads.yaml @@ -67,7 +67,7 @@ jobs: cd packages/google_mobile_ads/ios pod lib lint --allow-warnings env: - DEVELOPER_DIR: /Applications/Xcode_13.4.1.app/Contents/Developer + DEVELOPER_DIR: /Applications/Xcode_14.0.1.app/Contents/Developer flutter: runs-on: ubuntu-latest diff --git a/.github/workflows/scripts/build-example.sh b/.github/workflows/scripts/build-example.sh index ec6ce8136..1bfcf064e 100755 --- a/.github/workflows/scripts/build-example.sh +++ b/.github/workflows/scripts/build-example.sh @@ -32,6 +32,8 @@ fi if [ "$ACTION" == "ios" ] then + flutter pub get; + pod repo update; melos exec -c 1 --scope="$GOOGLEMOBILEADS_PLUGIN_SCOPE_EXAMPLE" -- \ flutter build ios --no-codesign --simulator --debug --target="$TARGET_FILE" --dart-define=CI=true exit diff --git a/packages/google_mobile_ads/CHANGELOG.md b/packages/google_mobile_ads/CHANGELOG.md index e19692fbe..b438a9ff8 100644 --- a/packages/google_mobile_ads/CHANGELOG.md +++ b/packages/google_mobile_ads/CHANGELOG.md @@ -6,6 +6,7 @@ * adSourceInstanceId * adSourceInstanceName * adSourceName +* Fixes [close button issue on iOS](https://github.com/googleads/googleads-mobile-flutter/issues/191) ## 2.0.1 * Bug fix for [issue 580](https://github.com/googleads/googleads-mobile-flutter/issues/580). Adds a workaround on Android to wait for the ad widget to become visible diff --git a/packages/google_mobile_ads/ios/Classes/FLTAd_Internal.m b/packages/google_mobile_ads/ios/Classes/FLTAd_Internal.m index e0dae9936..f7926d070 100644 --- a/packages/google_mobile_ads/ios/Classes/FLTAd_Internal.m +++ b/packages/google_mobile_ads/ios/Classes/FLTAd_Internal.m @@ -591,7 +591,9 @@ - (void)adView:(nonnull GADBannerView *)banner #pragma mark - FLTFullScreenAd -@implementation FLTFullScreenAd +@implementation FLTFullScreenAd { + BOOL _statusBarVisibilityBeforeAdShow; +} @synthesize manager; @@ -616,6 +618,14 @@ - (void)ad:(nonnull id)ad - (void)adWillPresentFullScreenContent: (nonnull id)ad { + // Manually hide the status bar. This is a fix for + // https://github.com/googleads/googleads-mobile-flutter/issues/191 +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + _statusBarVisibilityBeforeAdShow = + UIApplication.sharedApplication.statusBarHidden; + [UIApplication.sharedApplication setStatusBarHidden:YES]; +#pragma clang diagnostic pop [manager adWillPresentFullScreenContent:self]; } @@ -626,6 +636,11 @@ - (void)adDidDismissFullScreenContent: - (void)adWillDismissFullScreenContent: (nonnull id)ad { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + [UIApplication.sharedApplication + setStatusBarHidden:_statusBarVisibilityBeforeAdShow]; +#pragma clang diagnostic pop [manager adWillDismissFullScreenContent:self]; } diff --git a/packages/google_mobile_ads/ios/Tests/FLTRewardedAdTest.m b/packages/google_mobile_ads/ios/Tests/FLTRewardedAdTest.m index 5ddf7df18..b5a11b372 100644 --- a/packages/google_mobile_ads/ios/Tests/FLTRewardedAdTest.m +++ b/packages/google_mobile_ads/ios/Tests/FLTRewardedAdTest.m @@ -71,18 +71,11 @@ - (void)testLoadShowRewardedAd:(FLTAdRequest *)request }); // Stub setting of FullScreenContentDelegate to invoke delegate callbacks. NSError *error = OCMClassMock([NSError class]); + __block id fullScreenContentDelegate; OCMStub([rewardedClassMock setFullScreenContentDelegate:[OCMArg any]]) .andDo(^(NSInvocation *invocation) { - id delegate; - [invocation getArgument:&delegate atIndex:2]; - XCTAssertEqual(delegate, ad); - [delegate adDidRecordImpression:rewardedClassMock]; - [delegate adDidRecordClick:rewardedClassMock]; - [delegate adDidDismissFullScreenContent:rewardedClassMock]; - [delegate adWillPresentFullScreenContent:rewardedClassMock]; - [delegate adWillDismissFullScreenContent:rewardedClassMock]; - [delegate ad:rewardedClassMock - didFailToPresentFullScreenContentWithError:error]; + [invocation getArgument:&fullScreenContentDelegate atIndex:2]; + XCTAssertEqual(fullScreenContentDelegate, ad); }); GADResponseInfo *responseInfo = OCMClassMock([GADResponseInfo class]); OCMStub([rewardedClassMock responseInfo]).andReturn(responseInfo); @@ -110,6 +103,12 @@ - (void)testLoadShowRewardedAd:(FLTAdRequest *)request handler(adValue); return YES; }]]); + + // Setup mock for UIApplication.sharedInstance + id uiApplicationClassMock = OCMClassMock([UIApplication class]); + OCMStub(ClassMethod([uiApplicationClassMock sharedApplication])) + .andReturn(uiApplicationClassMock); + // Call load and check expected interactions with mocks. [ad load]; @@ -154,12 +153,31 @@ - (void)testLoadShowRewardedAd:(FLTAdRequest *)request presentFromRootViewController:[OCMArg isEqual:mockRootViewController] userDidEarnRewardHandler:[OCMArg any]]); - // Verify full screen callbacks. + [fullScreenContentDelegate adWillPresentFullScreenContent:rewardedClassMock]; OCMVerify([mockManager adWillPresentFullScreenContent:[OCMArg isEqual:ad]]); - OCMVerify([mockManager adDidDismissFullScreenContent:[OCMArg isEqual:ad]]); - OCMVerify([mockManager adWillDismissFullScreenContent:[OCMArg isEqual:ad]]); + // Verify that we hide status bar +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + OCMVerify([uiApplicationClassMock setStatusBarHidden:YES]); +#pragma clang diagnostic pop + + [fullScreenContentDelegate adDidRecordImpression:rewardedClassMock]; OCMVerify([mockManager adDidRecordImpression:[OCMArg isEqual:ad]]); + + [fullScreenContentDelegate adDidRecordClick:rewardedClassMock]; OCMVerify([mockManager adDidRecordClick:[OCMArg isEqual:ad]]); + + [fullScreenContentDelegate adDidDismissFullScreenContent:rewardedClassMock]; + OCMVerify([mockManager adDidDismissFullScreenContent:[OCMArg isEqual:ad]]); + + [fullScreenContentDelegate adWillDismissFullScreenContent:rewardedClassMock]; + OCMVerify([mockManager adWillDismissFullScreenContent:[OCMArg isEqual:ad]]); +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + OCMVerify([uiApplicationClassMock setStatusBarHidden:NO]); +#pragma clang diagnostic pop + + [ad ad:rewardedClassMock didFailToPresentFullScreenContentWithError:error]; OCMVerify([mockManager didFailToPresentFullScreenContentWithError:[OCMArg isEqual:ad] error:[OCMArg isEqual:error]]);