Skip to content

[firebase_admob] Support Native Ads on iOS #2106

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 78 commits into from
Mar 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
0d0c05f
Start of Android version of NativeAds
bparrishMines Sep 12, 2019
aad39a2
Android side of nativeads
bparrishMines Sep 16, 2019
08bab20
Add dart code for Native Ads
bparrishMines Sep 17, 2019
3f0978e
Add documentation and throw exception on iOS
bparrishMines Sep 17, 2019
0e073b4
Version bump
bparrishMines Sep 17, 2019
2cc277a
Add documentation to README
bparrishMines Sep 17, 2019
25cbc59
Update changelog and README and dispose ad
bparrishMines Sep 17, 2019
10bcb6c
Small comment change
bparrishMines Sep 17, 2019
d6805db
Merge branch 'master' of github.com:FirebaseExtended/flutterfire into…
bparrishMines Sep 17, 2019
7b16385
Formatting and documentation
bparrishMines Sep 20, 2019
daeb8ec
Add note about only supporting android
bparrishMines Sep 23, 2019
5d19c10
Macro for testAdUnitId
bparrishMines Sep 23, 2019
c69e94c
Show Ad content
bparrishMines Sep 23, 2019
abc4fee
Remove unused variable and view configuration
bparrishMines Sep 23, 2019
73b0337
Update documentation
bparrishMines Sep 23, 2019
20e6cb6
Show a UnifiedNativeAd
bparrishMines Sep 26, 2019
03300ad
Merge branch 'master' of github.com:FirebaseExtended/flutterfire into…
bparrishMines Dec 3, 2019
2211c63
Use NatvieAdFactory interface, reorder main.dart, create UnifiedNativ…
bparrishMines Dec 3, 2019
ba01270
update readme
bparrishMines Dec 3, 2019
2cc1a0b
Documentation and formatting
bparrishMines Dec 3, 2019
bf94993
Merge branch 'native_ads' of github.com:bparrishMines/flutterfire int…
bparrishMines Dec 9, 2019
af49fe7
Merge branch 'master' of github.com:FirebaseExtended/flutterfire into…
bparrishMines Dec 12, 2019
1467913
Fix interstitials
bparrishMines Dec 12, 2019
b5392c9
Formatting
bparrishMines Dec 12, 2019
d45f24d
Test native ad
bparrishMines Dec 12, 2019
ea4aef0
Add customOptions
bparrishMines Jan 22, 2020
2fbe0ee
Set native ad factory for plugin instance
bparrishMines Jan 22, 2020
e15649e
Update README
bparrishMines Jan 23, 2020
c8e7796
Merge branch 'master' of github.com:FirebaseExtended/flutterfire into…
bparrishMines Jan 23, 2020
3b43c89
Merge branch 'native_ads' of github.com:bparrishMines/flutterfire int…
bparrishMines Jan 28, 2020
a7011b4
Merge branch 'master' of github.com:FirebaseExtended/flutterfire into…
bparrishMines Jan 28, 2020
a647bff
Update readme with clearer instructions for adding nativeAdFactory
bparrishMines Jan 28, 2020
429df00
Create a map of factories
bparrishMines Jan 29, 2020
1166635
Documentation and formatting
bparrishMines Jan 29, 2020
377be15
lint
bparrishMines Jan 29, 2020
044e26e
bump e2e version
bparrishMines Jan 29, 2020
7b191ec
Merge branch 'master' of github.com:FirebaseExtended/flutterfire into…
bparrishMines Feb 19, 2020
1a4d891
Add static methods to register Native ad
bparrishMines Feb 20, 2020
a31908d
javadocs
bparrishMines Feb 20, 2020
d20939c
Update README
bparrishMines Feb 20, 2020
bc3ffc7
Formatting
bparrishMines Feb 20, 2020
846bb54
Clarify javadoc
bparrishMines Feb 20, 2020
dca6b13
Create common class for MobileAds with Views
bparrishMines Feb 20, 2020
5b8caf4
Update readme with Dart explanation
bparrishMines Feb 20, 2020
d0c4e70
Merge branch 'master' of github.com:FirebaseExtended/flutterfire into…
bparrishMines Feb 20, 2020
bf7d4c3
Extend test time
bparrishMines Feb 20, 2020
d40d2ac
Merge branch 'master' of github.com:FirebaseExtended/flutterfire into…
bparrishMines Feb 24, 2020
0e14c8f
Move timeout back to 10
bparrishMines Feb 24, 2020
bfafb95
Don't call on ad loaded when unified native ad is loaded
bparrishMines Feb 26, 2020
72e6254
Print statements in tests
bparrishMines Feb 26, 2020
bc4a1d8
More print statements
bparrishMines Feb 27, 2020
d3d65b5
Print out random int
bparrishMines Feb 27, 2020
5effdc0
only test loading the ad
bparrishMines Feb 27, 2020
39fd92e
Create MobileAdWithView base class and add NativeAd
bparrishMines Feb 28, 2020
ebb7ff2
Start of creating and registering native ad factory in example
bparrishMines Feb 28, 2020
e88865c
Setup example native ad factory
bparrishMines Feb 28, 2020
f8462d5
Create and populate a native ad view
bparrishMines Feb 29, 2020
d579020
Get Native ad to show without covering remove button
bparrishMines Mar 2, 2020
e517e55
Add anchor offset to example
bparrishMines Mar 2, 2020
da2ef42
Throw exception if plugin is null
bparrishMines Mar 2, 2020
fc9cb32
Merge branch 'master' of github.com:FirebaseExtended/flutterfire into…
bparrishMines Mar 2, 2020
287a756
Add static key and null check in unregisterNativeAdFactory
bparrishMines Mar 4, 2020
4eba72c
Formatting and Documentation
bparrishMines Mar 4, 2020
cf2511c
Add todo with lifecycle issue
bparrishMines Mar 4, 2020
29b2063
Merge branch 'native_ads' of github.com:bparrishMines/flutterfire int…
bparrishMines Mar 5, 2020
48acc40
Merge branch 'master' of github.com:FirebaseExtended/flutterfire into…
bparrishMines Mar 5, 2020
c9e10b8
Merge branch 'native_ads_ios2' of github.com:bparrishMines/flutterfir…
bparrishMines Mar 5, 2020
a583c5d
Fix showing the view
bparrishMines Mar 5, 2020
cd7d5f5
Documentation for iOS
bparrishMines Mar 6, 2020
4a4706f
Documentation and small change to example
bparrishMines Mar 7, 2020
0897e36
Handle errors when setting a native ad factory
bparrishMines Mar 7, 2020
717dba2
crash if method not overriden
bparrishMines Mar 7, 2020
8270b94
Add comment
bparrishMines Mar 7, 2020
1a4faee
Fix banner view showing
bparrishMines Mar 9, 2020
3b30a1e
Formatting
bparrishMines Mar 9, 2020
c7448b9
Format with clang 700
bparrishMines Mar 9, 2020
ab88c59
Review comments
bparrishMines Mar 12, 2020
dfd19f5
Add comment about example code location
bparrishMines Mar 16, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 50 additions & 4 deletions packages/firebase_admob/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,10 @@ Since Native Ads require UI components native to a platform, this feature requir
for Android and iOS:

### Android
The Android Admob Plugin requires a class that implements `NativeAdFactory` which implements `createNativeAd(
[UnifiedNativeAd](https://developers.google.com/android/reference/com/google/android/gms/ads/formats/UnifiedNativeAd) nativeAd,
Map<String, Options> customOptions)` and returns a
The Android Admob Plugin requires a class that implements `NativeAdFactory` which contains a method
that takes a
[UnifiedNativeAd](https://developers.google.com/android/reference/com/google/android/gms/ads/formats/UnifiedNativeAd)
and custom options and returns a
[UnifiedNativeAdView](https://developers.google.com/android/reference/com/google/android/gms/ads/formats/UnifiedNativeAdView).

You can implement this in your `MainActivity.java` or create a separate class in the same directory
Expand Down Expand Up @@ -285,8 +286,53 @@ An example of displaying a `UnifiedNativeAd` with a `UnifiedNativeAdView` can be
a custom layout and displays the test Native ad.

### iOS
Native Ads for iOS require a class that implements the protocol `FLTNativeAdFactory` which has a
single method `createNativeAd:customOptions:`.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the example below has a nativeAd argument too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was following the naming structure from apple docs. Example setObject:forKey: doesn't keep the name of the first object:
https://developer.apple.com/documentation/foundation/nsmutabledictionary/1411616-setobject?language=objc

I wasn't really sure what the best shorthand form for an objective c method was.


Currently unsupported.
You can have your `AppDelegate` implement this protocol or create a separate class as seen below:

```objectivec
/* AppDelegate.m */

#import "FLTFirebaseAdMobPlugin.h"

@interface NativeAdFactoryExample : NSObject<FLTNativeAdFactory>
@end

@implementation NativeAdFactoryExample
- (GADUnifiedNativeAdView *)createNativeAd:(GADUnifiedNativeAd *)nativeAd
customOptions:(NSDictionary *)customOptions {
// Create GADUnifiedNativeAdView
}
@end
```

Once there is an implementation of `FLTNativeAdFactory`, it must be added to the
`FLTFirebaseAdMobPlugin`. This is done by importing `FLTFirebaseAdMobPlugin.h` and calling
`registerNativeAdFactory:factoryId:nativeAdFactory:` with a `FlutterPluginRegistry`, a unique
identifier for the factory, and the factory itself. The factory also *MUST* be added after
`[GeneratedPluginRegistrant registerWithRegistry:self];` has been called.

If this is done in `AppDelegate.m`, it should look similar to:

```objectivec
#import "FLTFirebaseAdMobPlugin.h"

@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];

NativeAdFactoryExample *nativeAdFactory = [[NativeAdFactoryExample alloc] init];
[FLTFirebaseAdMobPlugin registerNativeAdFactory:self
factoryId:@"adFactoryExample"
nativeAdFactory:nativeAdFactory];

return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

@end
```

### Dart Example

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ public static void registerWith(Registrar registrar) {

/**
* Adds a {@link io.flutter.plugins.firebaseadmob.FirebaseAdMobPlugin.NativeAdFactory} used to
* create a {@link com.google.android.gms.ads.formats.UnifiedNativeAdView}s from a Native Ad
* created in Dart.
* create {@link com.google.android.gms.ads.formats.UnifiedNativeAdView}s from a Native Ad created
* in Dart.
*
* @param registry maintains access to a FirebaseAdMobPlugin instance.
* @param factoryId a unique identifier for the ad factory. The Native Ad created in Dart includes
Expand All @@ -110,7 +110,7 @@ public static boolean registerNativeAdFactory(

/**
* Registers a {@link io.flutter.plugins.firebaseadmob.FirebaseAdMobPlugin.NativeAdFactory} used
* to create a {@link com.google.android.gms.ads.formats.UnifiedNativeAdView}s from a Native Ad
* to create {@link com.google.android.gms.ads.formats.UnifiedNativeAdView}s from a Native Ad
* created in Dart.
*
* @param engine maintains access to a FirebaseAdMobPlugin instance.
Expand Down Expand Up @@ -142,7 +142,7 @@ private static boolean registerNativeAdFactory(

/**
* Unregisters a {@link io.flutter.plugins.firebaseadmob.FirebaseAdMobPlugin.NativeAdFactory} used
* to create a {@link com.google.android.gms.ads.formats.UnifiedNativeAdView}s from a Native Ad
* to create {@link com.google.android.gms.ads.formats.UnifiedNativeAdView}s from a Native Ad
* created in Dart.
*
* @param registry maintains access to a FirebaseAdMobPlugin instance.
Expand All @@ -162,7 +162,7 @@ public static NativeAdFactory unregisterNativeAdFactory(

/**
* Unregisters a {@link io.flutter.plugins.firebaseadmob.FirebaseAdMobPlugin.NativeAdFactory} used
* to create a {@link com.google.android.gms.ads.formats.UnifiedNativeAdView}s from a Native Ad
* to create {@link com.google.android.gms.ads.formats.UnifiedNativeAdView}s from a Native Ad
* created in Dart.
*
* @param engine maintains access to a FirebaseAdMobPlugin instance.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,9 @@

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't typically include this file, but I need it to add UnifiedNativeAdView.xib to the xcode project. Otherwise, the app crashes when creating a NativeAd.

/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
6E27B1151F0DAFA70028FD65 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 6E27B1141F0DAFA70028FD65 /* GoogleService-Info.plist */; };
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
8FC897F52411A9F100415930 /* UnifiedNativeAdView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8FC897F42411A9F100415930 /* UnifiedNativeAdView.xib */; };
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB31CF90195004384FC /* Generated.xcconfig */; };
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
Expand All @@ -32,8 +28,6 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
Expand All @@ -43,32 +37,30 @@
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
6E27B1141F0DAFA70028FD65 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
83F369F228D3A43519CEE308 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
8FC897F42411A9F100415930 /* UnifiedNativeAdView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UnifiedNativeAdView.xib; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CE82265EF05E2A9632B25E60 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
F74051031B69F8124E38352E /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
FBE669D215209F1F44CEEB21 /* libPods-Runner.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand All @@ -79,6 +71,8 @@
07A52D07C2C05D9527204891 /* Pods */ = {
isa = PBXGroup;
children = (
CE82265EF05E2A9632B25E60 /* Pods-Runner.debug.xcconfig */,
F74051031B69F8124E38352E /* Pods-Runner.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
Expand All @@ -94,10 +88,7 @@
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B80C3931E831B6300D905FE /* App.framework */,
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
2D5378251FAA1A9400D5DBA9 /* flutter_assets */,
9740EEBA1CF902C7004384FC /* Flutter.framework */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
Expand Down Expand Up @@ -127,6 +118,7 @@
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
8FC897F42411A9F100415930 /* UnifiedNativeAdView.xib */,
6E27B1141F0DAFA70028FD65 /* GoogleService-Info.plist */,
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
Expand Down Expand Up @@ -193,6 +185,7 @@
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
Base,
);
Expand All @@ -214,8 +207,8 @@
6E27B1151F0DAFA70028FD65 /* GoogleService-Info.plist in Resources */,
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */,
8FC897F52411A9F100415930 /* UnifiedNativeAdView.xib in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */,
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
Expand Down Expand Up @@ -255,7 +248,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
Expand All @@ -277,16 +270,13 @@
files = (
);
inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${PODS_ROOT}/.symlinks/flutter/ios/Flutter.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
Expand Down
57 changes: 55 additions & 2 deletions packages/firebase_admob/example/ios/Runner/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,67 @@
// found in the LICENSE file.

#include "AppDelegate.h"
#import "FLTFirebaseAdMobPlugin.h"
#include "GeneratedPluginRegistrant.h"

@implementation AppDelegate
@interface NativeAdFactoryExample : NSObject <FLTNativeAdFactory>
@end

// The UnifiedNativeAdView.xib and example GADUnifiedNativeAdView is provided and
// explained by https://developers.google.com/admob/ios/native/advanced.
@implementation NativeAdFactoryExample
- (GADUnifiedNativeAdView *)createNativeAd:(GADUnifiedNativeAd *)nativeAd
customOptions:(NSDictionary *)customOptions {
// Create and place ad in view hierarchy.
GADUnifiedNativeAdView *adView =
[[NSBundle mainBundle] loadNibNamed:@"UnifiedNativeAdView" owner:nil options:nil].firstObject;

// Associate the native ad view with the native ad object. This is
// required to make the ad clickable.
adView.nativeAd = nativeAd;

// Populate the native ad view with the native ad assets.
// The headline is guaranteed to be present in every native ad.
((UILabel *)adView.headlineView).text = nativeAd.headline;

// These assets are not guaranteed to be present. Check that they are before
// showing or hiding them.
Comment on lines +29 to +30
Copy link

@blasten blasten Mar 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this depend on the ad that is being displayed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes this depends on the information that is provided in the UnifiedNativeAd. Some ads may have this item and others won't.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Suggestion: what about we add a link to https://developers.google.com/admob/ios/native/advanced in a comment?

((UILabel *)adView.bodyView).text = nativeAd.body;
adView.bodyView.hidden = nativeAd.body ? NO : YES;

[((UIButton *)adView.callToActionView) setTitle:nativeAd.callToAction
forState:UIControlStateNormal];
adView.callToActionView.hidden = nativeAd.callToAction ? NO : YES;

((UIImageView *)adView.iconView).image = nativeAd.icon.image;
adView.iconView.hidden = nativeAd.icon ? NO : YES;

((UILabel *)adView.storeView).text = nativeAd.store;
adView.storeView.hidden = nativeAd.store ? NO : YES;

((UILabel *)adView.priceView).text = nativeAd.price;
adView.priceView.hidden = nativeAd.price ? NO : YES;

((UILabel *)adView.advertiserView).text = nativeAd.advertiser;
adView.advertiserView.hidden = nativeAd.advertiser ? NO : YES;

// In order for the SDK to process touch events properly, user interaction
// should be disabled.
adView.callToActionView.userInteractionEnabled = NO;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this a requirement for Flutter apps? Is this meant to be set by the iOS embedding?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is required for any app that uses UnifiedNativeAdView. Setting this to NO is to guarantee that UnifiedNativeAdView receives the touch event and not the subview. Otherwise, the adview wouldn't open the link.


return adView;
}
@end

@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
// Override point for customization after application launch.

NativeAdFactoryExample *nativeAdFactory = [[NativeAdFactoryExample alloc] init];
[FLTFirebaseAdMobPlugin registerNativeAdFactory:self
factoryId:@"adFactoryExample"
nativeAdFactory:nativeAdFactory];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

Expand Down
Loading