Repository: fbsamples/audience-network
Branch: main
Commit: bdd83086d558
Files: 236
Total size: 788.9 KB
Directory structure:
gitextract_zu2obygx/
├── .github/
│ └── workflows/
│ └── main.yml
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── README.md
└── samples/
├── android/
│ ├── .gitignore
│ ├── AdUnitsSample/
│ │ ├── .gitignore
│ │ ├── LICENSE
│ │ ├── build.gradle
│ │ ├── libs/
│ │ │ ├── AudienceNetwork.aar
│ │ │ └── DebugSettings.aar
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── AndroidManifestVariables.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── facebook/
│ │ │ └── samples/
│ │ │ └── AdUnitsSample/
│ │ │ ├── AdUnitsSampleActivity.java
│ │ │ ├── AdUnitsSampleApplication.java
│ │ │ ├── AdUnitsSampleType.java
│ │ │ ├── AudienceNetworkInitializeHelper.java
│ │ │ ├── SampleListActivity.java
│ │ │ ├── SplashActivity.java
│ │ │ ├── adapters/
│ │ │ │ ├── NativeAdRecyclerAdapter.java
│ │ │ │ └── SampleAdapter.java
│ │ │ ├── fragments/
│ │ │ │ ├── BannerFragment.java
│ │ │ │ ├── InterstitialFragment.java
│ │ │ │ ├── MultiLoadInterstitialFragment.java
│ │ │ │ ├── NativeAdHScrollFragment.java
│ │ │ │ ├── NativeAdRecyclerFragment.java
│ │ │ │ ├── NativeAdSampleFragment.java
│ │ │ │ ├── NativeAdTemplateFragment.java
│ │ │ │ ├── NativeBannerAdFragment.java
│ │ │ │ ├── NativeBannerAdTemplateFragment.java
│ │ │ │ ├── RectangleFragment.java
│ │ │ │ ├── RewardedInterstitialFragment.java
│ │ │ │ └── RewardedVideoFragment.java
│ │ │ ├── models/
│ │ │ │ └── RecyclerPostItem.java
│ │ │ └── thirdparty/
│ │ │ └── DividerItemDecoration/
│ │ │ └── DividerItemDecoration.java
│ │ └── res/
│ │ ├── layout/
│ │ │ ├── activity_ad_sample.xml
│ │ │ ├── activity_sample_list.xml
│ │ │ ├── activity_splash.xml
│ │ │ ├── fragment_banner.xml
│ │ │ ├── fragment_interstitial.xml
│ │ │ ├── fragment_multi_load_interstitial.xml
│ │ │ ├── fragment_native_ad_hscroll.xml
│ │ │ ├── fragment_native_ad_recycler.xml
│ │ │ ├── fragment_native_ad_sample.xml
│ │ │ ├── fragment_native_ad_template.xml
│ │ │ ├── fragment_native_banner_ad.xml
│ │ │ ├── fragment_native_banner_ad_template.xml
│ │ │ ├── fragment_rectangle.xml
│ │ │ ├── fragment_rewarded_interstitial.xml
│ │ │ ├── fragment_rewarded_video.xml
│ │ │ ├── list_item_section.xml
│ │ │ ├── native_ad_unit.xml
│ │ │ ├── native_banner_ad_unit.xml
│ │ │ └── recycler_post_item.xml
│ │ ├── layout-land/
│ │ │ └── fragment_rectangle.xml
│ │ ├── menu/
│ │ │ └── ad_units_sample_menu.xml
│ │ ├── values/
│ │ │ ├── layouts.xml
│ │ │ └── strings.xml
│ │ ├── values-large/
│ │ │ └── layout.xml
│ │ ├── values-sw600dp/
│ │ │ └── layout.xml
│ │ └── xml/
│ │ ├── locales_config.xml
│ │ └── network_security_config.xml
│ ├── KotlinAdUnitsSample/
│ │ ├── .gitignore
│ │ ├── KotlinAdUnitsSample/
│ │ │ └── .gitignore
│ │ ├── LICENSE
│ │ ├── build.gradle
│ │ ├── libs/
│ │ │ ├── AudienceNetwork.aar
│ │ │ └── DebugSettings.aar
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── facebook/
│ │ │ └── samples/
│ │ │ └── adunitssamplekotlin/
│ │ │ ├── AdUnitsSampleActivity.kt
│ │ │ ├── AdUnitsSampleApplication.kt
│ │ │ ├── AdUnitsSampleType.kt
│ │ │ ├── AudienceNetworkInitializeHelper.kt
│ │ │ ├── SampleListActivity.kt
│ │ │ ├── SplashActivity.kt
│ │ │ ├── adapters/
│ │ │ │ ├── NativeAdRecyclerAdapter.kt
│ │ │ │ └── SampleAdapter.kt
│ │ │ ├── fragments/
│ │ │ │ ├── BannerFragment.kt
│ │ │ │ ├── InterstitialFragment.kt
│ │ │ │ ├── NativeAdHScrollFragment.kt
│ │ │ │ ├── NativeAdRecyclerFragment.kt
│ │ │ │ ├── NativeAdSampleFragment.kt
│ │ │ │ ├── NativeAdTemplateFragment.kt
│ │ │ │ ├── NativeBannerAdFragment.kt
│ │ │ │ ├── NativeBannerAdTemplateFragment.kt
│ │ │ │ ├── RectangleFragment.kt
│ │ │ │ ├── RewardedInterstitialFragment.kt
│ │ │ │ ├── RewardedVideoFragment.kt
│ │ │ │ └── SampleListFragment.kt
│ │ │ └── models/
│ │ │ └── RecyclerPostItem.kt
│ │ └── res/
│ │ ├── layout/
│ │ │ ├── activity_ad_sample.xml
│ │ │ ├── activity_sample_list.xml
│ │ │ ├── activity_splash.xml
│ │ │ ├── fragment_banner.xml
│ │ │ ├── fragment_interstitial.xml
│ │ │ ├── fragment_native_ad_hscroll.xml
│ │ │ ├── fragment_native_ad_recycler.xml
│ │ │ ├── fragment_native_ad_sample.xml
│ │ │ ├── fragment_native_ad_template.xml
│ │ │ ├── fragment_native_banner_ad.xml
│ │ │ ├── fragment_native_banner_ad_template.xml
│ │ │ ├── fragment_rectangle.xml
│ │ │ ├── fragment_rewarded_interstitial.xml
│ │ │ ├── fragment_rewarded_video.xml
│ │ │ ├── list_item_section.xml
│ │ │ ├── native_ad_unit.xml
│ │ │ ├── native_banner_ad_unit.xml
│ │ │ └── recycler_post_item.xml
│ │ ├── menu/
│ │ │ └── ad_units_sample_menu.xml
│ │ └── values/
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ ├── README.md
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── ios/
│ ├── AdUnitsSample/
│ │ ├── .gitignore
│ │ ├── AdUnitsSample/
│ │ │ ├── AdUnitsSample-Prefix.pch
│ │ │ ├── AdUnitsSample.entitlements
│ │ │ ├── AdUnitsSampleStoryboard.storyboard
│ │ │ ├── AppDelegate.h
│ │ │ ├── AppDelegate.m
│ │ │ ├── BannerViewController.h
│ │ │ ├── BannerViewController.m
│ │ │ ├── CollectionViewController.h
│ │ │ ├── CollectionViewController.m
│ │ │ ├── DebugLogsViewController.h
│ │ │ ├── DebugLogsViewController.m
│ │ │ ├── Images.xcassets/
│ │ │ │ ├── AppIcon.appiconset/
│ │ │ │ │ └── Contents.json
│ │ │ │ └── Contents.json
│ │ │ ├── Info.plist
│ │ │ ├── InfoPlist.strings
│ │ │ ├── InstreamViewController.h
│ │ │ ├── InstreamViewController.m
│ │ │ ├── InterstitialViewController.h
│ │ │ ├── InterstitialViewController.m
│ │ │ ├── LaunchScreen.storyboard
│ │ │ ├── MediumRectViewController.h
│ │ │ ├── MediumRectViewController.m
│ │ │ ├── MenuTableViewController.h
│ │ │ ├── MenuTableViewController.m
│ │ │ ├── NativeAdTemplateViewController.h
│ │ │ ├── NativeAdTemplateViewController.m
│ │ │ ├── NativeBannerAdTemplateViewController.h
│ │ │ ├── NativeBannerAdTemplateViewController.m
│ │ │ ├── NativeBannerViewController.h
│ │ │ ├── NativeBannerViewController.m
│ │ │ ├── NativeViewController.h
│ │ │ ├── NativeViewController.m
│ │ │ ├── NavigationController.h
│ │ │ ├── NavigationController.m
│ │ │ ├── RewardedVideoViewController.h
│ │ │ ├── RewardedVideoViewController.m
│ │ │ ├── ScrollViewController.h
│ │ │ ├── ScrollViewController.m
│ │ │ ├── SettingsLogLevelCell.h
│ │ │ ├── SettingsLogLevelCell.m
│ │ │ ├── SettingsSandboxCell.h
│ │ │ ├── SettingsSandboxCell.m
│ │ │ ├── SettingsTableViewController.h
│ │ │ ├── SettingsTableViewController.m
│ │ │ ├── SettingsTestAdCell.h
│ │ │ ├── SettingsTestAdCell.m
│ │ │ ├── SettingsTestModeCell.h
│ │ │ ├── SettingsTestModeCell.m
│ │ │ ├── TableViewController.h
│ │ │ ├── TableViewController.m
│ │ │ └── main.m
│ │ ├── AdUnitsSample.xcodeproj/
│ │ │ ├── project.pbxproj
│ │ │ ├── project.xcworkspace/
│ │ │ │ ├── contents.xcworkspacedata
│ │ │ │ └── xcshareddata/
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ │ └── xcshareddata/
│ │ │ └── xcschemes/
│ │ │ └── AdUnitsSample.xcscheme
│ │ ├── AdUnitsSample.xcworkspace/
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata/
│ │ │ └── IDEWorkspaceChecks.plist
│ │ ├── Podfile
│ │ ├── ReadMe.txt
│ │ └── VERSION.bzl
│ ├── FANSample/
│ │ ├── .gitignore
│ │ ├── FANSample/
│ │ │ ├── AppDelegate.swift
│ │ │ ├── Assets.xcassets/
│ │ │ │ ├── AppIcon.appiconset/
│ │ │ │ │ └── Contents.json
│ │ │ │ ├── Contents.json
│ │ │ │ └── fan.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── Base.lproj/
│ │ │ │ ├── LaunchScreen.storyboard
│ │ │ │ └── Main.storyboard
│ │ │ ├── Extensions/
│ │ │ │ ├── NSObject+ClassName.swift
│ │ │ │ ├── UIView+NibContent.swift
│ │ │ │ └── UIViewController+Storyboard.swift
│ │ │ ├── Info.plist
│ │ │ ├── Samples/
│ │ │ │ ├── BannerSampleViewController.swift
│ │ │ │ ├── FullscreenAdSampleViewController.swift
│ │ │ │ ├── Native/
│ │ │ │ │ ├── NativeAdScreenViewController.swift
│ │ │ │ │ ├── NativeAdView.swift
│ │ │ │ │ └── NativeAdView.xib
│ │ │ │ ├── NativeBanner/
│ │ │ │ │ ├── NativeBannerAdScreenViewController.swift
│ │ │ │ │ ├── NativeBannerAdView.swift
│ │ │ │ │ └── NativeBannerAdView.xib
│ │ │ │ ├── NativeBannerTemplate/
│ │ │ │ │ ├── NativeBannerTemplateAdScreenViewController.swift
│ │ │ │ │ └── NativeBannerTemplateAdView.swift
│ │ │ │ └── NativeTemplate/
│ │ │ │ ├── NativeTemplateAdView.swift
│ │ │ │ └── NativeTemplateScreenViewController.swift
│ │ │ ├── SamplesViewController.swift
│ │ │ ├── SceneDelegate.swift
│ │ │ ├── Settings/
│ │ │ │ ├── Picker/
│ │ │ │ │ ├── PickerTableViewCell.swift
│ │ │ │ │ ├── PickerTableViewCell.xib
│ │ │ │ │ └── ViewModels.swift
│ │ │ │ ├── SettingScreenViewController.swift
│ │ │ │ └── TestMode/
│ │ │ │ ├── TestModeTableViewCell.swift
│ │ │ │ └── TestModeTableViewCell.xib
│ │ │ └── Utils/
│ │ │ ├── AdUtils.swift
│ │ │ ├── BottomBarView.swift
│ │ │ ├── BottomBarView.xib
│ │ │ └── NavigationController.swift
│ │ ├── FANSample.xcodeproj/
│ │ │ ├── project.pbxproj
│ │ │ ├── project.xcworkspace/
│ │ │ │ ├── contents.xcworkspacedata
│ │ │ │ └── xcshareddata/
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ │ └── xcshareddata/
│ │ │ └── xcschemes/
│ │ │ └── FANSample.xcscheme
│ │ ├── FANSample.xcworkspace/
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata/
│ │ │ └── IDEWorkspaceChecks.plist
│ │ ├── Podfile
│ │ └── README.md
│ └── README.md
└── python/
└── ReportingAPISamples/
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE.md
├── PATENTS.md
├── README.md
├── adnw_examples.py
├── adnw_exception.py
├── adnw_params.py
├── adnw_requests.py
├── adnw_response.py
└── adnw_utils.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/main.yml
================================================
name: Close new issues with template
on:
issues:
types: [opened]
jobs:
close-new-issues:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/github-script@v3
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
msg = `Dear developers. You will not be able to create new bug reports on GitHub after 28 April, and existing tickets will be automatically closed.\n
Instead, please use the bug report (https://developers.facebook.com/support/bugs/) tool to report a bug on Audience Network. Our engineers will get back to you as soon as possible.\n
If you have any other questions or suggestions relating to Facebook Audience Network, please use the online publisher support portal (https://www.facebook.com/business/publishersupport?hc_location=ufi) to submit a request.`
issue = await github.issues.get({
owner: context.issue.owner,
repo: context.issue.repo,
issue_number: context.issue.number,
});
await github.issues.createComment({
owner: context.issue.owner,
repo: context.issue.repo,
issue_number: context.issue.number,
body: msg,
});
await github.issues.update({
owner: context.issue.owner,
repo: context.issue.repo,
issue_number: context.issue.number,
state: "closed"
});
================================================
FILE: .gitignore
================================================
.DS_Store
xcuserdata/
*.xcuserdatad
*.xcuserstate
*.hmap
*.ipa
*.dSYM.zip
*.dSYM
Pods/
build/
DerivedData/
================================================
FILE: CONTRIBUTING.md
================================================
Contributing to audience-network-support
We want to make contributing to this project as easy and transparent as possible.
Pull Requests
We actively welcome your pull requests.
Fork the repo and create your branch from master.
If you've changed APIs, update the documentation.
If you haven't already, complete the Contributor License Agreement ("CLA").
Contributor License Agreement ("CLA")
In order to accept your pull request, we need you to submit a CLA. You only need to do this once to work on any of Facebook's open source projects.
Complete your CLA here: https://code.facebook.com/cla
Issues
We use GitHub issues to track public bugs. Please ensure your description is clear and has sufficient instructions to be able to reproduce the issue.
Facebook has a bounty program for the safe disclosure of security bugs. In those cases, please go through the process outlined on that page and do not file a public issue.
================================================
FILE: LICENSE
================================================
Copyright (c) 2016-present, Facebook, Inc. All rights reserved.
You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
copy, modify, and distribute this software in source code or binary form for use
in connection with the web services and APIs provided by Facebook.
As with any software that integrates with the Facebook platform, your use of
this software is subject to the Facebook Developer Principles and Policies
[http://developers.facebook.com/policy/]. This copyright notice shall be
included in all copies or substantial portions of the software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: README.md
================================================
# Audience Network Samples
In this repository there are sample code that demonstrates how to use Facebook [Audience Network](https://developers.facebook.com/docs/audience-network).
## Samples
* [Android](./samples/android)
* [iOS](./samples/ios)
* [Facebook Audience Reporting API Samples](./samples/python)
## Support
You can see our [developers' site][1] for documentation on using the SDK.
From 28 April 2021, if you are having technical issues or experiencing bugs, please use the [bug report][2] tool to report a bug on `Audience Network`. Our engineers will get back to you as soon as possible.
If you have any other questions or suggestions relating to Facebook Audience Network, please use the online [publisher support portal][3] to submit a request.
[1]: https://developers.facebook.com/docs/audience-network
[2]: https://developers.facebook.com/support/bugs/
[3]: https://www.facebook.com/business/publishersupport?hc_location=ufi
================================================
FILE: samples/android/.gitignore
================================================
admob.xml
# Built application files
*.apk
*.ap_
# Files for the ART/Dalvik VM
*.dex
# Java class files
*.class
# Generated files
bin/
gen/
out/
# Gradle files
.gradle/
gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
# Proguard folder generated by Eclipse
proguard/
# Log Files
*.log
# Android Studio Navigation editor temp files
.navigation/
# Android Studio captures folder
captures/
# Intellij
*.iml
.idea
# Keystore files
*.jks
# External native build folder generated in Android Studio 2.2 and later
.externalNativeBuild
google-services.json
================================================
FILE: samples/android/AdUnitsSample/.gitignore
================================================
BUCK
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
================================================
FILE: samples/android/AdUnitsSample/LICENSE
================================================
Copyright (c) Meta Platforms, Inc. and affiliates.
All rights reserved.
You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
copy, modify, and distribute this software in source code or binary form for use
in connection with the web services and APIs provided by Facebook.
As with any software that integrates with the Facebook platform, your use of
this software is subject to the Facebook Platform Policy
[http://developers.facebook.com/policy/]. This copyright notice shall be
included in all copies or substantial portions of the software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: samples/android/AdUnitsSample/build.gradle
================================================
apply plugin: 'com.android.application'
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
implementation(name: 'AudienceNetwork', ext: 'aar')
implementation(name: 'DebugSettings', ext: 'aar')
implementation "androidx.legacy:legacy-support-v4:$project.ANDROIDX_VERSION"
implementation "androidx.recyclerview:recyclerview:$project.ANDROIDX_VERSION"
implementation "androidx.appcompat:appcompat:$project.ANDROIDX_VERSION"
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation "com.google.android.gms:play-services-basement:$project.ANDROID_GOOGLE_PLAY_SERVICES_VERSION"
}
android {
compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION)
buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION
useLibrary 'org.apache.http.legacy'
defaultConfig {
applicationId 'com.facebook.samples.AdUnitsSample'
minSdkVersion Integer.parseInt(project.ANDROID_BUILD_MIN_SDK_VERSION)
targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
versionCode 1
versionName '1.0'
rootProject.ext.variantRelease = false
}
lintOptions {
abortOnError false
}
}
================================================
FILE: samples/android/AdUnitsSample/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/songqian/android-sdk-macosx/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
================================================
FILE: samples/android/AdUnitsSample/src/main/AndroidManifest.xml
================================================
================================================
FILE: samples/android/AdUnitsSample/src/main/AndroidManifestVariables.xml
================================================
================================================
FILE: samples/android/AdUnitsSample/src/main/java/com/facebook/samples/AdUnitsSample/AdUnitsSampleActivity.java
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.AdUnitsSample;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.LinearLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import com.facebook.common.preconditions.Preconditions;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.samples.AdUnitsSample.fragments.BannerFragment;
import com.facebook.samples.AdUnitsSample.fragments.InterstitialFragment;
import com.facebook.samples.AdUnitsSample.fragments.MultiLoadInterstitialFragment;
import com.facebook.samples.AdUnitsSample.fragments.NativeAdHScrollFragment;
import com.facebook.samples.AdUnitsSample.fragments.NativeAdRecyclerFragment;
import com.facebook.samples.AdUnitsSample.fragments.NativeAdSampleFragment;
import com.facebook.samples.AdUnitsSample.fragments.NativeAdTemplateFragment;
import com.facebook.samples.AdUnitsSample.fragments.NativeBannerAdFragment;
import com.facebook.samples.AdUnitsSample.fragments.NativeBannerAdTemplateFragment;
import com.facebook.samples.AdUnitsSample.fragments.RectangleFragment;
import com.facebook.samples.AdUnitsSample.fragments.RewardedInterstitialFragment;
import com.facebook.samples.AdUnitsSample.fragments.RewardedVideoFragment;
import com.facebook.samples.ads.debugsettings.DebugSettingsActivity;
@Nullsafe(Nullsafe.Mode.LOCAL)
public class AdUnitsSampleActivity extends FragmentActivity {
public static final String SAMPLE_TYPE = "SAMPLE_TYPE";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// If you call AudienceNetworkAds.buildInitSettings(Context).initialize()
// in Application.onCreate() this call is not really necessary.
// Otherwise call initialize() onCreate() of all Activities that contain ads or
// from onCreate() of your Splash Activity.
AudienceNetworkInitializeHelper.initialize(this);
setContentView(R.layout.activity_ad_sample);
LinearLayout rootLayout = findViewById(R.id.activity_ad_sample);
// added check for Android 35 to fix system toolbar issue
// used hard coded value, as VANILLA_ICE_CREAM won't be available for older versions
if (rootLayout != null && android.os.Build.VERSION.SDK_INT >= 35) {
rootLayout.setFitsSystemWindows(true);
}
if (savedInstanceState != null) {
return;
}
Intent intent = getIntent();
String sampleType = intent.getStringExtra(SAMPLE_TYPE);
Fragment fragment = null;
if (sampleType == null) {
return;
}
// Basic ad unit sample types
AdUnitsSampleType type = AdUnitsSampleType.getSampleTypeFromName(sampleType);
if (type != null) {
switch (type) {
case BANNER:
fragment = new BannerFragment();
break;
case RECTANGLE:
fragment = new RectangleFragment();
break;
case INTERSTITIAL:
fragment = new InterstitialFragment();
break;
case MULTI_LOAD_INTERSTITIAL:
fragment = new MultiLoadInterstitialFragment();
break;
case REWARDED_VIDEO:
fragment = new RewardedVideoFragment();
break;
case REWARDED_INTERSTITIAL:
fragment = new RewardedInterstitialFragment();
break;
case NATIVE:
fragment = new NativeAdSampleFragment();
break;
case NATIVE_BANNER:
fragment = NativeBannerAdFragment.newInstance(false);
break;
case NATIVE_BANNER_WITH_IMAGE_VIEW:
fragment = NativeBannerAdFragment.newInstance(true);
break;
case RECYCLERVIEW:
fragment = new NativeAdRecyclerFragment();
break;
case HSCROLL:
fragment = new NativeAdHScrollFragment();
break;
case TEMPLATE:
fragment = new NativeAdTemplateFragment();
break;
case BANNER_TEMPLATE:
fragment = new NativeBannerAdTemplateFragment();
break;
}
Preconditions.checkNotNull(fragment).setRetainInstance(true);
setTitle(type.getName());
getSupportFragmentManager()
.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.ad_units_sample_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int i = item.getItemId();
if (i == R.id.debug_settings) {
startActivity(new Intent(getApplicationContext(), DebugSettingsActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
}
================================================
FILE: samples/android/AdUnitsSample/src/main/java/com/facebook/samples/AdUnitsSample/AdUnitsSampleApplication.java
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.AdUnitsSample;
import android.app.Application;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.samples.ads.debugsettings.DebugSettings;
@Nullsafe(Nullsafe.Mode.LOCAL)
public class AdUnitsSampleApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
DebugSettings.initialize(this);
AudienceNetworkInitializeHelper.initialize(this);
}
}
================================================
FILE: samples/android/AdUnitsSample/src/main/java/com/facebook/samples/AdUnitsSample/AdUnitsSampleType.java
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.AdUnitsSample;
import androidx.annotation.Nullable;
import com.facebook.infer.annotation.Nullsafe;
@Nullsafe(Nullsafe.Mode.LOCAL)
public enum AdUnitsSampleType {
BANNER("Banner"),
RECTANGLE("Rectangle"),
INTERSTITIAL("Interstitial"),
MULTI_LOAD_INTERSTITIAL("Multiple Interstitials"),
REWARDED_VIDEO("Rewarded Video"),
REWARDED_INTERSTITIAL("Rewarded Interstitial"),
NATIVE("Native Ad"),
NATIVE_BANNER("Native Banner Ad"),
RECYCLERVIEW("Native Ad in RecyclerView"),
HSCROLL("Native Ad in H-Scroll"),
TEMPLATE("Native Ad Template"),
BANNER_TEMPLATE("Native Banner Ad Template"),
NATIVE_BANNER_WITH_IMAGE_VIEW("Native Banner Ad With ImageView");
private final String mName;
AdUnitsSampleType(String mName) {
this.mName = mName;
}
public String getName() {
return this.mName;
}
public static @Nullable AdUnitsSampleType getSampleTypeFromName(String name) {
for (AdUnitsSampleType type : AdUnitsSampleType.values()) {
if (type.getName().contentEquals(name)) {
return type;
}
}
return null;
}
}
================================================
FILE: samples/android/AdUnitsSample/src/main/java/com/facebook/samples/AdUnitsSample/AudienceNetworkInitializeHelper.java
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.AdUnitsSample;
import static com.facebook.ads.BuildConfig.DEBUG;
import android.content.Context;
import android.util.Log;
import com.facebook.ads.AdSettings;
import com.facebook.ads.AudienceNetworkAds;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.samples.ads.debugsettings.DebugSettings;
/** Sample class that shows how to call initialize() method of Audience Network SDK. */
@Nullsafe(Nullsafe.Mode.LOCAL)
public class AudienceNetworkInitializeHelper implements AudienceNetworkAds.InitListener {
private final Context mContext;
private AudienceNetworkInitializeHelper(Context context) {
mContext = context;
}
/**
* It's recommended to call this method from Application.onCreate(). Otherwise you can call it
* from all Activity.onCreate() methods for Activities that contain ads.
*
* @param context Application or Activity.
*/
static void initialize(Context context) {
if (!AudienceNetworkAds.isInitialized(context)) {
if (DEBUG) {
AdSettings.turnOnSDKDebugger(context);
}
AudienceNetworkAds.buildInitSettings(context)
.withInitListener(new AudienceNetworkInitializeHelper(context))
.initialize();
}
}
@Override
public void onInitialized(AudienceNetworkAds.InitResult result) {
Log.d(AudienceNetworkAds.TAG, result.getMessage());
DebugSettings.onSDKInitialized(mContext);
}
}
================================================
FILE: samples/android/AdUnitsSample/src/main/java/com/facebook/samples/AdUnitsSample/SampleListActivity.java
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.AdUnitsSample;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import androidx.fragment.app.Fragment;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.samples.AdUnitsSample.adapters.SampleAdapter;
import com.facebook.samples.ads.debugsettings.DebugSettingsActivity;
/** A simple {@link Fragment} subclass. */
@Nullsafe(Nullsafe.Mode.LOCAL)
public class SampleListActivity extends ListActivity {
private static final String TAG = SampleListActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle(R.string.select_sample);
final SampleAdapter adapter = new SampleAdapter(SampleListActivity.this);
// Bind to our new adapter.
setListAdapter(adapter);
// added check for Android 35 to fix system toolbar issue
// used hard coded value, as VANILLA_ICE_CREAM won't be available for older versions
if (android.os.Build.VERSION.SDK_INT >= 35) {
getListView().setFitsSystemWindows(true);
}
getListView()
.setOnItemClickListener(
new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
Log.e(TAG, "List item clicked: " + position);
SampleAdapter.Item item = (SampleAdapter.Item) adapter.getItem(position);
// NULLSAFE_FIXME[Nullable Dereference]
String sampleName = item.getTitle();
AdUnitsSampleType type = AdUnitsSampleType.getSampleTypeFromName(sampleName);
if (type != null) {
Intent intent = new Intent(SampleListActivity.this, AdUnitsSampleActivity.class);
intent.putExtra(AdUnitsSampleActivity.SAMPLE_TYPE, type.getName());
startActivity(intent);
}
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.ad_units_sample_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int i = item.getItemId();
if (i == R.id.debug_settings) {
startActivity(new Intent(getApplicationContext(), DebugSettingsActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
}
================================================
FILE: samples/android/AdUnitsSample/src/main/java/com/facebook/samples/AdUnitsSample/SplashActivity.java
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.AdUnitsSample;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.Window;
import android.view.WindowManager;
import com.facebook.infer.annotation.Nullsafe;
@Nullsafe(Nullsafe.Mode.LOCAL)
public class SplashActivity extends Activity {
private static final int SPLASH_TIME = 2000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// If you call AudienceNetworkAds.buildInitSettings(Context).initialize()
// in Application.onCreate() this call is not really necessary.
// Otherwise call initialize() onCreate() of all Activities that contain ads or
// from onCreate() of your Splash Activity.
AudienceNetworkInitializeHelper.initialize(this);
// Hide title and nav bar, must be done before setContentView.
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow()
// NULLSAFE_FIXME[Nullable Dereference]
.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_splash);
final Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(
new Runnable() {
@Override
public void run() {
Intent intent = new Intent(SplashActivity.this, SampleListActivity.class);
startActivity(intent);
}
},
SPLASH_TIME);
}
}
================================================
FILE: samples/android/AdUnitsSample/src/main/java/com/facebook/samples/AdUnitsSample/adapters/NativeAdRecyclerAdapter.java
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.AdUnitsSample.adapters;
import android.app.Activity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.facebook.ads.Ad;
import com.facebook.ads.AdError;
import com.facebook.ads.AdOptionsView;
import com.facebook.ads.MediaView;
import com.facebook.ads.NativeAd;
import com.facebook.ads.NativeAdLayout;
import com.facebook.ads.NativeAdListener;
import com.facebook.ads.NativeAdsManager;
import com.facebook.common.preconditions.Preconditions;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.samples.AdUnitsSample.R;
import com.facebook.samples.AdUnitsSample.models.RecyclerPostItem;
import java.util.ArrayList;
import java.util.List;
@Nullsafe(Nullsafe.Mode.LOCAL)
public class NativeAdRecyclerAdapter extends RecyclerView.Adapter {
private List mPostItems;
private List mAdItems;
private NativeAdsManager mNativeAdsManager;
private Activity mActivity;
private static final int AD_DISPLAY_FREQUENCY = 5;
private static final int POST_TYPE = 0;
private static final int AD_TYPE = 1;
private static final String TAG = "NativeAdsManager";
public NativeAdRecyclerAdapter(
Activity activity, List postItems, NativeAdsManager nativeAdsManager) {
mNativeAdsManager = nativeAdsManager;
mPostItems = postItems;
mAdItems = new ArrayList<>();
mActivity = activity;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == AD_TYPE) {
NativeAdLayout inflatedView =
(NativeAdLayout)
LayoutInflater.from(parent.getContext())
.inflate(R.layout.native_ad_unit, parent, false);
return new AdHolder(inflatedView);
} else {
View inflatedView =
LayoutInflater.from(parent.getContext())
.inflate(R.layout.recycler_post_item, parent, false);
return new PostHolder(inflatedView);
}
}
@Override
public int getItemViewType(int position) {
return position % AD_DISPLAY_FREQUENCY == 0 ? AD_TYPE : POST_TYPE;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder.getItemViewType() == AD_TYPE) {
NativeAd ad;
if (mAdItems.size() > position / AD_DISPLAY_FREQUENCY) {
ad = mAdItems.get(position / AD_DISPLAY_FREQUENCY);
} else {
ad =
mNativeAdsManager.nextNativeAd(
new NativeAdListener() {
@Override
public void onMediaDownloaded(Ad ad) {
// ignore
}
@Override
public void onError(Ad ad, AdError error) {
// ignore
}
@Override
public void onAdLoaded(Ad ad) {
// ignore
}
@Override
public void onAdClicked(Ad ad) {
Log.i(TAG, ((NativeAd) ad).getAdvertiserName() + " Ad Clicked");
}
@Override
public void onLoggingImpression(Ad ad) {
Log.i(TAG, ((NativeAd) ad).getAdvertiserName() + " Ad Impression");
}
});
if (!Preconditions.checkNotNull(ad).isAdInvalidated()) {
mAdItems.add(ad);
} else {
Log.w(NativeAdRecyclerAdapter.class.getSimpleName(), "Ad is invalidated!");
}
}
AdHolder adHolder = (AdHolder) holder;
adHolder.adChoicesContainer.removeAllViews();
if (ad != null) {
adHolder.tvAdTitle.setText(ad.getAdvertiserName());
adHolder.tvAdBody.setText(ad.getAdBodyText());
adHolder.tvAdSocialContext.setText(ad.getAdSocialContext());
adHolder.tvAdSponsoredLabel.setText(R.string.sponsored);
adHolder.btnAdCallToAction.setText(ad.getAdCallToAction());
adHolder.btnAdCallToAction.setVisibility(
ad.hasCallToAction() ? View.VISIBLE : View.INVISIBLE);
AdOptionsView adOptionsView = new AdOptionsView(mActivity, ad, adHolder.nativeAdLayout);
adHolder.adChoicesContainer.addView(adOptionsView, 0);
List clickableViews = new ArrayList<>();
clickableViews.add(adHolder.ivAdIcon);
clickableViews.add(adHolder.mvAdMedia);
clickableViews.add(adHolder.btnAdCallToAction);
ad.registerViewForInteraction(
adHolder.nativeAdLayout, adHolder.mvAdMedia, adHolder.ivAdIcon, clickableViews);
}
} else {
PostHolder postHolder = (PostHolder) holder;
// Calculate where the next postItem index is by subtracting ads we've shown.
int index = position - (position / AD_DISPLAY_FREQUENCY) - 1;
RecyclerPostItem postItem = mPostItems.get(index);
postHolder.tvPostContent.setText(postItem.getPostContent());
}
}
@Override
public int getItemCount() {
return mPostItems.size() + mAdItems.size();
}
private static class PostHolder extends RecyclerView.ViewHolder {
TextView tvPostContent;
PostHolder(View view) {
super(view);
// NULLSAFE_FIXME[Field Not Nullable]
tvPostContent = view.findViewById(R.id.tvPostContent);
}
}
private static class AdHolder extends RecyclerView.ViewHolder {
NativeAdLayout nativeAdLayout;
MediaView mvAdMedia;
MediaView ivAdIcon;
TextView tvAdTitle;
TextView tvAdBody;
TextView tvAdSocialContext;
TextView tvAdSponsoredLabel;
Button btnAdCallToAction;
LinearLayout adChoicesContainer;
AdHolder(NativeAdLayout adLayout) {
super(adLayout);
nativeAdLayout = adLayout;
// NULLSAFE_FIXME[Field Not Nullable]
mvAdMedia = adLayout.findViewById(R.id.native_ad_media);
// NULLSAFE_FIXME[Field Not Nullable]
tvAdTitle = adLayout.findViewById(R.id.native_ad_title);
// NULLSAFE_FIXME[Field Not Nullable]
tvAdBody = adLayout.findViewById(R.id.native_ad_body);
// NULLSAFE_FIXME[Field Not Nullable]
tvAdSocialContext = adLayout.findViewById(R.id.native_ad_social_context);
// NULLSAFE_FIXME[Field Not Nullable]
tvAdSponsoredLabel = adLayout.findViewById(R.id.native_ad_sponsored_label);
// NULLSAFE_FIXME[Field Not Nullable]
btnAdCallToAction = adLayout.findViewById(R.id.native_ad_call_to_action);
// NULLSAFE_FIXME[Field Not Nullable]
ivAdIcon = adLayout.findViewById(R.id.native_ad_icon);
// NULLSAFE_FIXME[Field Not Nullable]
adChoicesContainer = adLayout.findViewById(R.id.ad_choices_container);
}
}
}
================================================
FILE: samples/android/AdUnitsSample/src/main/java/com/facebook/samples/AdUnitsSample/adapters/SampleAdapter.java
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.AdUnitsSample.adapters;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import com.facebook.common.preconditions.Preconditions;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.samples.AdUnitsSample.AdUnitsSampleType;
import com.facebook.samples.AdUnitsSample.R;
@Nullsafe(Nullsafe.Mode.LOCAL)
public class SampleAdapter extends ArrayAdapter {
public static class Item {
private String title;
private boolean isSection;
public Item(String title, boolean isSection) {
this.title = title;
this.isSection = isSection;
}
public Item(String title) {
this(title, false);
}
public String getTitle() {
return title;
}
}
private Context context;
private LayoutInflater inflater;
public SampleAdapter(Context context) {
super(context, 0);
this.context = context;
// Add the samples and section headers
add(new Item("Basic Samples", true));
add(new Item(AdUnitsSampleType.BANNER.getName()));
add(new Item(AdUnitsSampleType.RECTANGLE.getName()));
add(new Item(AdUnitsSampleType.INTERSTITIAL.getName()));
add(new Item(AdUnitsSampleType.MULTI_LOAD_INTERSTITIAL.getName()));
add(new Item(AdUnitsSampleType.REWARDED_VIDEO.getName()));
add(new Item(AdUnitsSampleType.REWARDED_INTERSTITIAL.getName()));
// Native ad samples
add(new Item("Native Ad Samples", true));
add(new Item(AdUnitsSampleType.NATIVE.getName()));
add(new Item(AdUnitsSampleType.NATIVE_BANNER.getName()));
add(new Item(AdUnitsSampleType.RECYCLERVIEW.getName()));
add(new Item(AdUnitsSampleType.HSCROLL.getName()));
add(new Item(AdUnitsSampleType.TEMPLATE.getName()));
add(new Item(AdUnitsSampleType.BANNER_TEMPLATE.getName()));
add(new Item(AdUnitsSampleType.NATIVE_BANNER_WITH_IMAGE_VIEW.getName()));
// NULLSAFE_FIXME[Field Not Nullable]
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
final Item item = (Item) getItem(position);
if (item != null) {
if (item.isSection) {
v = inflater.inflate(R.layout.list_item_section, parent, false);
v.setOnClickListener(null);
v.setOnLongClickListener(null);
v.setLongClickable(false);
final TextView title = (TextView) v.findViewById(R.id.list_item_section_text);
Preconditions.checkNotNull(title).setText(item.title);
} else {
v = inflater.inflate(android.R.layout.simple_list_item_1, parent, false);
final TextView title = (TextView) v.findViewById(android.R.id.text1);
Preconditions.checkNotNull(title).setText(item.title);
}
}
return v;
}
}
================================================
FILE: samples/android/AdUnitsSample/src/main/java/com/facebook/samples/AdUnitsSample/fragments/BannerFragment.java
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.AdUnitsSample.fragments;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.facebook.ads.Ad;
import com.facebook.ads.AdError;
import com.facebook.ads.AdListener;
import com.facebook.ads.AdSize;
import com.facebook.ads.AdView;
import com.facebook.samples.AdUnitsSample.R;
import com.facebook.samples.ads.debugsettings.DebugToast;
public class BannerFragment extends Fragment implements AdListener {
private static final String TAG = BannerFragment.class.getSimpleName();
private RelativeLayout bannerAdContainer;
private Button refreshBannerButton;
private TextView bannerStatusLabel;
private @Nullable AdView bannerAdView;
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_banner, container, false);
bannerStatusLabel = (TextView) view.findViewById(R.id.bannerStatusLabel);
bannerAdContainer = (RelativeLayout) view.findViewById(R.id.bannerAdContainer);
refreshBannerButton = (Button) view.findViewById(R.id.refreshBannerButton);
refreshBannerButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
loadAdView();
}
});
loadAdView();
return view;
}
@Override
public void onDestroyView() {
bannerAdContainer.removeView(bannerAdView);
super.onDestroyView();
}
@Override
public void onDestroy() {
if (bannerAdView != null) {
bannerAdView.destroy();
bannerAdView = null;
}
super.onDestroy();
}
private void loadAdView() {
if (bannerAdView != null) {
bannerAdView.destroy();
bannerAdView = null;
}
// Update progress message
setLabel(getString(R.string.loading_status));
// Create a banner's ad view with a unique placement ID (generate your own on the Facebook
// app settings). Use different ID for each ad placement in your app.
boolean isTablet = getResources().getBoolean(R.bool.is_tablet);
bannerAdView =
new AdView(
this.getActivity(),
"YOUR_PLACEMENT_ID",
isTablet ? AdSize.BANNER_HEIGHT_90 : AdSize.BANNER_HEIGHT_50);
// Reposition the ad and add it to the view hierarchy.
bannerAdContainer.addView(bannerAdView);
// Initiate a request to load an ad.
bannerAdView.loadAd(bannerAdView.buildLoadAdConfig().withAdListener(this).build());
}
@Override
public void onError(Ad ad, AdError error) {
if (ad == bannerAdView) {
setLabel("Ad failed to load: " + error.getErrorMessage());
}
}
@Override
public void onAdLoaded(Ad ad) {
if (ad == bannerAdView) {
setLabel("");
}
}
@Override
public void onAdClicked(Ad ad) {
DebugToast.show(requireActivity(), "Ad Clicked", Toast.LENGTH_SHORT);
}
@Override
public void onLoggingImpression(Ad ad) {
Log.d(TAG, "onLoggingImpression");
}
private void setLabel(String status) {
bannerStatusLabel.setText(status);
}
}
================================================
FILE: samples/android/AdUnitsSample/src/main/java/com/facebook/samples/AdUnitsSample/fragments/InterstitialFragment.java
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.AdUnitsSample.fragments;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.fragment.app.Fragment;
import com.facebook.ads.Ad;
import com.facebook.ads.AdError;
import com.facebook.ads.CacheFlag;
import com.facebook.ads.InterstitialAd;
import com.facebook.ads.InterstitialAdExtendedListener;
import com.facebook.ads.RewardData;
import com.facebook.common.preconditions.Preconditions;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.samples.AdUnitsSample.R;
import com.facebook.samples.ads.debugsettings.DebugToast;
import java.util.EnumSet;
import javax.annotation.Nullable;
@Nullsafe(Nullsafe.Mode.LOCAL)
public class InterstitialFragment extends Fragment implements InterstitialAdExtendedListener {
private static final String TAG = InterstitialFragment.class.getSimpleName();
private TextView interstitialAdStatusLabel;
private Button loadInterstitialButton;
private Button showInterstitialButton;
@Nullable private InterstitialAd interstitialAd;
private String statusLabel = "";
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_interstitial, container, false);
// NULLSAFE_FIXME[Field Not Nullable]
interstitialAdStatusLabel = (TextView) view.findViewById(R.id.interstitialAdStatusLabel);
// NULLSAFE_FIXME[Field Not Nullable]
loadInterstitialButton = (Button) view.findViewById(R.id.loadInterstitialButton);
// NULLSAFE_FIXME[Field Not Nullable]
showInterstitialButton = (Button) view.findViewById(R.id.showInterstitialButton);
loadInterstitialButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
if (interstitialAd != null) {
interstitialAd.destroy();
interstitialAd = null;
}
setLabel("Loading interstitial ad...");
// Create the interstitial unit with a placement ID (generate your own on the Facebook
// app settings).
// Use different ID for each ad placement in your app.
interstitialAd =
// NULLSAFE_FIXME[Parameter Not Nullable]
new InterstitialAd(InterstitialFragment.this.getActivity(), "YOUR_PLACEMENT_ID");
// Load a new interstitial.
InterstitialAd.InterstitialLoadAdConfig loadAdConfig =
interstitialAd
.buildLoadAdConfig()
// Set a listener to get notified on changes
// or when the user interact with the ad.
.withAdListener(InterstitialFragment.this)
.withCacheFlags(EnumSet.of(CacheFlag.VIDEO))
.withRewardData(new RewardData("YOUR_USER_ID", "YOUR_REWARD", 10))
.build();
interstitialAd.loadAd(loadAdConfig);
}
});
showInterstitialButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
if (interstitialAd == null
|| !interstitialAd.isAdLoaded()
|| interstitialAd.isAdInvalidated()) {
// Ad not ready to show.
setLabel("Ad not loaded. Click load to request an ad.");
} else {
// Ad was loaded, show it!
setLabel("");
interstitialAd.show();
}
}
});
return view;
}
@Override
public void onDestroy() {
if (interstitialAd != null) {
interstitialAd.destroy();
interstitialAd = null;
}
super.onDestroy();
}
@Override
public void onError(Ad ad, AdError error) {
if (ad == interstitialAd) {
setLabel("Interstitial ad failed to load: " + error.getErrorMessage());
}
}
@Override
public void onAdLoaded(Ad ad) {
if (ad == interstitialAd) {
setLabel("Ad loaded. Click show to present!");
}
}
@Override
public void onInterstitialDisplayed(Ad ad) {
showToast("Interstitial Displayed");
}
@Override
public void onInterstitialDismissed(Ad ad) {
showToast("Interstitial Dismissed");
// Cleanup.
Preconditions.checkNotNull(interstitialAd).destroy();
interstitialAd = null;
}
@Override
public void onAdClicked(Ad ad) {
showToast("Interstitial Clicked");
}
@Override
public void onLoggingImpression(Ad ad) {
Log.d(TAG, "onLoggingImpression");
showToast("Interstitial Impression");
}
private void setLabel(String label) {
statusLabel = label;
if (interstitialAdStatusLabel != null) {
interstitialAdStatusLabel.setText(statusLabel);
}
}
@Override
public void onRewardedAdCompleted() {
showToast("Reward Received");
}
@Override
public void onRewardedAdServerSucceeded() {
showToast("Server success!");
}
@Override
public void onRewardedAdServerFailed() {
showToast("Server failure");
}
@Override
public void onInterstitialActivityDestroyed() {
showToast("Activity destroyed");
}
private void showToast(String message) {
Log.d(TAG, message);
if (isAdded()) {
DebugToast.show(requireActivity(), message, Toast.LENGTH_SHORT);
}
}
}
================================================
FILE: samples/android/AdUnitsSample/src/main/java/com/facebook/samples/AdUnitsSample/fragments/MultiLoadInterstitialFragment.java
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.AdUnitsSample.fragments;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.facebook.ads.Ad;
import com.facebook.ads.AdError;
import com.facebook.ads.CacheFlag;
import com.facebook.ads.InterstitialAd;
import com.facebook.ads.InterstitialAdExtendedListener;
import com.facebook.ads.RewardData;
import com.facebook.samples.AdUnitsSample.R;
import com.facebook.samples.ads.debugsettings.DebugToast;
import java.util.EnumSet;
public class MultiLoadInterstitialFragment extends Fragment
implements InterstitialAdExtendedListener {
private static final String TAG = MultiLoadInterstitialFragment.class.getSimpleName();
@Nullable private TextView mInterstitialAdStatusLabel;
@Nullable private Button mLoadInterstitialButton;
@Nullable private Button mShowInterstitialButton;
@Nullable private InterstitialAd mInterstitialAd;
@Nullable private TextView mInterstitialAdStatusLabel2;
@Nullable private Button mLoadInterstitialButton2;
@Nullable private Button mShowInterstitialButton2;
@Nullable private InterstitialAd mInterstitialAd2;
@Nullable private TextView mInterstitialAdStatusLabel3;
@Nullable private Button mLoadInterstitialButton3;
@Nullable private Button mShowInterstitialButton3;
@Nullable private InterstitialAd mInterstitialAd3;
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_multi_load_interstitial, container, false);
mInterstitialAdStatusLabel = (TextView) view.findViewById(R.id.interstitialAdStatusLabel);
mLoadInterstitialButton = (Button) view.findViewById(R.id.loadInterstitialButton);
mShowInterstitialButton = (Button) view.findViewById(R.id.showInterstitialButton);
if (mInterstitialAdStatusLabel == null
|| mLoadInterstitialButton == null
|| mShowInterstitialButton == null) {
return view;
}
mLoadInterstitialButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mInterstitialAd != null) {
mInterstitialAd.destroy();
mInterstitialAd = null;
}
setLabel(mInterstitialAdStatusLabel, "Loading interstitial ad...");
// Create the interstitial unit with a placement ID (generate your own on the Facebook
// app settings).
// Use different ID for each ad placement in your app.
mInterstitialAd =
new InterstitialAd(
MultiLoadInterstitialFragment.this.requireActivity(), "YOUR_PLACEMENT_ID");
// Load a new interstitial.
InterstitialAd.InterstitialLoadAdConfig loadAdConfig =
mInterstitialAd
.buildLoadAdConfig()
// Set a listener to get notified on changes
// or when the user interact with the ad.
.withAdListener(MultiLoadInterstitialFragment.this)
.withCacheFlags(EnumSet.of(CacheFlag.VIDEO))
.withRewardData(new RewardData("YOUR_USER_ID", "YOUR_REWARD", 10))
.build();
mInterstitialAd.loadAd(loadAdConfig);
}
});
mShowInterstitialButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mInterstitialAd == null
|| !mInterstitialAd.isAdLoaded()
|| mInterstitialAd.isAdInvalidated()) {
// Ad not ready to show.
setLabel(mInterstitialAdStatusLabel, "Ad not loaded. Click load to request an ad.");
} else {
// Ad was loaded, show it!
mInterstitialAd.show();
setLabel(mInterstitialAdStatusLabel, "");
}
}
});
mInterstitialAdStatusLabel2 = (TextView) view.findViewById(R.id.interstitialAdStatusLabel2);
mLoadInterstitialButton2 = (Button) view.findViewById(R.id.loadInterstitialButton2);
mShowInterstitialButton2 = (Button) view.findViewById(R.id.showInterstitialButton2);
if (mInterstitialAdStatusLabel2 == null
|| mLoadInterstitialButton2 == null
|| mShowInterstitialButton2 == null) {
return view;
}
mLoadInterstitialButton2.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mInterstitialAd2 != null) {
mInterstitialAd2.destroy();
mInterstitialAd2 = null;
}
setLabel(mInterstitialAdStatusLabel2, "Loading interstitial ad...");
// Create the interstitial unit with a placement ID (generate your own on the Facebook
// app settings).
// Use different ID for each ad placement in your app.
mInterstitialAd2 =
new InterstitialAd(
MultiLoadInterstitialFragment.this.requireActivity(), "YOUR_PLACEMENT_ID");
// Load a new interstitial.
InterstitialAd.InterstitialLoadAdConfig loadAdConfig =
mInterstitialAd2
.buildLoadAdConfig()
// Set a listener to get notified on changes
// or when the user interact with the ad.
.withAdListener(MultiLoadInterstitialFragment.this)
.withCacheFlags(EnumSet.of(CacheFlag.VIDEO))
.withRewardData(new RewardData("YOUR_USER_ID", "YOUR_REWARD", 10))
.build();
mInterstitialAd2.loadAd(loadAdConfig);
}
});
mShowInterstitialButton2.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mInterstitialAd2 == null
|| !mInterstitialAd2.isAdLoaded()
|| mInterstitialAd2.isAdInvalidated()) {
// Ad not ready to show.
setLabel(mInterstitialAdStatusLabel2, "Ad not loaded. Click load to request an ad.");
} else {
// Ad was loaded, show it!
mInterstitialAd2.show();
setLabel(mInterstitialAdStatusLabel2, "");
}
}
});
mInterstitialAdStatusLabel3 = (TextView) view.findViewById(R.id.interstitialAdStatusLabel3);
mLoadInterstitialButton3 = (Button) view.findViewById(R.id.loadInterstitialButton3);
mShowInterstitialButton3 = (Button) view.findViewById(R.id.showInterstitialButton3);
if (mInterstitialAdStatusLabel3 == null
|| mLoadInterstitialButton3 == null
|| mShowInterstitialButton3 == null) {
return view;
}
mLoadInterstitialButton3.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mInterstitialAd3 != null) {
mInterstitialAd3.destroy();
mInterstitialAd3 = null;
}
setLabel(mInterstitialAdStatusLabel3, "Loading interstitial ad...");
// Create the interstitial unit with a placement ID (generate your own on the Facebook
// app settings).
// Use different ID for each ad placement in your app.
mInterstitialAd3 =
new InterstitialAd(
MultiLoadInterstitialFragment.this.requireActivity(), "YOUR_PLACEMENT_ID");
// Load a new interstitial.
InterstitialAd.InterstitialLoadAdConfig loadAdConfig =
mInterstitialAd3
.buildLoadAdConfig()
// Set a listener to get notified on changes
// or when the user interact with the ad.
.withAdListener(MultiLoadInterstitialFragment.this)
.withCacheFlags(EnumSet.of(CacheFlag.VIDEO))
.withRewardData(new RewardData("YOUR_USER_ID", "YOUR_REWARD", 10))
.build();
mInterstitialAd3.loadAd(loadAdConfig);
}
});
mShowInterstitialButton3.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mInterstitialAd3 == null
|| !mInterstitialAd3.isAdLoaded()
|| mInterstitialAd3.isAdInvalidated()) {
// Ad not ready to show.
setLabel(mInterstitialAdStatusLabel3, "Ad not loaded. Click load to request an ad.");
} else {
// Ad was loaded, show it!
mInterstitialAd3.show();
setLabel(mInterstitialAdStatusLabel3, "");
}
}
});
return view;
}
private void destroy(@Nullable InterstitialAd interstitialAd) {
if (interstitialAd != null) {
interstitialAd.destroy();
interstitialAd = null;
}
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onDestroyView() {
super.onDestroyView();
destroy(mInterstitialAd);
destroy(mInterstitialAd2);
destroy(mInterstitialAd3);
mInterstitialAdStatusLabel = null;
mInterstitialAdStatusLabel2 = null;
mInterstitialAdStatusLabel3 = null;
mLoadInterstitialButton = null;
mLoadInterstitialButton2 = null;
mLoadInterstitialButton3 = null;
mShowInterstitialButton = null;
mShowInterstitialButton2 = null;
mShowInterstitialButton3 = null;
}
@Override
public void onError(Ad ad, AdError error) {
if (ad == mInterstitialAd) {
setLabel(
mInterstitialAdStatusLabel, "Interstitial ad failed to load: " + error.getErrorMessage());
} else if (ad == mInterstitialAd2) {
setLabel(
mInterstitialAdStatusLabel2,
"Interstitial ad failed to load: " + error.getErrorMessage());
} else if (ad == mInterstitialAd3) {
setLabel(
mInterstitialAdStatusLabel3,
"Interstitial ad failed to load: " + error.getErrorMessage());
}
}
@Override
public void onAdLoaded(Ad ad) {
if (ad == mInterstitialAd) {
setLabel(mInterstitialAdStatusLabel, "Ad loaded. Click show to present!");
} else if (ad == mInterstitialAd2) {
setLabel(mInterstitialAdStatusLabel2, "Ad loaded. Click show to present!");
} else if (ad == mInterstitialAd3) {
setLabel(mInterstitialAdStatusLabel3, "Ad loaded. Click show to present!");
}
}
@Override
public void onInterstitialDisplayed(Ad ad) {
showToast("Interstitial Displayed");
}
@Override
public void onInterstitialDismissed(Ad ad) {
showToast("Interstitial Dismissed");
// Cleanup.
if (ad == mInterstitialAd) {
destroy(mInterstitialAd);
} else if (ad == mInterstitialAd2) {
destroy(mInterstitialAd2);
} else if (ad == mInterstitialAd3) {
destroy(mInterstitialAd3);
}
}
@Override
public void onAdClicked(Ad ad) {
showToast("Interstitial Clicked");
}
/** showing toast for tracking impression for manual testing */
@Override
public void onLoggingImpression(Ad ad) {
Log.d(TAG, "onLoggingImpression");
showToast("Interstitial Impression");
}
private void setLabel(@Nullable TextView interstitialAdStatusLabel, String label) {
if (interstitialAdStatusLabel != null) {
interstitialAdStatusLabel.setText(label);
}
}
@Override
public void onRewardedAdCompleted() {}
@Override
public void onRewardedAdServerSucceeded() {}
@Override
public void onRewardedAdServerFailed() {}
@Override
public void onInterstitialActivityDestroyed() {
showToast("Activity destroyed");
}
private void showToast(String message) {
Log.d(TAG, message);
if (isAdded()) {
DebugToast.show(requireActivity(), message, Toast.LENGTH_SHORT);
}
}
}
================================================
FILE: samples/android/AdUnitsSample/src/main/java/com/facebook/samples/AdUnitsSample/fragments/NativeAdHScrollFragment.java
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.AdUnitsSample.fragments;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.facebook.ads.AdError;
import com.facebook.ads.NativeAd;
import com.facebook.ads.NativeAdScrollView;
import com.facebook.ads.NativeAdsManager;
import com.facebook.common.preconditions.Preconditions;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.samples.AdUnitsSample.R;
import com.facebook.samples.ads.debugsettings.DebugToast;
@Nullsafe(Nullsafe.Mode.LOCAL)
public class NativeAdHScrollFragment extends Fragment implements NativeAdsManager.Listener {
private static final int NATIVE_AD_VIEW_HEIGHT_DP = 300;
private NativeAdsManager manager;
private @Nullable NativeAdScrollView scrollView;
private LinearLayout scrollViewContainer;
@Override
public View onCreateView(
LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_native_ad_hscroll, container, false);
// Create native options to enable or disable the different options on media
NativeAd.NativeOptions nativeOptions =
new NativeAd.NativeOptions()
.setDisableFullScreen(false)
.setHideMediaControls(false)
.setUnMuteVolume(false);
manager = new NativeAdsManager(requireActivity(), "YOUR_PLACEMENT_ID", 5, nativeOptions);
manager.setListener(this);
manager.loadAds(NativeAd.MediaCacheFlag.ALL);
Button reloadButton = (Button) view.findViewById(R.id.reload_hscroll);
Preconditions.checkNotNull(reloadButton)
.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
manager.loadAds();
}
});
// NULLSAFE_FIXME[Field Not Nullable]
scrollViewContainer = (LinearLayout) view.findViewById(R.id.hscroll_container);
return view;
}
@Override
public void onAdsLoaded() {
if (getActivity() == null) {
return;
}
DebugToast.show(getActivity(), "Ads loaded", Toast.LENGTH_SHORT);
if (scrollView != null) {
scrollViewContainer.removeView(scrollView);
}
scrollView = new NativeAdScrollView(getActivity(), manager, NATIVE_AD_VIEW_HEIGHT_DP);
scrollViewContainer.addView(scrollView);
}
@Override
public void onAdError(AdError error) {
DebugToast.show(requireActivity(), "Ad error: " + error.getErrorMessage(), Toast.LENGTH_SHORT);
}
}
================================================
FILE: samples/android/AdUnitsSample/src/main/java/com/facebook/samples/AdUnitsSample/fragments/NativeAdRecyclerFragment.java
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.AdUnitsSample.fragments;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.facebook.ads.AdError;
import com.facebook.ads.NativeAd;
import com.facebook.ads.NativeAdsManager;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.samples.AdUnitsSample.R;
import com.facebook.samples.AdUnitsSample.adapters.NativeAdRecyclerAdapter;
import com.facebook.samples.AdUnitsSample.models.RecyclerPostItem;
import com.facebook.samples.AdUnitsSample.thirdparty.DividerItemDecoration.DividerItemDecoration;
import java.util.ArrayList;
@Nullsafe(Nullsafe.Mode.LOCAL)
public class NativeAdRecyclerFragment extends Fragment implements NativeAdsManager.Listener {
private ArrayList mPostItemList;
private NativeAdsManager mNativeAdsManager;
private RecyclerView mRecyclerView;
@Override
public View onCreateView(
LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// Create some dummy post items
mPostItemList = new ArrayList<>();
for (int i = 1; i <= 100; i++) {
mPostItemList.add(new RecyclerPostItem("RecyclerView Item #" + i));
}
String placement_id = "YOUR_PLACEMENT_ID";
// Create native options to enable or disable the different options on media
NativeAd.NativeOptions nativeOptions =
new NativeAd.NativeOptions()
.setDisableFullScreen(false)
.setHideMediaControls(false)
.setUnMuteVolume(false);
mNativeAdsManager = new NativeAdsManager(requireActivity(), placement_id, 5, nativeOptions);
mNativeAdsManager.loadAds();
mNativeAdsManager.setListener(this);
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_native_ad_recycler, container, false);
// NULLSAFE_FIXME[Field Not Nullable]
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
return view;
}
@Override
public void onAdsLoaded() {
if (getActivity() == null) {
return;
}
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
RecyclerView.ItemDecoration itemDecoration =
new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST);
mRecyclerView.addItemDecoration(itemDecoration);
NativeAdRecyclerAdapter adapter =
new NativeAdRecyclerAdapter(getActivity(), mPostItemList, mNativeAdsManager);
mRecyclerView.setAdapter(adapter);
}
@Override
public void onAdError(AdError error) {}
}
================================================
FILE: samples/android/AdUnitsSample/src/main/java/com/facebook/samples/AdUnitsSample/fragments/NativeAdSampleFragment.java
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.AdUnitsSample.fragments;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.facebook.ads.Ad;
import com.facebook.ads.AdClosedListener;
import com.facebook.ads.AdError;
import com.facebook.ads.AdOptionsView;
import com.facebook.ads.MediaView;
import com.facebook.ads.MediaViewListener;
import com.facebook.ads.NativeAd;
import com.facebook.ads.NativeAdBase.NativeComponentTag;
import com.facebook.ads.NativeAdLayout;
import com.facebook.ads.NativeAdListener;
import com.facebook.common.preconditions.Preconditions;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.samples.AdUnitsSample.R;
import com.facebook.samples.ads.debugsettings.DebugToast;
import java.util.ArrayList;
import java.util.List;
@Nullsafe(Nullsafe.Mode.LOCAL)
public class NativeAdSampleFragment extends Fragment implements NativeAdListener {
protected static final String TAG = NativeAdSampleFragment.class.getSimpleName();
private @Nullable TextView nativeAdStatus;
private @Nullable LinearLayout adChoicesContainer;
private @Nullable NativeAdLayout nativeAdLayout;
private @Nullable NativeAd nativeAd;
private @Nullable AdOptionsView adOptionsView;
// NULLSAFE_FIXME[Field Not Initialized]
private MediaView nativeAdMedia;
private NativeAd.NativeOptions mNativeOptions;
@Override
public View onCreateView(
LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_native_ad_sample, container, false);
nativeAdLayout = view.findViewById(R.id.native_ad_container);
nativeAdStatus = view.findViewById(R.id.native_ad_status);
adChoicesContainer = view.findViewById(R.id.ad_choices_container);
// Create native options to enable or disable the different options on media
mNativeOptions = new NativeAd.NativeOptions();
Switch disableFullScreenSwitch = view.findViewById(R.id.switch_fullscreen);
if (disableFullScreenSwitch != null) {
disableFullScreenSwitch.setOnCheckedChangeListener(
(compoundButton, isChecked) -> mNativeOptions.setDisableFullScreen(isChecked));
}
Switch unMuteSwitch = view.findViewById(R.id.switch_unmute);
if (unMuteSwitch != null) {
unMuteSwitch.setOnCheckedChangeListener(
(compoundButton, isChecked) -> mNativeOptions.setUnMuteVolume(isChecked));
}
Switch hideMediaControlsSwitch = view.findViewById(R.id.switch_hide_media_controls);
if (hideMediaControlsSwitch != null) {
hideMediaControlsSwitch.setOnCheckedChangeListener(
(compoundButton, isChecked) -> mNativeOptions.setHideMediaControls(isChecked));
}
Button showNativeAdButton = view.findViewById(R.id.load_native_ad_button);
Preconditions.checkNotNull(showNativeAdButton)
.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
if (nativeAdStatus != null) {
nativeAdStatus.setText(R.string.loading_status);
}
if (nativeAd != null) {
nativeAd.destroy();
}
// Create a native ad request with a unique placement ID (generate your own on the
// Facebook app settings). Use different ID for each ad placement in your app.
nativeAd = new NativeAd(requireActivity(), "YOUR_PLACEMENT_ID", mNativeOptions);
// When testing on a device, add its hashed ID to force test ads.
// The hash ID is printed to log cat when running on a device and loading an ad.
// AdSettings.addTestDevice("THE HASHED ID AS PRINTED TO LOG CAT");
// Initiate a request to load an ad.
nativeAd.loadAd(
nativeAd
.buildLoadAdConfig()
.withAdListener(NativeAdSampleFragment.this)
.build());
}
});
// if we already have loaded ad, render it
if (nativeAd != null) {
onAdLoaded(nativeAd);
}
return view;
}
@Override
public void onDestroyView() {
adChoicesContainer = null;
nativeAdLayout = null;
adOptionsView = null;
nativeAdStatus = null;
super.onDestroyView();
}
@Override
public void onError(Ad ad, AdError error) {
if (nativeAdStatus != null) {
nativeAdStatus.setText("Ad failed to load: " + error.getErrorMessage());
}
}
@Override
public void onAdClicked(Ad ad) {
showToast("Ad Clicked");
}
@Override
public void onLoggingImpression(Ad ad) {
showToast("Native Impression");
}
@Override
public void onMediaDownloaded(Ad ad) {
if (nativeAd == ad) {
Log.d(TAG, "onMediaDownloaded");
}
}
@Override
public void onAdLoaded(Ad ad) {
if (nativeAd == null || nativeAd != ad) {
// Race condition, load() called again before last ad was displayed
return;
}
if (nativeAdLayout == null) {
return;
}
// Unregister last ad
nativeAd.unregisterView();
if (nativeAdStatus != null) {
nativeAdStatus.setText("");
}
if (!nativeAd.isAdLoaded() || nativeAd.isAdInvalidated()) {
if (nativeAdStatus != null) {
nativeAdStatus.setText("Ad is not loaded or invalidated.");
}
return;
}
if (adChoicesContainer != null) {
// NULLSAFE_FIXME[Parameter Not Nullable]
adOptionsView = new AdOptionsView(getActivity(), nativeAd, nativeAdLayout);
adOptionsView.setOnAdClosedListener(
new AdClosedListener() {
@Override
public void onAdClosed() {
// Ad closed by user move to next ad
showToast("Ad closed by user!");
}
});
adChoicesContainer.removeAllViews();
adChoicesContainer.addView(adOptionsView, 0);
}
inflateAd(nativeAd, nativeAdLayout);
// Registering a touch listener to log which ad component receives the touch event.
// We always return false from onTouch so that we don't swallow the touch event (which
// would prevent click events from reaching the NativeAd control).
// The touch listener could be used to do animations.
nativeAd.setOnTouchListener(
new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
int i = view.getId();
if (i == R.id.native_ad_call_to_action) {
Log.d(TAG, "Call to action button clicked");
} else if (i == R.id.native_ad_media) {
Log.d(TAG, "Main image clicked");
} else {
Log.d(TAG, "Other ad component clicked");
}
}
return false;
}
});
}
private void inflateAd(NativeAd nativeAd, View adView) {
Log.d(TAG, "Aspect ratio of ad: " + nativeAd.getAspectRatio());
// Create native UI using the ad metadata.
MediaView nativeAdIcon = adView.findViewById(R.id.native_ad_icon);
TextView nativeAdTitle = adView.findViewById(R.id.native_ad_title);
TextView nativeAdBody = adView.findViewById(R.id.native_ad_body);
TextView sponsoredLabel = adView.findViewById(R.id.native_ad_sponsored_label);
TextView nativeAdSocialContext = adView.findViewById(R.id.native_ad_social_context);
Button nativeAdCallToAction = adView.findViewById(R.id.native_ad_call_to_action);
// NULLSAFE_FIXME[Field Not Nullable]
nativeAdMedia = adView.findViewById(R.id.native_ad_media);
nativeAdMedia.setListener(getMediaViewListener());
// Setting the Text
Preconditions.checkNotNull(nativeAdSocialContext).setText(nativeAd.getAdSocialContext());
// NULLSAFE_FIXME[Nullable Dereference]
nativeAdCallToAction.setText(nativeAd.getAdCallToAction());
// NULLSAFE_FIXME[Nullable Dereference]
nativeAdCallToAction.setVisibility(nativeAd.hasCallToAction() ? View.VISIBLE : View.INVISIBLE);
// NULLSAFE_FIXME[Nullable Dereference]
nativeAdTitle.setText(nativeAd.getAdvertiserName());
// NULLSAFE_FIXME[Nullable Dereference]
nativeAdBody.setText(nativeAd.getAdBodyText());
// NULLSAFE_FIXME[Nullable Dereference]
sponsoredLabel.setText(R.string.sponsored);
// You can use the following to specify the clickable areas.
List clickableViews = new ArrayList<>();
clickableViews.add(nativeAdIcon);
clickableViews.add(nativeAdMedia);
clickableViews.add(nativeAdCallToAction);
nativeAd.registerViewForInteraction(
// NULLSAFE_FIXME[Parameter Not Nullable]
nativeAdLayout, nativeAdMedia, nativeAdIcon, clickableViews);
if (nativeAdMedia.isVideoContent()) {
showToast("This is video content!!!");
showToast("Video duration: " + nativeAdMedia.getVideoDuration());
}
// Optional: tag views
// NULLSAFE_FIXME[Parameter Not Nullable]
NativeComponentTag.tagView(nativeAdIcon, NativeComponentTag.AD_ICON);
// NULLSAFE_FIXME[Parameter Not Nullable]
NativeComponentTag.tagView(nativeAdTitle, NativeComponentTag.AD_TITLE);
// NULLSAFE_FIXME[Parameter Not Nullable]
NativeComponentTag.tagView(nativeAdBody, NativeComponentTag.AD_BODY);
NativeComponentTag.tagView(nativeAdSocialContext, NativeComponentTag.AD_SOCIAL_CONTEXT);
// NULLSAFE_FIXME[Parameter Not Nullable]
NativeComponentTag.tagView(nativeAdCallToAction, NativeComponentTag.AD_CALL_TO_ACTION);
}
@Override
public void onDestroy() {
if (nativeAdMedia != null) {
nativeAdMedia.destroy();
}
if (nativeAd != null) {
nativeAd.unregisterView();
nativeAd.destroy();
}
super.onDestroy();
}
private static MediaViewListener getMediaViewListener() {
return new MediaViewListener() {
@Override
public void onVolumeChange(MediaView mediaView, float volume) {
Log.i(TAG, "MediaViewEvent: Volume " + volume);
}
@Override
public void onPause(MediaView mediaView) {
Log.i(TAG, "MediaViewEvent: Paused");
}
@Override
public void onPlay(MediaView mediaView) {
Log.i(TAG, "MediaViewEvent: Play");
}
@Override
public void onFullscreenBackground(MediaView mediaView) {
Log.i(TAG, "MediaViewEvent: FullscreenBackground");
}
@Override
public void onFullscreenForeground(MediaView mediaView) {
Log.i(TAG, "MediaViewEvent: FullscreenForeground");
}
@Override
public void onExitFullscreen(MediaView mediaView) {
Log.i(TAG, "MediaViewEvent: ExitFullscreen");
}
@Override
public void onEnterFullscreen(MediaView mediaView) {
Log.i(TAG, "MediaViewEvent: EnterFullscreen");
}
@Override
public void onComplete(MediaView mediaView) {
Log.i(TAG, "MediaViewEvent: Completed");
}
};
}
private void showToast(String message) {
if (isAdded()) {
DebugToast.show(requireActivity(), message, Toast.LENGTH_SHORT);
}
}
}
================================================
FILE: samples/android/AdUnitsSample/src/main/java/com/facebook/samples/AdUnitsSample/fragments/NativeAdTemplateFragment.java
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.AdUnitsSample.fragments;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import android.app.Activity;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.Spinner;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.facebook.ads.Ad;
import com.facebook.ads.AdError;
import com.facebook.ads.NativeAd;
import com.facebook.ads.NativeAdListener;
import com.facebook.ads.NativeAdView;
import com.facebook.ads.NativeAdViewAttributes;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.samples.AdUnitsSample.R;
@Nullsafe(Nullsafe.Mode.LOCAL)
public class NativeAdTemplateFragment extends Fragment implements NativeAdListener {
private static final String TAG = NativeAdTemplateFragment.class.getSimpleName();
private static final int COLOR_LIGHT_GRAY = 0xff90949c;
private static final int COLOR_DARK_GRAY = 0xff4e5665;
private static final int COLOR_CTA_BLUE_BG = 0xff4080ff;
private static final int MIN_HEIGHT_DP = 200;
private static final int MAX_HEIGHT_DP = 500;
private static final int DEFAULT_HEIGHT_DP = 350;
private static final int DEFAULT_PROGRESS_DP = 50;
private @Nullable NativeAd mNativeAd;
private int mLayoutHeightDp = DEFAULT_HEIGHT_DP;
private int mAdBackgroundColor, mTitleColor, mCtaTextColor, mContentColor, mCtaBgColor;
private TextView mStatusText;
private ViewGroup mNativeAdContainer;
private Spinner mBackgroundColorSpinner;
private Button mShowCodeButton, mReloadButton;
private SeekBar mSeekBar;
@Nullable private View mAdView;
@Override
public View onCreateView(
LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_native_ad_template, container, false);
// NULLSAFE_FIXME[Field Not Nullable]
mStatusText = view.findViewById(R.id.status);
// NULLSAFE_FIXME[Field Not Nullable]
mNativeAdContainer = view.findViewById(R.id.templateContainer);
// NULLSAFE_FIXME[Field Not Nullable]
mShowCodeButton = view.findViewById(R.id.showCodeButton);
// NULLSAFE_FIXME[Field Not Nullable]
mReloadButton = view.findViewById(R.id.reloadAdButton);
// NULLSAFE_FIXME[Field Not Nullable]
mBackgroundColorSpinner = view.findViewById(R.id.backgroundColorSpinner);
// NULLSAFE_FIXME[Field Not Nullable]
mSeekBar = view.findViewById(R.id.seekBar);
setUpLayoutBuilders();
setUpButtons();
createAndLoadNativeAd();
return view;
}
@Override
public void onAdLoaded(Ad ad) {
if (mNativeAd == null || mNativeAd != ad) {
// Race condition, load() called again before last ad was displayed
return;
}
mStatusText.setText(R.string.ad_loaded);
reloadAdContainer();
}
@Override
public void onError(Ad ad, AdError error) {
String msg = getResources().getString(R.string.ad_load_failed, error.getErrorMessage());
mStatusText.setText(msg);
}
@Override
public void onAdClicked(Ad ad) {
mStatusText.setText(R.string.ad_clicked);
}
@Override
public void onLoggingImpression(Ad ad) {
Log.d(TAG, "onLoggingImpression");
}
@Override
public void onMediaDownloaded(Ad ad) {
Log.d(TAG, "onMediaDownloaded");
}
@Override
public void onDestroy() {
mNativeAd = null;
super.onDestroy();
}
private void createAndLoadNativeAd() {
// Create a native ad request with a unique placement ID
// (generate your own on the Facebook app settings).
// Use different ID for each ad placement in your app.
// NULLSAFE_FIXME[Parameter Not Nullable]
mNativeAd = new NativeAd(getActivity(), "YOUR_PLACEMENT_ID");
// Initiate a request to load an ad.
mNativeAd.loadAd(mNativeAd.buildLoadAdConfig().withAdListener(this).build());
mStatusText.setText(R.string.ad_loading);
}
private void reloadAdContainer() {
Activity activity = getActivity();
if (activity != null
&& mNativeAd != null
&& mNativeAd.isAdLoaded()
&& !mNativeAd.isAdInvalidated()) {
mNativeAdContainer.removeAllViews();
// Create a NativeAdViewAttributes object and set the attributes
NativeAdViewAttributes attributes =
new NativeAdViewAttributes()
.setBackgroundColor(mAdBackgroundColor)
.setTitleTextColor(mTitleColor)
.setDescriptionTextColor(mContentColor)
.setButtonBorderColor(mCtaTextColor)
.setButtonTextColor(mCtaTextColor)
.setButtonColor(mCtaBgColor);
// Use NativeAdView.render to generate the ad View
mAdView = NativeAdView.render(activity, mNativeAd, attributes);
mNativeAdContainer.addView(mAdView, new ViewGroup.LayoutParams(MATCH_PARENT, 0));
updateAdViewParams();
mShowCodeButton.setText(R.string.show_code);
}
}
private void setUpLayoutBuilders() {
ArrayAdapter backgroundColorSpinnerAdapter =
ArrayAdapter.createFromResource(
// NULLSAFE_FIXME[Parameter Not Nullable]
getActivity(), R.array.background_color_array, android.R.layout.simple_spinner_item);
backgroundColorSpinnerAdapter.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);
mBackgroundColorSpinner.setAdapter(backgroundColorSpinnerAdapter);
mBackgroundColorSpinner.setOnItemSelectedListener(
new android.widget.AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView> arg0, View view, int position, long id) {
int item = mBackgroundColorSpinner.getSelectedItemPosition();
switch (item) {
case 0:
mAdBackgroundColor = Color.WHITE;
mTitleColor = COLOR_DARK_GRAY;
mCtaTextColor = COLOR_CTA_BLUE_BG;
mContentColor = COLOR_LIGHT_GRAY;
mCtaBgColor = Color.WHITE;
break;
case 1:
mAdBackgroundColor = Color.BLACK;
mTitleColor = Color.WHITE;
mContentColor = Color.LTGRAY;
mCtaTextColor = Color.BLACK;
mCtaBgColor = Color.WHITE;
break;
}
reloadAdContainer();
}
@Override
public void onNothingSelected(AdapterView> parent) {}
});
mSeekBar.setProgress(DEFAULT_PROGRESS_DP);
mSeekBar.setOnSeekBarChangeListener(
new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mLayoutHeightDp = progress * ((MAX_HEIGHT_DP - MIN_HEIGHT_DP) / 100) + MIN_HEIGHT_DP;
updateAdViewParams();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {}
});
}
private void updateAdViewParams() {
if (mAdView == null) {
return;
}
ViewGroup.LayoutParams params = mAdView.getLayoutParams();
params.height = (int) (Resources.getSystem().getDisplayMetrics().density * mLayoutHeightDp);
mAdView.setLayoutParams(params);
mAdView.requestLayout();
}
private void setUpButtons() {
mShowCodeButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mShowCodeButton.getText() == getResources().getString(R.string.show_ad)) {
reloadAdContainer();
} else {
showCodeInAdContainer();
}
}
});
mReloadButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
createAndLoadNativeAd();
}
});
}
private void showCodeInAdContainer() {
String[] lines = getResources().getStringArray(R.array.code_snippet_mediumrect_template);
StringBuilder codeSnippet = new StringBuilder();
for (String line : lines) {
codeSnippet.append(line).append("\r\n");
}
mNativeAdContainer.removeAllViews();
// NULLSAFE_FIXME[Parameter Not Nullable]
TextView code = new TextView(getActivity());
code.setText(codeSnippet);
code.setBackgroundColor(Color.WHITE);
code.setTextColor(Color.BLACK);
mNativeAdContainer.addView(code, 0);
mShowCodeButton.setText(R.string.show_ad);
}
}
================================================
FILE: samples/android/AdUnitsSample/src/main/java/com/facebook/samples/AdUnitsSample/fragments/NativeBannerAdFragment.java
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.AdUnitsSample.fragments;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.facebook.ads.Ad;
import com.facebook.ads.AdError;
import com.facebook.ads.AdOptionsView;
import com.facebook.ads.MediaView;
import com.facebook.ads.NativeAdBase;
import com.facebook.ads.NativeAdLayout;
import com.facebook.ads.NativeAdListener;
import com.facebook.ads.NativeBannerAd;
import com.facebook.samples.AdUnitsSample.R;
import com.facebook.samples.ads.debugsettings.DebugToast;
import java.util.ArrayList;
import java.util.List;
public class NativeBannerAdFragment extends Fragment implements NativeAdListener {
public static final String USE_IMAGE_VIEW = "useImageView";
private static final String TAG = NativeBannerAdFragment.class.getSimpleName();
private LinearLayout mAdView;
private FrameLayout mAdChoicesContainer;
private NativeAdLayout mNativeBannerAdContainer;
private @Nullable NativeBannerAd mNativeBannerAd;
private TextView mNativeBannerAdStatusLabel;
private boolean isAdViewAdded;
private boolean mUseImageView;
public static NativeBannerAdFragment newInstance(boolean useImageView) {
NativeBannerAdFragment myFragment = new NativeBannerAdFragment();
Bundle args = new Bundle();
args.putBoolean(USE_IMAGE_VIEW, useImageView);
myFragment.setArguments(args);
return myFragment;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle arguments = getArguments();
if (arguments != null) {
mUseImageView = arguments.getBoolean(USE_IMAGE_VIEW, false);
}
}
@Nullable
@Override
public View onCreateView(
LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_native_banner_ad, container, false);
mNativeBannerAdContainer = view.findViewById(R.id.native_banner_ad_container);
mNativeBannerAdStatusLabel = view.findViewById(R.id.native_banner_status_label);
mAdView =
(LinearLayout)
inflater.inflate(R.layout.native_banner_ad_unit, mNativeBannerAdContainer, false);
mAdChoicesContainer = mAdView.findViewById(R.id.ad_choices_container);
Button showNativeBannerAdButton = view.findViewById(R.id.refresh_native_banner_button);
showNativeBannerAdButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
mNativeBannerAdStatusLabel.setText(getString(R.string.loading_status));
// Create a native ad request with a unique placement ID (generate your own on the
// Facebook app settings). Use different ID for each ad placement in your app.
mNativeBannerAd = new NativeBannerAd(getContext(), "YOUR_PLACEMENT_ID");
// When testing on a device, add its hashed ID to force test ads.
// The hash ID is printed to log cat when running on a device and loading an ad.
// AdSettings.addTestDevice("THE HASHED ID AS PRINTED TO LOG CAT");
// Initiate a request to load an ad.
mNativeBannerAd.loadAd(
mNativeBannerAd
.buildLoadAdConfig()
.withMediaCacheFlag(NativeAdBase.MediaCacheFlag.ALL)
.withAdListener(NativeBannerAdFragment.this)
.build());
}
});
// load the Native Banner when this fragment is created
// as the Banner in BannerFragment does.
showNativeBannerAdButton.performClick();
return view;
}
@Override
public void onError(Ad ad, AdError error) {
mNativeBannerAdStatusLabel.setText("Ad Failed to Load: " + error.getErrorMessage());
}
@Override
public void onAdLoaded(Ad ad) {
if (mNativeBannerAd == null || mNativeBannerAd != ad) {
// Race condition, load() called again before last ad was displayed
return;
}
if (!isAdViewAdded) {
isAdViewAdded = true;
mNativeBannerAdContainer.addView(mAdView);
}
// Unregister last ad
mNativeBannerAd.unregisterView();
mNativeBannerAdStatusLabel.setText("");
if (!mNativeBannerAd.isAdLoaded() || mNativeBannerAd.isAdInvalidated()) {
mNativeBannerAdStatusLabel.setText("Ad is not loaded or invalidated.");
return;
}
// Using the AdOptionsView is optional, but your native ad unit should
// be clearly delineated from the rest of your app content. See
// https://developers.facebook.com/docs/audience-network/guidelines/native-ads#native
// for details. We recommend using the AdOptionsView.
AdOptionsView adOptionsView =
new AdOptionsView(
getActivity(),
mNativeBannerAd,
mNativeBannerAdContainer,
AdOptionsView.Orientation.HORIZONTAL,
20);
mAdChoicesContainer.removeAllViews();
mAdChoicesContainer.addView(adOptionsView);
inflateAd(mNativeBannerAd, mAdView);
// Registering a touch listener to log which ad component receives the touch event.
// We always return false from onTouch so that we don't swallow the touch event (which
// would prevent click events from reaching the NativeAd control).
// The touch listener could be used to do animations.
mNativeBannerAd.setOnTouchListener(
new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
int i = view.getId();
if (i == R.id.native_ad_call_to_action) {
Log.d(TAG, "Call to action button clicked");
} else if (i == R.id.native_icon_view) {
Log.d(TAG, "Main image clicked");
} else {
Log.d(TAG, "Other ad component clicked");
}
}
return false;
}
});
}
@Override
public void onAdClicked(Ad ad) {
DebugToast.show(requireActivity(), "Ad Clicked", Toast.LENGTH_SHORT);
}
@Override
public void onLoggingImpression(Ad ad) {
Log.d(TAG, "onLoggingImpression");
}
@Override
public void onMediaDownloaded(Ad ad) {
Log.d(TAG, "onMediaDownloaded");
}
private void inflateAd(NativeBannerAd nativeBannerAd, View adView) {
// Create native UI using the ad metadata.
TextView nativeAdTitle = adView.findViewById(R.id.native_ad_title);
TextView nativeAdSocialContext = adView.findViewById(R.id.native_ad_social_context);
TextView sponsoredLabel = adView.findViewById(R.id.native_ad_sponsored_label);
Button nativeAdCallToAction = adView.findViewById(R.id.native_ad_call_to_action);
// Setting the Text
nativeAdCallToAction.setText(nativeBannerAd.getAdCallToAction());
nativeAdCallToAction.setVisibility(
nativeBannerAd.hasCallToAction() ? View.VISIBLE : View.INVISIBLE);
nativeAdTitle.setText(nativeBannerAd.getAdvertiserName());
nativeAdSocialContext.setText(nativeBannerAd.getAdSocialContext());
// You can use the following to specify the clickable areas.
List clickableViews = new ArrayList<>();
clickableViews.add(nativeAdCallToAction);
MediaView nativeAdIconView = adView.findViewById(R.id.native_icon_view);
ImageView nativeImageViewAdIconView = adView.findViewById(R.id.image_view_icon_view);
if (mUseImageView) {
nativeAdIconView.setVisibility(View.GONE);
nativeImageViewAdIconView.setVisibility(View.VISIBLE);
nativeBannerAd.registerViewForInteraction(
mNativeBannerAdContainer, nativeImageViewAdIconView, clickableViews);
} else { // use MediaView
nativeAdIconView.setVisibility(View.VISIBLE);
nativeImageViewAdIconView.setVisibility(View.GONE);
nativeBannerAd.registerViewForInteraction(
mNativeBannerAdContainer, nativeAdIconView, clickableViews);
}
sponsoredLabel.setText(R.string.sponsored);
}
@Override
public void onDestroy() {
if (mNativeBannerAd != null) {
mNativeBannerAd.unregisterView();
mNativeBannerAd = null;
}
super.onDestroy();
}
}
================================================
FILE: samples/android/AdUnitsSample/src/main/java/com/facebook/samples/AdUnitsSample/fragments/NativeBannerAdTemplateFragment.java
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.AdUnitsSample.fragments;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.facebook.ads.Ad;
import com.facebook.ads.AdError;
import com.facebook.ads.NativeAdListener;
import com.facebook.ads.NativeAdViewAttributes;
import com.facebook.ads.NativeBannerAd;
import com.facebook.ads.NativeBannerAdView;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.samples.AdUnitsSample.R;
@Nullsafe(Nullsafe.Mode.LOCAL)
public class NativeBannerAdTemplateFragment extends Fragment implements NativeAdListener {
private static final String TAG = NativeBannerAdTemplateFragment.class.getSimpleName();
private static final int COLOR_LIGHT_GRAY = 0xff90949c;
private static final int COLOR_DARK_GRAY = 0xff4e5665;
private static final int COLOR_CTA_BLUE_BG = 0xff4080ff;
private @Nullable NativeBannerAd mNativeBannerAd;
private NativeBannerAdView.Type mViewType = NativeBannerAdView.Type.HEIGHT_100;
private int mAdBackgroundColor, mTitleColor, mLinkColor, mContentColor, mCtaBgColor;
private TextView mStatusText;
private ViewGroup mNativeAdContainer;
private Spinner mBackgroundColorSpinner;
private Spinner mAdViewTypeSpinner;
private Button mShowCodeButton;
@Override
public View onCreateView(
LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_native_banner_ad_template, container, false);
// NULLSAFE_FIXME[Field Not Nullable]
mStatusText = view.findViewById(R.id.status);
// NULLSAFE_FIXME[Field Not Nullable]
mNativeAdContainer = view.findViewById(R.id.templateContainer);
// NULLSAFE_FIXME[Field Not Nullable]
mShowCodeButton = view.findViewById(R.id.showCodeButton);
// NULLSAFE_FIXME[Field Not Nullable]
mBackgroundColorSpinner = view.findViewById(R.id.backgroundColorSpinner);
// NULLSAFE_FIXME[Field Not Nullable]
mAdViewTypeSpinner = view.findViewById(R.id.adViewTypeSpinner);
ArrayAdapter backgroundColorSpinnerAdapter =
ArrayAdapter.createFromResource(
// NULLSAFE_FIXME[Parameter Not Nullable]
getActivity(), R.array.background_color_array, android.R.layout.simple_spinner_item);
backgroundColorSpinnerAdapter.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);
mBackgroundColorSpinner.setAdapter(backgroundColorSpinnerAdapter);
ArrayAdapter adViewTypeSpinnerAdapter =
ArrayAdapter.createFromResource(
// NULLSAFE_FIXME[Parameter Not Nullable]
getActivity(), R.array.ad_bannerview_type_array, android.R.layout.simple_spinner_item);
adViewTypeSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mAdViewTypeSpinner.setAdapter(adViewTypeSpinnerAdapter);
setSpinnerListeners();
setButtonListeners();
createAndLoadNativeAd();
return view;
}
protected void createAndLoadNativeAd() {
// Create a native banner ad request with a unique placement ID
// (generate your own on the Facebook app settings).
// Use different ID for each ad placement in your app.
// NULLSAFE_FIXME[Parameter Not Nullable]
mNativeBannerAd = new NativeBannerAd(getContext(), "YOUR_PLACEMENT_ID");
// Initiate a request to load an ad.
mNativeBannerAd.loadAd(mNativeBannerAd.buildLoadAdConfig().withAdListener(this).build());
mStatusText.setText(R.string.ad_loading);
}
private void reloadAdContainer() {
Activity activity = getActivity();
if (activity != null
&& mNativeBannerAd != null
&& mNativeBannerAd.isAdLoaded()
&& !mNativeBannerAd.isAdInvalidated()) {
mNativeAdContainer.removeAllViews();
// Create a NativeAdViewAttributes object and set the attributes
NativeAdViewAttributes attributes =
new NativeAdViewAttributes(activity)
.setBackgroundColor(mAdBackgroundColor)
.setTitleTextColor(mTitleColor)
.setDescriptionTextColor(mContentColor)
.setButtonBorderColor(mCtaBgColor)
.setButtonTextColor(mLinkColor)
.setButtonColor(mCtaBgColor);
// Use NativeAdView.render to generate the ad View
View adView = NativeBannerAdView.render(activity, mNativeBannerAd, mViewType, attributes);
// Add adView to the container showing Ads
mNativeAdContainer.addView(adView, 0);
mNativeAdContainer.setBackgroundColor(Color.TRANSPARENT);
mShowCodeButton.setText(R.string.show_code);
}
}
private void setSpinnerListeners() {
mBackgroundColorSpinner.setOnItemSelectedListener(
new android.widget.AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView> arg0, View view, int position, long id) {
int item = mBackgroundColorSpinner.getSelectedItemPosition();
switch (item) {
case 0:
mAdBackgroundColor = Color.WHITE;
mTitleColor = COLOR_DARK_GRAY;
mLinkColor = Color.WHITE;
mContentColor = COLOR_LIGHT_GRAY;
mCtaBgColor = COLOR_CTA_BLUE_BG;
break;
case 1:
mAdBackgroundColor = Color.BLACK;
mTitleColor = Color.WHITE;
mContentColor = Color.LTGRAY;
mLinkColor = Color.BLACK;
mCtaBgColor = Color.WHITE;
break;
}
reloadAdContainer();
}
@Override
public void onNothingSelected(AdapterView> parent) {}
});
mAdViewTypeSpinner.setOnItemSelectedListener(
new android.widget.AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView> arg0, View view, int position, long id) {
int item = mAdViewTypeSpinner.getSelectedItemPosition();
if (item == 0) {
mViewType = NativeBannerAdView.Type.HEIGHT_50;
} else if (item == 1) {
mViewType = NativeBannerAdView.Type.HEIGHT_100;
} else if (item == 2) {
mViewType = NativeBannerAdView.Type.HEIGHT_120;
}
reloadAdContainer();
}
@Override
public void onNothingSelected(AdapterView> parent) {}
});
}
private void setButtonListeners() {
mShowCodeButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mShowCodeButton.getText() == getResources().getString(R.string.show_ad)) {
reloadAdContainer();
} else {
showCodeInAdContainer();
}
}
});
}
private void showCodeInAdContainer() {
String[] lines = getResources().getStringArray(R.array.code_snippet_banner_template);
StringBuilder codeSnippet = new StringBuilder();
for (String line : lines) {
codeSnippet.append(line).append("\r\n");
}
mNativeAdContainer.removeAllViews();
// NULLSAFE_FIXME[Parameter Not Nullable]
TextView code = new TextView(getActivity());
code.setText(codeSnippet);
code.setBackgroundColor(Color.WHITE);
code.setTextColor(Color.BLACK);
mNativeAdContainer.addView(code, 0);
mShowCodeButton.setText(R.string.show_ad);
}
@Override
public void onAdLoaded(Ad ad) {
if (mNativeBannerAd == null || mNativeBannerAd != ad) {
// Race condition, load() called again before last ad was displayed
return;
}
mStatusText.setText(R.string.ad_loaded);
reloadAdContainer();
}
@Override
public void onError(Ad ad, AdError error) {
String msg = getResources().getString(R.string.ad_load_failed, error.getErrorMessage());
mStatusText.setText(msg);
}
@Override
public void onAdClicked(Ad ad) {
mStatusText.setText(R.string.ad_clicked);
}
@Override
public void onLoggingImpression(Ad ad) {
Log.d(TAG, "onLoggingImpression");
}
@Override
public void onMediaDownloaded(Ad ad) {
Log.d(TAG, "onMediaDownloaded");
}
@Override
public void onDestroy() {
mNativeBannerAd = null;
super.onDestroy();
}
}
================================================
FILE: samples/android/AdUnitsSample/src/main/java/com/facebook/samples/AdUnitsSample/fragments/RectangleFragment.java
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.AdUnitsSample.fragments;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.facebook.ads.Ad;
import com.facebook.ads.AdError;
import com.facebook.ads.AdListener;
import com.facebook.ads.AdSize;
import com.facebook.ads.AdView;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.samples.AdUnitsSample.R;
import com.facebook.samples.ads.debugsettings.DebugToast;
@Nullsafe(Nullsafe.Mode.LOCAL)
public class RectangleFragment extends Fragment implements AdListener {
private static final String TAG = RectangleFragment.class.getSimpleName();
private RelativeLayout rectangleAdContainer;
private Button refreshRectangleButton;
private TextView rectangleStatusLabel;
private @Nullable AdView rectangleAdView;
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_rectangle, container, false);
// NULLSAFE_FIXME[Field Not Nullable]
rectangleStatusLabel = (TextView) view.findViewById(R.id.rectangleStatusLabel);
// NULLSAFE_FIXME[Field Not Nullable]
rectangleAdContainer = (RelativeLayout) view.findViewById(R.id.rectangleAdContainer);
// NULLSAFE_FIXME[Field Not Nullable]
refreshRectangleButton = (Button) view.findViewById(R.id.refreshRectangleButton);
refreshRectangleButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
loadAdView();
}
});
loadAdView();
return view;
}
@Override
public void onDestroyView() {
rectangleAdContainer.removeView(rectangleAdView);
super.onDestroyView();
}
@Override
public void onDestroy() {
if (rectangleAdView != null) {
rectangleAdView.destroy();
rectangleAdView = null;
}
super.onDestroy();
}
private void loadAdView() {
if (rectangleAdView != null) {
rectangleAdView.destroy();
rectangleAdView = null;
}
// Update progress message
setLabel(getString(R.string.loading_status));
// Create a banner's ad view with a unique placement ID (generate your own on the Facebook
// app settings). Use different ID for each ad placement in your app.
// NULLSAFE_FIXME[Parameter Not Nullable]
rectangleAdView = new AdView(getActivity(), "YOUR_PLACEMENT_ID", AdSize.RECTANGLE_HEIGHT_250);
// Reposition the ad and add it to the view hierarchy.
rectangleAdContainer.addView(rectangleAdView);
// Initiate a request to load an ad.
rectangleAdView.loadAd(rectangleAdView.buildLoadAdConfig().withAdListener(this).build());
}
@Override
public void onError(Ad ad, AdError error) {
if (ad == rectangleAdView) {
setLabel("Ad failed to load: " + error.getErrorMessage());
}
}
@Override
public void onAdLoaded(Ad ad) {
if (ad == rectangleAdView) {
setLabel("");
}
}
@Override
public void onAdClicked(Ad ad) {
DebugToast.show(requireActivity(), "Ad Clicked", Toast.LENGTH_SHORT);
}
@Override
public void onLoggingImpression(Ad ad) {
Log.d(TAG, "onLoggingImpression");
}
private void setLabel(String status) {
rectangleStatusLabel.setText(status);
}
}
================================================
FILE: samples/android/AdUnitsSample/src/main/java/com/facebook/samples/AdUnitsSample/fragments/RewardedInterstitialFragment.java
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.AdUnitsSample.fragments;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.fragment.app.Fragment;
import com.facebook.ads.Ad;
import com.facebook.ads.AdError;
import com.facebook.ads.RewardData;
import com.facebook.ads.RewardedInterstitialAd;
import com.facebook.ads.S2SRewardedInterstitialAdListener;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.samples.AdUnitsSample.R;
import com.facebook.samples.ads.debugsettings.DebugToast;
import javax.annotation.Nullable;
@Nullsafe(Nullsafe.Mode.LOCAL)
public class RewardedInterstitialFragment extends Fragment
implements S2SRewardedInterstitialAdListener {
private TextView rewardedInterstitialAdStatusLabel;
private Button loadRewardedInterstitialButton;
private Button showRewardedInterstitialButton;
@Nullable private RewardedInterstitialAd rewardedInterstitialAd;
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_rewarded_interstitial, container, false);
// NULLSAFE_FIXME[Field Not Nullable]
rewardedInterstitialAdStatusLabel =
(TextView) view.findViewById(R.id.rewardedInterstitialAdStatusLabel);
// NULLSAFE_FIXME[Field Not Nullable]
loadRewardedInterstitialButton =
(Button) view.findViewById(R.id.loadRewardedInterstitialButton);
// NULLSAFE_FIXME[Field Not Nullable]
showRewardedInterstitialButton =
(Button) view.findViewById(R.id.showRewardedInterstitialButton);
loadRewardedInterstitialButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
if (rewardedInterstitialAd != null) {
rewardedInterstitialAd.destroy();
rewardedInterstitialAd = null;
}
rewardedInterstitialAd =
new RewardedInterstitialAd(
// NULLSAFE_FIXME[Parameter Not Nullable]
RewardedInterstitialFragment.this.getActivity(), "YOUR_PLACEMENT_ID");
RewardedInterstitialAd.RewardedInterstitialLoadAdConfig loadAdConfig =
rewardedInterstitialAd
.buildLoadAdConfig()
.withAdListener(RewardedInterstitialFragment.this)
.withFailOnCacheFailureEnabled(true)
.withRewardData(new RewardData("YOUR_USER_ID", "YOUR_REWARD", 10))
.build();
rewardedInterstitialAd.loadAd(loadAdConfig);
setStatusLabelText("Loading rewarded interstitial ad...");
}
});
showRewardedInterstitialButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
if (rewardedInterstitialAd == null
|| !rewardedInterstitialAd.isAdLoaded()
|| rewardedInterstitialAd.isAdInvalidated()) {
setStatusLabelText("Ad not loaded. Click load to request an ad.");
} else {
rewardedInterstitialAd.show();
setStatusLabelText("");
}
}
});
return view;
}
@Override
public void onError(Ad ad, AdError error) {
if (ad == rewardedInterstitialAd) {
setStatusLabelText("Rewarded interstitial ad failed to load: " + error.getErrorMessage());
}
}
@Override
public void onAdLoaded(Ad ad) {
if (ad == rewardedInterstitialAd) {
setStatusLabelText("Ad loaded. Click show to present!");
}
}
@Override
public void onAdClicked(Ad ad) {
showToast("Rewarded Interstitial Clicked");
}
private void setStatusLabelText(String label) {
if (rewardedInterstitialAdStatusLabel != null) {
rewardedInterstitialAdStatusLabel.setText(label);
}
}
private void showToast(String message) {
if (isAdded()) {
DebugToast.show(requireActivity(), message, Toast.LENGTH_SHORT);
}
}
@Override
public void onRewardedInterstitialCompleted() {
showToast("Rewarded Interstitial View Complete");
}
@Override
public void onLoggingImpression(Ad ad) {
showToast("Rewarded Interstitial Impression");
}
@Override
public void onRewardedInterstitialClosed() {
showToast("Rewarded Interstitial Closed");
}
@Override
public void onRewardServerFailed() {
showToast("Reward Video Server Failed");
}
@Override
public void onRewardServerSuccess() {
showToast("Reward Video Server Succeeded");
}
}
================================================
FILE: samples/android/AdUnitsSample/src/main/java/com/facebook/samples/AdUnitsSample/fragments/RewardedVideoFragment.java
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.AdUnitsSample.fragments;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.fragment.app.Fragment;
import com.facebook.ads.Ad;
import com.facebook.ads.AdError;
import com.facebook.ads.RewardData;
import com.facebook.ads.RewardedVideoAd;
import com.facebook.ads.S2SRewardedVideoAdListener;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.samples.AdUnitsSample.R;
import com.facebook.samples.ads.debugsettings.DebugToast;
import javax.annotation.Nullable;
@Nullsafe(Nullsafe.Mode.LOCAL)
public class RewardedVideoFragment extends Fragment implements S2SRewardedVideoAdListener {
private static final String TAG = "RewardedVideoFragment";
private TextView rewardedVideoAdStatusLabel;
private Button loadRewardedVideoButton;
private Button showRewardedVideoButton;
@Nullable private RewardedVideoAd rewardedVideoAd;
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_rewarded_video, container, false);
// NULLSAFE_FIXME[Field Not Nullable]
rewardedVideoAdStatusLabel = (TextView) view.findViewById(R.id.rewardedVideoAdStatusLabel);
// NULLSAFE_FIXME[Field Not Nullable]
loadRewardedVideoButton = (Button) view.findViewById(R.id.loadRewardedVideoButton);
// NULLSAFE_FIXME[Field Not Nullable]
showRewardedVideoButton = (Button) view.findViewById(R.id.showRewardedVideoButton);
loadRewardedVideoButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
if (rewardedVideoAd != null) {
rewardedVideoAd.destroy();
rewardedVideoAd = null;
}
rewardedVideoAd =
// NULLSAFE_FIXME[Parameter Not Nullable]
new RewardedVideoAd(RewardedVideoFragment.this.getActivity(), "YOUR_PLACEMENT_ID");
RewardedVideoAd.RewardedVideoLoadAdConfig loadAdConfig =
rewardedVideoAd
.buildLoadAdConfig()
.withAdListener(RewardedVideoFragment.this)
.withFailOnCacheFailureEnabled(true)
.withRewardData(new RewardData("YOUR_USER_ID", "YOUR_REWARD", 10))
.build();
rewardedVideoAd.loadAd(loadAdConfig);
setStatusLabelText("Loading rewarded video ad...");
}
});
showRewardedVideoButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
if (rewardedVideoAd == null
|| !rewardedVideoAd.isAdLoaded()
|| rewardedVideoAd.isAdInvalidated()) {
setStatusLabelText("Ad not loaded. Click load to request an ad.");
} else {
setStatusLabelText("");
rewardedVideoAd.show();
}
}
});
return view;
}
@Override
public void onError(Ad ad, AdError error) {
if (ad == rewardedVideoAd) {
setStatusLabelText("Rewarded video ad failed to load: " + error.getErrorMessage());
}
}
@Override
public void onAdLoaded(Ad ad) {
if (ad == rewardedVideoAd) {
setStatusLabelText("Ad loaded. Click show to present!");
}
}
@Override
public void onAdClicked(Ad ad) {
showToast("Rewarded Video Clicked");
}
private void setStatusLabelText(String label) {
if (rewardedVideoAdStatusLabel != null) {
rewardedVideoAdStatusLabel.setText(label);
}
}
private void showToast(String message) {
Log.d(TAG, message);
if (isAdded()) {
DebugToast.show(requireActivity(), message, Toast.LENGTH_SHORT);
}
}
@Override
public void onRewardedVideoCompleted() {
showToast("Rewarded Video View Complete");
}
@Override
public void onLoggingImpression(Ad ad) {
showToast("Rewarded Video Impression");
}
@Override
public void onRewardedVideoClosed() {
showToast("Rewarded Video Closed");
}
@Override
public void onRewardServerFailed() {
showToast("Reward Video Server Failed");
}
@Override
public void onRewardServerSuccess() {
showToast("Reward Video Server Succeeded");
}
}
================================================
FILE: samples/android/AdUnitsSample/src/main/java/com/facebook/samples/AdUnitsSample/models/RecyclerPostItem.java
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.AdUnitsSample.models;
import com.facebook.infer.annotation.Nullsafe;
@Nullsafe(Nullsafe.Mode.LOCAL)
public class RecyclerPostItem {
// NULLSAFE_FIXME[Field Not Initialized]
private String postContent;
public RecyclerPostItem(String postContent) {
setPostContent(postContent);
}
public String getPostContent() {
return postContent;
}
public void setPostContent(String postContent) {
this.postContent = postContent;
}
}
================================================
FILE: samples/android/AdUnitsSample/src/main/java/com/facebook/samples/AdUnitsSample/thirdparty/DividerItemDecoration/DividerItemDecoration.java
================================================
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.facebook.samples.AdUnitsSample.thirdparty.DividerItemDecoration;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.view.View;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.facebook.infer.annotation.Nullsafe;
@Nullsafe(Nullsafe.Mode.LOCAL)
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
private static final int[] ATTRS = new int[] {android.R.attr.listDivider};
public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
private Drawable mDivider;
private int mOrientation;
public DividerItemDecoration(Context context, int orientation) {
final TypedArray a = context.obtainStyledAttributes(ATTRS);
// NULLSAFE_FIXME[Field Not Nullable]
mDivider = a.getDrawable(0);
a.recycle();
setOrientation(orientation);
}
public void setOrientation(int orientation) {
if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
throw new IllegalArgumentException("invalid orientation");
}
mOrientation = orientation;
}
@Override
public void onDraw(Canvas c, RecyclerView parent) {
if (mOrientation == VERTICAL_LIST) {
drawVertical(c, parent);
} else {
drawHorizontal(c, parent);
}
}
public void drawVertical(Canvas c, RecyclerView parent) {
final int left = parent.getPaddingLeft();
final int right = parent.getWidth() - parent.getPaddingRight();
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
public void drawHorizontal(Canvas c, RecyclerView parent) {
final int top = parent.getPaddingTop();
final int bottom = parent.getHeight() - parent.getPaddingBottom();
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
final int left = child.getRight() + params.rightMargin;
final int right = left + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
@Override
public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
if (mOrientation == VERTICAL_LIST) {
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
} else {
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
}
}
}
================================================
FILE: samples/android/AdUnitsSample/src/main/res/layout/activity_ad_sample.xml
================================================
================================================
FILE: samples/android/AdUnitsSample/src/main/res/layout/activity_sample_list.xml
================================================
================================================
FILE: samples/android/AdUnitsSample/src/main/res/layout/activity_splash.xml
================================================
================================================
FILE: samples/android/AdUnitsSample/src/main/res/layout/fragment_banner.xml
================================================
================================================
FILE: samples/android/AdUnitsSample/src/main/res/layout/fragment_interstitial.xml
================================================
================================================
FILE: samples/android/AdUnitsSample/src/main/res/layout/fragment_multi_load_interstitial.xml
================================================
================================================
FILE: samples/android/AdUnitsSample/src/main/res/layout/fragment_native_ad_hscroll.xml
================================================
================================================
FILE: samples/android/AdUnitsSample/src/main/res/layout/fragment_native_ad_recycler.xml
================================================
================================================
FILE: samples/android/AdUnitsSample/src/main/res/layout/fragment_native_ad_sample.xml
================================================
================================================
FILE: samples/android/AdUnitsSample/src/main/res/layout/fragment_native_ad_template.xml
================================================
================================================
FILE: samples/android/AdUnitsSample/src/main/res/layout/fragment_native_banner_ad.xml
================================================
================================================
FILE: samples/android/AdUnitsSample/src/main/res/layout/fragment_native_banner_ad_template.xml
================================================
================================================
FILE: samples/android/AdUnitsSample/src/main/res/layout/fragment_rectangle.xml
================================================
================================================
FILE: samples/android/AdUnitsSample/src/main/res/layout/fragment_rewarded_interstitial.xml
================================================
================================================
FILE: samples/android/AdUnitsSample/src/main/res/layout/fragment_rewarded_video.xml
================================================
================================================
FILE: samples/android/AdUnitsSample/src/main/res/layout/list_item_section.xml
================================================
================================================
FILE: samples/android/AdUnitsSample/src/main/res/layout/native_ad_unit.xml
================================================
================================================
FILE: samples/android/AdUnitsSample/src/main/res/layout/native_banner_ad_unit.xml
================================================
================================================
FILE: samples/android/AdUnitsSample/src/main/res/layout/recycler_post_item.xml
================================================
================================================
FILE: samples/android/AdUnitsSample/src/main/res/layout-land/fragment_rectangle.xml
================================================
================================================
FILE: samples/android/AdUnitsSample/src/main/res/menu/ad_units_sample_menu.xml
================================================
================================================
FILE: samples/android/AdUnitsSample/src/main/res/values/layouts.xml
================================================
- @layout/activity_ad_sample
false
================================================
FILE: samples/android/AdUnitsSample/src/main/res/values/strings.xml
================================================
Copyright © Meta Platforms, Inc. and affiliates. All rights reserved.
Ad Units Sample
Select an option
Debug Settings
Requesting an ad…
Load Interstitial
Refresh Now
Show!
Destroy Ad
Load Rewarded Video
Load Rewarded Interstitial
Enable Rewarded Interstitial
Load Native Ad
Check out more Native Ads examples in
hScroll
Template
RecyclerView
Ad icon
Ad image
Sponsored
Reload ads
Loading an ad…
Ad loaded
Ad failed to load: %s
Ad clicked
Style
Height
Show Code
- protected void onCreate(Bundle savedInstanceState) {
- \t…
- \tnativeAdContainer = (LinearLayout) findViewById(R.id.nativeAdContainer);
- \tnativeAd = new NativeAd(NativeTemplateActivity.this, "YOUR_PLACEMENT_ID");
- \tnativeAd.setAdListener(NativeTemplateActivity.this);
- \tnativeAd.loadAd();
- \t…
- }
-
- public void onAdLoaded(Ad ad) {
- \t…
- \tNativeAdViewAttributes adViewAttributes = new NativeAdViewAttributes();
- \tadViewAttributes.setBackgroundColor(adBackgroundColor);
- \tadViewAttributes.setTitleTextColor(adTitleColor);
- \t…
- \tView adView = NativeAdView.render(this, nativeAd, adViewAttributes);
- \tnativeAdContainer.addView(adView, 0);
- \t…
- }
- protected void onCreate(Bundle savedInstanceState) {
- \t…
- \tnativeAdContainer = (LinearLayout) findViewById(R.id.nativeAdContainer);
- \tnativeBannerAd = new NativeBannerAd(getContext(), "YOUR_PLACEMENT_ID");
- \tnativeBannerAd.setAdListener(this);
- \tnativeBannerAd.loadAd();
- \t…
- }
-
- public void onAdLoaded(Ad ad) {
- \t…
- \tNativeAdViewAttributes adViewAttributes = new NativeAdViewAttributes();
- \tadViewAttributes.setBackgroundColor(adBackgroundColor);
- \tadViewAttributes.setTitleTextColor(adTitleColor);
- \t…
- \tNativeBannerAdView.Type viewType = NativeBannerAdView.Type.HEIGHT_100;
- \tView adView = NativeBannerAdView.render(this, nativeBannerAd, viewType, adViewAttributes);
- \tnativeAdContainer.addView(adView, 0);
- \t…
- }
- White
- Black
- 50 DP
- 100 DP
- 120 DP
================================================
FILE: samples/android/AdUnitsSample/src/main/res/values-large/layout.xml
================================================
- @layout/activity_ad_sample
true
================================================
FILE: samples/android/AdUnitsSample/src/main/res/values-sw600dp/layout.xml
================================================
- @layout/activity_ad_sample
true
================================================
FILE: samples/android/AdUnitsSample/src/main/res/xml/locales_config.xml
================================================
================================================
FILE: samples/android/AdUnitsSample/src/main/res/xml/network_security_config.xml
================================================
127.0.0.1
facebook.com
================================================
FILE: samples/android/KotlinAdUnitsSample/.gitignore
================================================
/build
================================================
FILE: samples/android/KotlinAdUnitsSample/KotlinAdUnitsSample/.gitignore
================================================
/build
================================================
FILE: samples/android/KotlinAdUnitsSample/LICENSE
================================================
Copyright (c) Meta Platforms, Inc. and affiliates.
All rights reserved.
You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
copy, modify, and distribute this software in source code or binary form for use
in connection with the web services and APIs provided by Facebook.
As with any software that integrates with the Facebook platform, your use of
this software is subject to the Facebook Platform Policy
[http://developers.facebook.com/policy/]. This copyright notice shall be
included in all copies or substantial portions of the software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: samples/android/KotlinAdUnitsSample/build.gradle
================================================
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
implementation(name: 'AudienceNetwork', ext: 'aar')
implementation(name: 'DebugSettings', ext: 'aar')
implementation "androidx.legacy:legacy-support-v4:$project.ANDROIDX_VERSION"
implementation "androidx.recyclerview:recyclerview:$project.ANDROIDX_VERSION"
implementation "androidx.appcompat:appcompat:$project.ANDROIDX_VERSION"
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation "com.google.android.gms:play-services-basement:$project.ANDROID_GOOGLE_PLAY_SERVICES_VERSION"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$project.KOTLIN_VERSION"
}
android {
compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION)
buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION
useLibrary 'org.apache.http.legacy'
defaultConfig {
applicationId 'com.facebook.samples.AdUnitsSample'
minSdkVersion Integer.parseInt(project.ANDROID_BUILD_MIN_SDK_VERSION)
targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
versionCode 1
versionName '1.0'
rootProject.ext.variantRelease = false
}
lintOptions {
abortOnError false
}
buildFeatures {
viewBinding true
}
}
================================================
FILE: samples/android/KotlinAdUnitsSample/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/AndroidManifest.xml
================================================
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/java/com/facebook/samples/adunitssamplekotlin/AdUnitsSampleActivity.kt
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.adunitssamplekotlin
import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import com.facebook.samples.ads.debugsettings.DebugSettingsActivity
import com.facebook.samples.adunitssamplekotlin.fragments.*
class AdUnitsSampleActivity : AppCompatActivity() {
companion object {
val TAG: String = AdUnitsSampleActivity::class.java.simpleName
const val SAMPLE_TYPE: String = "SAMPLE_TYPE"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_ad_sample)
if (savedInstanceState != null) {
return
}
val sampleType = intent.getStringExtra(SAMPLE_TYPE)
if (sampleType != null) {
val type: AdUnitsSampleType? = AdUnitsSampleType.getSampleTypeFromName(sampleType)
if (type != null) {
val fragment: Fragment? =
when (type) {
AdUnitsSampleType.BANNER -> BannerFragment()
AdUnitsSampleType.INTERSTITIAL -> InterstitialFragment()
AdUnitsSampleType.RECTANGLE -> RectangleFragment()
AdUnitsSampleType.REWARDED_VIDEO -> RewardedVideoFragment()
AdUnitsSampleType.REWARDED_INTERSTITIAL -> RewardedInterstitialFragment()
AdUnitsSampleType.NATIVE -> NativeAdSampleFragment()
AdUnitsSampleType.NATIVE_BANNER -> NativeBannerAdFragment()
AdUnitsSampleType.RECYCLERVIEW -> NativeAdRecyclerFragment()
AdUnitsSampleType.HSCROLL -> NativeAdHScrollFragment()
AdUnitsSampleType.TEMPLATE -> NativeAdTemplateFragment()
AdUnitsSampleType.BANNER_TEMPLATE -> NativeBannerAdTemplateFragment()
}
if (fragment != null) {
fragment.setRetainInstance(true)
title = type.sampleType
supportFragmentManager.beginTransaction().add(R.id.fragment_container, fragment).commit()
}
}
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
val inflater = menuInflater
inflater.inflate(R.menu.ad_units_sample_menu, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val i = item.itemId
if (i == R.id.debug_settings) {
startActivity(Intent(applicationContext, DebugSettingsActivity::class.java))
return true
}
return super.onOptionsItemSelected(item)
}
}
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/java/com/facebook/samples/adunitssamplekotlin/AdUnitsSampleApplication.kt
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.adunitssamplekotlin
import android.app.Application
import android.os.StrictMode
import com.facebook.samples.ads.debugsettings.DebugSettings
import com.facebook.samples.adunitssamplekotlin.BuildConfig.DEBUG
class AdUnitsSampleApplication : Application() {
override fun onCreate() {
super.onCreate()
DebugSettings.initialize(this)
AudienceNetworkInitializeHelper.initialize(this)
if (DEBUG) {
StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build())
StrictMode.setVmPolicy(StrictMode.VmPolicy.Builder().detectAll().penaltyLog().build())
}
}
}
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/java/com/facebook/samples/adunitssamplekotlin/AdUnitsSampleType.kt
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.adunitssamplekotlin
enum class AdUnitsSampleType(val sampleType: String) {
BANNER("Banner"),
RECTANGLE("Rectangle"),
INTERSTITIAL("Interstitial"),
REWARDED_VIDEO("Rewarded Video"),
REWARDED_INTERSTITIAL("Rewarded Interstitial"),
NATIVE("Native Ad"),
NATIVE_BANNER("Native Banner Ad"),
RECYCLERVIEW("Native Ad in RecyclerView"),
HSCROLL("Native Ad in H-Scroll"),
TEMPLATE("Native Ad Template"),
BANNER_TEMPLATE("Native Banner Ad Template");
companion object {
fun getSampleTypeFromName(name: String): AdUnitsSampleType? {
for (type in values()) {
if (type.sampleType.contentEquals(name)) {
return type
}
}
return null
}
}
}
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/java/com/facebook/samples/adunitssamplekotlin/AudienceNetworkInitializeHelper.kt
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.adunitssamplekotlin
import android.content.Context
import android.util.Log
import com.facebook.ads.AdSettings
import com.facebook.ads.AudienceNetworkAds
import com.facebook.samples.adunitssamplekotlin.BuildConfig.DEBUG
/** Sample class that shows how to call initialize() method of Audience Network SDK. */
class AudienceNetworkInitializeHelper : AudienceNetworkAds.InitListener {
override fun onInitialized(result: AudienceNetworkAds.InitResult) {
Log.d(AudienceNetworkAds.TAG, result.message)
}
companion object {
/**
* It's recommended to call this method from Application.onCreate(). Otherwise you can call it
* from all Activity.onCreate() methods for Activities that contain ads.
*
* @param context Application or Activity.
*/
internal fun initialize(context: Context) {
if (!AudienceNetworkAds.isInitialized(context)) {
if (DEBUG) {
AdSettings.turnOnSDKDebugger(context)
}
AudienceNetworkAds.buildInitSettings(context)
.withInitListener(AudienceNetworkInitializeHelper())
.initialize()
}
}
}
}
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/java/com/facebook/samples/adunitssamplekotlin/SampleListActivity.kt
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.adunitssamplekotlin
import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import com.facebook.samples.ads.debugsettings.DebugSettingsActivity
import com.facebook.samples.adunitssamplekotlin.fragments.SampleListFragment
class SampleListActivity : AppCompatActivity() {
companion object {
val TAG = SampleListActivity::class.java.simpleName
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_sample_list)
supportFragmentManager
.beginTransaction()
.add(R.id.list_fragment_container, SampleListFragment())
.commit()
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.ad_units_sample_menu, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.debug_settings) {
// Start debug settings
startActivity(Intent(this, DebugSettingsActivity::class.java))
return true
}
return super.onOptionsItemSelected(item)
}
}
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/java/com/facebook/samples/adunitssamplekotlin/SplashActivity.kt
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.adunitssamplekotlin
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.Window
import android.view.WindowManager
class SplashActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// If you call AudienceNetworkAds.buildInitSettings(Context).initialize()
// in Application.onCreate() this call is not really necessary.
// Otherwise call initialize() onCreate() of all Activities that contain ads or
// from onCreate() of your Splash Activity.
AudienceNetworkInitializeHelper.initialize(this)
// Hide title and nav bar, must be done before setContentView.
requestWindowFeature(Window.FEATURE_NO_TITLE)
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN,
)
setContentView(R.layout.activity_splash)
val handler = Handler(Looper.getMainLooper())
handler.postDelayed(
{
val intent = Intent(this@SplashActivity, SampleListActivity::class.java)
startActivity(intent)
},
SPLASH_TIME.toLong(),
)
}
companion object {
private const val SPLASH_TIME = 2000
}
}
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/java/com/facebook/samples/adunitssamplekotlin/adapters/NativeAdRecyclerAdapter.kt
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.adunitssamplekotlin.adapters
import android.app.Activity
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.LinearLayout
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.facebook.ads.*
import com.facebook.samples.adunitssamplekotlin.R
import com.facebook.samples.adunitssamplekotlin.models.RecyclerPostItem
import java.util.ArrayList
class NativeAdRecyclerAdapter(
private val activity: Activity,
private val postItems: List,
private val nativeAdsManager: NativeAdsManager,
) : RecyclerView.Adapter() {
private val adItems: MutableList
init {
adItems = ArrayList()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return if (viewType == AD_TYPE) {
val inflatedView =
LayoutInflater.from(parent.context).inflate(R.layout.native_ad_unit, parent, false)
as NativeAdLayout
AdHolder(inflatedView)
} else {
val inflatedView =
LayoutInflater.from(parent.context).inflate(R.layout.recycler_post_item, parent, false)
PostHolder(inflatedView)
}
}
override fun getItemViewType(position: Int): Int {
return if (position % AD_DISPLAY_FREQUENCY == 0) AD_TYPE else POST_TYPE
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder.itemViewType == AD_TYPE) {
val ad: NativeAd?
if (adItems.size > position / AD_DISPLAY_FREQUENCY) {
ad = adItems[position / AD_DISPLAY_FREQUENCY]
} else {
ad = nativeAdsManager.nextNativeAd()
if (ad != null && !ad.isAdInvalidated) {
adItems.add(ad)
} else {
Log.w(NativeAdRecyclerAdapter::class.java.simpleName, "Ad is invalidated!")
}
}
val adHolder = holder as AdHolder
adHolder.adChoicesContainer.removeAllViews()
ad?.let { nonNullAd ->
adHolder.tvAdTitle.text = nonNullAd.advertiserName
adHolder.tvAdBody.text = nonNullAd.adBodyText
adHolder.tvAdSocialContext.text = nonNullAd.adSocialContext
adHolder.tvAdSponsoredLabel.setText(R.string.sponsored)
adHolder.btnAdCallToAction.text = nonNullAd.adCallToAction
adHolder.btnAdCallToAction.visibility =
if (nonNullAd.hasCallToAction()) View.VISIBLE else View.INVISIBLE
val adOptionsView = AdOptionsView(activity, nonNullAd, adHolder.nativeAdLayout)
adHolder.adChoicesContainer.addView(adOptionsView, 0)
val clickableViews = ArrayList()
clickableViews.add(adHolder.ivAdIcon)
clickableViews.add(adHolder.mvAdMedia)
clickableViews.add(adHolder.btnAdCallToAction)
nonNullAd.registerViewForInteraction(
adHolder.nativeAdLayout,
adHolder.mvAdMedia,
adHolder.ivAdIcon,
clickableViews,
)
}
} else {
val postHolder = holder as PostHolder
// Calculate where the next postItem index is by subtracting ads we've shown.
val index = position - position / AD_DISPLAY_FREQUENCY - 1
val postItem = postItems[index]
postHolder.tvPostContent.text = postItem.postContent
}
}
override fun getItemCount(): Int {
return postItems.size + adItems.size
}
private class PostHolder internal constructor(view: View) : RecyclerView.ViewHolder(view) {
internal var tvPostContent: TextView = view.findViewById(R.id.tvPostContent)
}
private class AdHolder internal constructor(internal var nativeAdLayout: NativeAdLayout) :
RecyclerView.ViewHolder(nativeAdLayout) {
internal var mvAdMedia: MediaView = nativeAdLayout.findViewById(R.id.native_ad_media)
internal var ivAdIcon: MediaView = nativeAdLayout.findViewById(R.id.native_ad_icon)
internal var tvAdTitle: TextView = nativeAdLayout.findViewById(R.id.native_ad_title)
internal var tvAdBody: TextView = nativeAdLayout.findViewById(R.id.native_ad_body)
internal var tvAdSocialContext: TextView =
nativeAdLayout.findViewById(R.id.native_ad_social_context)
internal var tvAdSponsoredLabel: TextView =
nativeAdLayout.findViewById(R.id.native_ad_sponsored_label)
internal var btnAdCallToAction: Button =
nativeAdLayout.findViewById(R.id.native_ad_call_to_action)
internal var adChoicesContainer: LinearLayout =
nativeAdLayout.findViewById(R.id.ad_choices_container)
}
companion object {
private const val AD_DISPLAY_FREQUENCY = 5
private const val POST_TYPE = 0
private const val AD_TYPE = 1
}
}
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/java/com/facebook/samples/adunitssamplekotlin/adapters/SampleAdapter.kt
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.adunitssamplekotlin.adapters
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.TextView
import com.facebook.samples.adunitssamplekotlin.AdUnitsSampleType
import com.facebook.samples.adunitssamplekotlin.R
class SampleAdapter(context: Context, resource: Int) :
ArrayAdapter(context, resource) {
class Item(val title: String, val isSection: Boolean = false)
private val inflater: LayoutInflater = LayoutInflater.from(this.context)
init {
add(Item("Basic Samples", true))
add(Item(AdUnitsSampleType.BANNER.sampleType))
add(Item(AdUnitsSampleType.RECTANGLE.sampleType))
add(Item(AdUnitsSampleType.INTERSTITIAL.sampleType))
add(Item(AdUnitsSampleType.REWARDED_VIDEO.sampleType))
add(Item(AdUnitsSampleType.REWARDED_INTERSTITIAL.sampleType))
add(Item("Native Ad Samples", true))
add(Item(AdUnitsSampleType.NATIVE.sampleType))
add(Item(AdUnitsSampleType.NATIVE_BANNER.sampleType))
add(Item(AdUnitsSampleType.RECYCLERVIEW.sampleType))
add(Item(AdUnitsSampleType.HSCROLL.sampleType))
add(Item(AdUnitsSampleType.TEMPLATE.sampleType))
add(Item(AdUnitsSampleType.BANNER_TEMPLATE.sampleType))
}
constructor(context: Context) : this(context, 0)
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val v: View
val item = getItem(position)
if (item.isSection) {
v = inflater.inflate(R.layout.list_item_section, parent, false)
v.findViewById(R.id.list_item_title).text = item.title
} else {
v = inflater.inflate(android.R.layout.simple_list_item_1, parent, false)
v.findViewById(android.R.id.text1).text = item.title
}
return v
}
override fun getItem(position: Int): Item {
return checkNotNull(super.getItem(position)) {
"Only add non-null SampleAdapter.Item to the adapter"
}
}
}
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/java/com/facebook/samples/adunitssamplekotlin/fragments/BannerFragment.kt
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.adunitssamplekotlin.fragments
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.RelativeLayout
import android.widget.TextView
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.facebook.ads.*
import com.facebook.samples.adunitssamplekotlin.R
class BannerFragment : Fragment(), AdListener {
companion object {
val TAG = BannerFragment::class.java.simpleName
}
private var bannerAdView: AdView? = null
private var bannerStatusLabel: TextView? = null
private var bannerAdContainer: RelativeLayout? = null
private var refreshBannerButton: Button? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View? {
val view = inflater.inflate(R.layout.fragment_banner, container, false)
bannerStatusLabel = view.findViewById(R.id.bannerStatusLabel)
bannerAdContainer = view.findViewById(R.id.bannerAdContainer)
refreshBannerButton = view.findViewById(R.id.refreshBannerButton)
refreshBannerButton?.setOnClickListener { loadAdView() }
loadAdView()
return view
}
override fun onError(ad: Ad?, error: AdError?) {
if (ad == bannerAdView) {
Log.e(TAG, "Banner failed to load: " + error?.errorMessage)
}
}
override fun onAdLoaded(ad: Ad?) {
if (ad == bannerAdView) {
setLabel("")
}
}
override fun onAdClicked(ad: Ad?) {
Toast.makeText(this.activity, "Ad clicked!", Toast.LENGTH_SHORT).show()
}
override fun onLoggingImpression(ad: Ad?) {
Log.d(TAG, "onLoggingImpression")
}
private fun setLabel(status: String) {
bannerStatusLabel?.text = status
}
private fun loadAdView() {
bannerAdView?.destroy()
bannerAdView = null
setLabel(getString(R.string.loading_status))
bannerAdView = AdView(this.activity, "YOUR_PLACEMENT_ID", AdSize.BANNER_HEIGHT_50)
bannerAdView?.let { nonNullBannerAdView ->
bannerAdContainer?.addView(nonNullBannerAdView)
nonNullBannerAdView.loadAd(
nonNullBannerAdView.buildLoadAdConfig().withAdListener(this).build()
)
}
}
}
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/java/com/facebook/samples/adunitssamplekotlin/fragments/InterstitialFragment.kt
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.adunitssamplekotlin.fragments
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.facebook.ads.*
import com.facebook.samples.adunitssamplekotlin.R
import java.util.*
class InterstitialFragment : Fragment(), InterstitialAdListener {
companion object {
val TAG = InterstitialFragment::class.java.simpleName
}
private var interstitialAd: InterstitialAd? = null
private var interstitialAdStatusLabel: TextView? = null
private var loadInterstitialButton: Button? = null
private var showInterstitialButton: Button? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View? {
val view = inflater.inflate(R.layout.fragment_interstitial, container, false)
interstitialAdStatusLabel = view?.findViewById(R.id.interstitialAdStatusLabel)
loadInterstitialButton = view?.findViewById(R.id.loadInterstitialButton)
showInterstitialButton = view?.findViewById(R.id.showInterstitialButton)
loadInterstitialButton?.setOnClickListener {
if (interstitialAd != null) {
interstitialAd?.destroy()
interstitialAd = null
}
setLabel("Loading interstitial ad...")
interstitialAd = InterstitialAd(this.activity, "YOUR_PLACEMENT_ID")
interstitialAd?.loadAd(
interstitialAd!!
.buildLoadAdConfig()
.withAdListener(this)
.withCacheFlags(EnumSet.of(CacheFlag.VIDEO))
.build()
)
}
showInterstitialButton?.setOnClickListener {
if (interstitialAd == null || !interstitialAd!!.isAdLoaded) {
setLabel("Ad not loaded. Click load to request an ad.")
} else {
interstitialAd?.show()
setLabel("")
}
}
return view
}
override fun onDestroy() {
interstitialAd?.destroy()
interstitialAd = null
super.onDestroy()
}
override fun onError(ad: Ad, error: AdError) {
if (ad === interstitialAd) {
setLabel("Interstitial ad failed to load: " + error.errorMessage)
}
}
override fun onAdLoaded(ad: Ad) {
if (ad === interstitialAd) {
setLabel("Ad loaded. Click show to present!")
}
}
override fun onInterstitialDisplayed(ad: Ad) {
if (isAdded) {
Toast.makeText(activity, "Interstitial Displayed", Toast.LENGTH_SHORT).show()
}
}
override fun onInterstitialDismissed(ad: Ad) {
if (isAdded) {
Toast.makeText(activity, "Interstitial Dismissed", Toast.LENGTH_SHORT).show()
}
// Cleanup.
interstitialAd?.destroy()
interstitialAd = null
}
override fun onAdClicked(ad: Ad) {
if (isAdded) {
Toast.makeText(activity, "Interstitial Clicked", Toast.LENGTH_SHORT).show()
}
}
override fun onLoggingImpression(ad: Ad) {
Log.d(TAG, "onLoggingImpression")
}
private fun setLabel(label: String) {
interstitialAdStatusLabel?.text = label
}
}
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/java/com/facebook/samples/adunitssamplekotlin/fragments/NativeAdHScrollFragment.kt
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.adunitssamplekotlin.fragments
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.LinearLayout
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.facebook.ads.AdError
import com.facebook.ads.NativeAdBase
import com.facebook.ads.NativeAdScrollView
import com.facebook.ads.NativeAdsManager
import com.facebook.samples.adunitssamplekotlin.R
class NativeAdHScrollFragment : Fragment(), NativeAdsManager.Listener {
private var manager: NativeAdsManager? = null
private var scrollView: NativeAdScrollView? = null
private var scrollViewContainer: LinearLayout? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_native_ad_hscroll, container, false)
manager = NativeAdsManager(activity, "YOUR_PLACEMENT_ID", 5)
manager!!.setListener(this)
manager!!.loadAds(NativeAdBase.MediaCacheFlag.ALL)
val reloadButton = view.findViewById(R.id.reload_hscroll) as Button
reloadButton.setOnClickListener { manager!!.loadAds() }
scrollViewContainer = view.findViewById(R.id.hscroll_container)
return view
}
override fun onAdsLoaded() {
if (activity == null) {
return
}
Toast.makeText(activity, "Ads loaded", Toast.LENGTH_SHORT).show()
if (scrollView != null) {
scrollViewContainer?.removeView(scrollView)
}
scrollView = NativeAdScrollView(activity, manager, NATIVE_AD_VIEW_HEIGHT_DP)
scrollViewContainer?.addView(scrollView)
}
override fun onAdError(error: AdError) {
if (activity != null) {
Toast.makeText(activity, "Ad error: " + error.errorMessage, Toast.LENGTH_SHORT).show()
}
}
companion object {
private const val NATIVE_AD_VIEW_HEIGHT_DP = 300
}
}
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/java/com/facebook/samples/adunitssamplekotlin/fragments/NativeAdRecyclerFragment.kt
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.adunitssamplekotlin.fragments
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.facebook.ads.AdError
import com.facebook.ads.NativeAdsManager
import com.facebook.samples.adunitssamplekotlin.R
import com.facebook.samples.adunitssamplekotlin.adapters.NativeAdRecyclerAdapter
import com.facebook.samples.adunitssamplekotlin.models.RecyclerPostItem
import java.util.ArrayList
class NativeAdRecyclerFragment : Fragment(), NativeAdsManager.Listener {
private var postItemList: ArrayList? = null
private var nativeAdsManager: NativeAdsManager? = null
private var recyclerView: RecyclerView? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View? {
// Create some dummy post items
postItemList = ArrayList()
for (i in 1..100) {
postItemList!!.add(RecyclerPostItem("RecyclerView Item #$i"))
}
val placementId = "YOUR_PLACEMENT_ID"
nativeAdsManager = NativeAdsManager(activity, placementId, 5)
nativeAdsManager!!.loadAds()
nativeAdsManager!!.setListener(this)
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_native_ad_recycler, container, false)
recyclerView = view.findViewById(R.id.recyclerView)
return view
}
override fun onAdsLoaded() {
if (activity == null) {
return
}
recyclerView!!.layoutManager = LinearLayoutManager(activity)
val itemDecoration = DividerItemDecoration(activity, DividerItemDecoration.VERTICAL)
recyclerView!!.addItemDecoration(itemDecoration)
val adapter = NativeAdRecyclerAdapter(activity!!, postItemList!!, nativeAdsManager!!)
recyclerView!!.adapter = adapter
}
override fun onAdError(error: AdError) = Unit
}
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/java/com/facebook/samples/adunitssamplekotlin/fragments/NativeAdSampleFragment.kt
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.adunitssamplekotlin.fragments
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.facebook.ads.*
import com.facebook.samples.adunitssamplekotlin.R
import java.util.ArrayList
class NativeAdSampleFragment : Fragment(), NativeAdListener {
private var nativeAdStatus: TextView? = null
private var adChoicesContainer: LinearLayout? = null
private var nativeAdLayout: NativeAdLayout? = null
private var nativeAd: NativeAd? = null
private var adOptionsView: AdOptionsView? = null
private var nativeAdMedia: MediaView? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View? {
val view = inflater.inflate(R.layout.fragment_native_ad_sample, container, false)
nativeAdLayout = view.findViewById(R.id.native_ad_container)
nativeAdStatus = view.findViewById(R.id.native_ad_status)
adChoicesContainer = view.findViewById(R.id.ad_choices_container)
val showNativeAdButton = view.findViewById(R.id.load_native_ad_button)
showNativeAdButton.setOnClickListener {
nativeAdStatus?.setText(R.string.loading_status)
// Create a native ad request with a unique placement ID (generate your own on the
// Facebook app settings). Use different ID for each ad placement in your app.
nativeAd = NativeAd(activity, "YOUR_PLACEMENT_ID")
// When testing on a device, add its hashed ID to force test ads.
// The hash ID is printed to log cat when running on a device and loading an ad.
// AdSettings.addTestDevice("THE HASHED ID AS PRINTED TO LOG CAT");
// Initiate a request to load an ad.
nativeAd?.loadAd(
nativeAd!!
.buildLoadAdConfig()
// Set a listener to get notified when the ad was loaded.
.withAdListener(this@NativeAdSampleFragment)
.build()
)
}
// if we already have loaded ad, render it
nativeAd?.let { onAdLoaded(it) }
return view
}
override fun onDestroyView() {
adChoicesContainer = null
nativeAdLayout = null
adOptionsView = null
nativeAdStatus = null
super.onDestroyView()
}
override fun onError(ad: Ad, error: AdError) {
nativeAdStatus?.text = "Ad failed to load: " + error.errorMessage
}
override fun onAdClicked(ad: Ad) {
Toast.makeText(activity, "Ad Clicked", Toast.LENGTH_SHORT).show()
}
override fun onLoggingImpression(ad: Ad) {
Log.d(TAG, "onLoggingImpression")
}
override fun onMediaDownloaded(ad: Ad) {
if (nativeAd === ad) {
Log.d(TAG, "onMediaDownloaded")
}
}
override fun onAdLoaded(ad: Ad) {
if (nativeAd == null || nativeAd !== ad) {
// Race condition, load() called again before last ad was displayed
return
}
if (nativeAdLayout == null) {
return
}
// Unregister last ad
nativeAd!!.unregisterView()
nativeAdStatus?.text = ""
if (adChoicesContainer != null) {
adOptionsView = AdOptionsView(activity, nativeAd, nativeAdLayout)
adChoicesContainer?.removeAllViews()
adChoicesContainer?.addView(adOptionsView, 0)
}
inflateAd(nativeAd!!, nativeAdLayout!!)
// Registering a touch listener to log which ad component receives the touch event.
// We always return false from onTouch so that we don't swallow the touch event (which
// would prevent click events from reaching the NativeAd control).
// The touch listener could be used to do animations.
nativeAd!!.setOnTouchListener { view, event ->
if (event.action == MotionEvent.ACTION_DOWN) {
when (view.id) {
R.id.native_ad_call_to_action -> Log.d(TAG, "Call to action button clicked")
R.id.native_ad_media -> Log.d(TAG, "Main image clicked")
else -> Log.d(TAG, "Other ad component clicked")
}
}
false
}
}
private fun inflateAd(nativeAd: NativeAd, adView: View) {
// Create native UI using the ad metadata.
val nativeAdIcon = adView.findViewById(R.id.native_ad_icon)
val nativeAdTitle = adView.findViewById(R.id.native_ad_title)
val nativeAdBody = adView.findViewById(R.id.native_ad_body)
val sponsoredLabel = adView.findViewById(R.id.native_ad_sponsored_label)
val nativeAdSocialContext = adView.findViewById(R.id.native_ad_social_context)
val nativeAdCallToAction = adView.findViewById(R.id.native_ad_call_to_action)
nativeAdMedia = adView.findViewById(R.id.native_ad_media)
nativeAdMedia?.setListener(mediaViewListener)
// Setting the Text
nativeAdSocialContext.text = nativeAd.adSocialContext
nativeAdCallToAction.text = nativeAd.adCallToAction
nativeAdCallToAction.visibility =
if (nativeAd.hasCallToAction()) View.VISIBLE else View.INVISIBLE
nativeAdTitle.text = nativeAd.advertiserName
nativeAdBody.text = nativeAd.adBodyText
sponsoredLabel.setText(R.string.sponsored)
// You can use the following to specify the clickable areas.
val clickableViews = ArrayList()
clickableViews.add(nativeAdIcon)
clickableViews.add(nativeAdMedia!!)
clickableViews.add(nativeAdCallToAction)
nativeAd.registerViewForInteraction(nativeAdLayout, nativeAdMedia, nativeAdIcon, clickableViews)
// Optional: tag views
NativeAdBase.NativeComponentTag.tagView(nativeAdIcon, NativeAdBase.NativeComponentTag.AD_ICON)
NativeAdBase.NativeComponentTag.tagView(nativeAdTitle, NativeAdBase.NativeComponentTag.AD_TITLE)
NativeAdBase.NativeComponentTag.tagView(nativeAdBody, NativeAdBase.NativeComponentTag.AD_BODY)
NativeAdBase.NativeComponentTag.tagView(
nativeAdSocialContext,
NativeAdBase.NativeComponentTag.AD_SOCIAL_CONTEXT,
)
NativeAdBase.NativeComponentTag.tagView(
nativeAdCallToAction,
NativeAdBase.NativeComponentTag.AD_CALL_TO_ACTION,
)
}
override fun onDestroy() {
nativeAdMedia?.destroy()
nativeAd?.unregisterView()
nativeAd?.destroy()
super.onDestroy()
}
companion object {
private val TAG = NativeAdSampleFragment::class.java.simpleName
private val mediaViewListener: MediaViewListener
get() =
object : MediaViewListener {
override fun onVolumeChange(mediaView: MediaView, volume: Float) {
Log.i(TAG, "MediaViewEvent: Volume $volume")
}
override fun onPause(mediaView: MediaView) {
Log.i(TAG, "MediaViewEvent: Paused")
}
override fun onPlay(mediaView: MediaView) {
Log.i(TAG, "MediaViewEvent: Play")
}
override fun onFullscreenBackground(mediaView: MediaView) {
Log.i(TAG, "MediaViewEvent: FullscreenBackground")
}
override fun onFullscreenForeground(mediaView: MediaView) {
Log.i(TAG, "MediaViewEvent: FullscreenForeground")
}
override fun onExitFullscreen(mediaView: MediaView) {
Log.i(TAG, "MediaViewEvent: ExitFullscreen")
}
override fun onEnterFullscreen(mediaView: MediaView) {
Log.i(TAG, "MediaViewEvent: EnterFullscreen")
}
override fun onComplete(mediaView: MediaView) {
Log.i(TAG, "MediaViewEvent: Completed")
}
}
}
}
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/java/com/facebook/samples/adunitssamplekotlin/fragments/NativeAdTemplateFragment.kt
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.adunitssamplekotlin.fragments
import android.content.Context
import android.content.res.Resources
import android.graphics.Color
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.fragment.app.Fragment
import com.facebook.ads.*
import com.facebook.samples.adunitssamplekotlin.R
class NativeAdTemplateFragment : Fragment(), NativeAdListener {
private var nativeAd: NativeAd? = null
private var layoutHeightDp = DEFAULT_HEIGHT_DP
private var adBackgroundColor: Int = 0
private var titleColor: Int = 0
private var ctaTextColor: Int = 0
private var contentColor: Int = 0
private var ctaBgColor: Int = 0
private var statusText: TextView? = null
private var nativeAdContainer: ViewGroup? = null
private var backgroundColorSpinner: Spinner? = null
private var showCodeButton: Button? = null
private var reloadButton: Button? = null
private var seekBar: SeekBar? = null
private var adView: View? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View? {
val view = inflater.inflate(R.layout.fragment_native_ad_template, container, false)
statusText = view.findViewById(R.id.status)
nativeAdContainer = view.findViewById(R.id.templateContainer)
showCodeButton = view.findViewById(R.id.showCodeButton)
reloadButton = view.findViewById(R.id.reloadAdButton)
backgroundColorSpinner = view.findViewById(R.id.backgroundColorSpinner)
seekBar = view.findViewById(R.id.seekBar)
setUpLayoutBuilders(inflater.context)
setUpButtons()
createAndLoadNativeAd()
return view
}
override fun onAdLoaded(ad: Ad) {
if (nativeAd == null || nativeAd !== ad) {
// Race condition, load() called again before last ad was displayed
return
}
statusText?.setText(R.string.ad_loaded)
reloadAdContainer()
}
override fun onError(ad: Ad, error: AdError) {
val msg = resources.getString(R.string.ad_load_failed, error.errorMessage)
statusText?.text = msg
}
override fun onAdClicked(ad: Ad) {
statusText?.setText(R.string.ad_clicked)
}
override fun onLoggingImpression(ad: Ad) {
Log.d(TAG, "onLoggingImpression")
}
override fun onMediaDownloaded(ad: Ad) {
Log.d(TAG, "onMediaDownloaded")
}
override fun onDestroy() {
nativeAd = null
super.onDestroy()
}
private fun createAndLoadNativeAd() {
// Create a native ad request with a unique placement ID
// (generate your own on the Facebook app settings).
// Use different ID for each ad placement in your app.
nativeAd = NativeAd(activity, "YOUR_PLACEMENT_ID")
// Initiate a request to load an ad.
nativeAd!!.loadAd(
nativeAd!!
.buildLoadAdConfig()
// Set a listener to get notified when the ad was loaded.
.withAdListener(this)
.build()
)
statusText?.setText(R.string.ad_loading)
}
private fun reloadAdContainer() {
val activity = activity
if (activity != null && nativeAd != null && nativeAd!!.isAdLoaded) {
nativeAdContainer!!.removeAllViews()
// Create a NativeAdViewAttributes object and set the attributes
val attributes =
NativeAdViewAttributes(context)
.setBackgroundColor(adBackgroundColor)
.setTitleTextColor(titleColor)
.setDescriptionTextColor(contentColor)
.setButtonBorderColor(ctaTextColor)
.setButtonTextColor(ctaTextColor)
.setButtonColor(ctaBgColor)
// Use NativeAdView.render to generate the ad View
adView = NativeAdView.render(activity, nativeAd!!, attributes)
nativeAdContainer!!.addView(
adView,
ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0),
)
updateAdViewParams()
showCodeButton!!.setText(R.string.show_code)
}
}
private fun setUpLayoutBuilders(context: Context) {
val backgroundColorSpinnerAdapter =
ArrayAdapter.createFromResource(
context,
R.array.background_color_array,
android.R.layout.simple_spinner_item,
)
backgroundColorSpinnerAdapter.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item
)
backgroundColorSpinner!!.adapter = backgroundColorSpinnerAdapter
backgroundColorSpinner!!.onItemSelectedListener =
object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(arg0: AdapterView<*>, view: View, position: Int, id: Long) {
when (backgroundColorSpinner!!.selectedItemPosition) {
0 -> {
adBackgroundColor = Color.WHITE
titleColor = COLOR_DARK_GRAY
ctaTextColor = COLOR_CTA_BLUE_BG
contentColor = COLOR_LIGHT_GRAY
ctaBgColor = Color.WHITE
}
1 -> {
adBackgroundColor = Color.BLACK
titleColor = Color.WHITE
contentColor = Color.LTGRAY
ctaTextColor = Color.BLACK
ctaBgColor = Color.WHITE
}
}
reloadAdContainer()
}
override fun onNothingSelected(parent: AdapterView<*>) = Unit
}
seekBar!!.progress = DEFAULT_PROGRESS_DP
seekBar!!.setOnSeekBarChangeListener(
object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
layoutHeightDp = progress * ((MAX_HEIGHT_DP - MIN_HEIGHT_DP) / 100) + MIN_HEIGHT_DP
updateAdViewParams()
}
override fun onStartTrackingTouch(seekBar: SeekBar) = Unit
override fun onStopTrackingTouch(seekBar: SeekBar) = Unit
}
)
}
private fun updateAdViewParams() {
if (adView == null) {
return
}
val params = adView!!.layoutParams
params.height = (Resources.getSystem().displayMetrics.density * layoutHeightDp).toInt()
adView!!.layoutParams = params
adView!!.requestLayout()
}
private fun setUpButtons() {
showCodeButton!!.setOnClickListener {
if (showCodeButton!!.text === resources.getString(R.string.show_ad)) {
reloadAdContainer()
} else {
showCodeInAdContainer()
}
}
reloadButton!!.setOnClickListener { createAndLoadNativeAd() }
}
private fun showCodeInAdContainer() {
val lines = resources.getStringArray(R.array.code_snippet_mediumrect_template)
val codeSnippet = StringBuilder()
for (line in lines) {
codeSnippet.append(line).append("\r\n")
}
nativeAdContainer!!.removeAllViews()
val code = TextView(activity)
code.text = codeSnippet
code.setBackgroundColor(Color.WHITE)
code.setTextColor(Color.BLACK)
nativeAdContainer!!.addView(code, 0)
showCodeButton!!.setText(R.string.show_ad)
}
companion object {
private val TAG = NativeAdTemplateFragment::class.java.simpleName
private const val COLOR_LIGHT_GRAY = -0x6f6b64
private const val COLOR_DARK_GRAY = -0xb1a99b
private const val COLOR_CTA_BLUE_BG = -0xbf7f01
private const val MIN_HEIGHT_DP = 200
private const val MAX_HEIGHT_DP = 500
private const val DEFAULT_HEIGHT_DP = 350
private const val DEFAULT_PROGRESS_DP = 50
}
}
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/java/com/facebook/samples/adunitssamplekotlin/fragments/NativeBannerAdFragment.kt
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.adunitssamplekotlin.fragments
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.fragment.app.Fragment
import com.facebook.ads.*
import com.facebook.samples.adunitssamplekotlin.R
import java.util.*
class NativeBannerAdFragment : Fragment(), NativeAdListener {
private var adView: LinearLayout? = null
private var adChoicesContainer: FrameLayout? = null
private var nativeBannerAdContainer: NativeAdLayout? = null
private var nativeBannerAd: NativeBannerAd? = null
private var nativeBannerAdStatusLabel: TextView? = null
private var isAdViewAdded: Boolean = false
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View? {
val view = inflater.inflate(R.layout.fragment_native_banner_ad, container, false)
nativeBannerAdContainer = view.findViewById(R.id.native_banner_ad_container)
nativeBannerAdStatusLabel = view.findViewById(R.id.native_banner_status_label)
adView =
inflater.inflate(R.layout.native_banner_ad_unit, nativeBannerAdContainer, false)
as LinearLayout
adChoicesContainer = adView!!.findViewById(R.id.ad_choices_container)
val showNativeBannerAdButton = view.findViewById(R.id.refresh_native_banner_button)
showNativeBannerAdButton.setOnClickListener {
nativeBannerAdStatusLabel!!.text = getString(R.string.loading_status)
// Create a native ad request with a unique placement ID (generate your own on the
// Facebook app settings). Use different ID for each ad placement in your app.
nativeBannerAd = NativeBannerAd(context, "YOUR_PLACEMENT_ID")
// When testing on a device, add its hashed ID to force test ads.
// The hash ID is printed to log cat when running on a device and loading an ad.
// AdSettings.addTestDevice("THE HASHED ID AS PRINTED TO LOG CAT");
// Initiate a request to load an ad.
nativeBannerAd!!.loadAd(
nativeBannerAd!!
.buildLoadAdConfig()
// Set a listener to get notified when the ad was loaded.
.withAdListener(this)
.withMediaCacheFlag(NativeAdBase.MediaCacheFlag.ALL)
.build()
)
}
// load the Native Banner when this fragment is created
// as the Banner in BannerFragment does.
showNativeBannerAdButton.performClick()
return view
}
override fun onError(ad: Ad, error: AdError) {
nativeBannerAdStatusLabel?.text = "Ad Failed to Load: " + error.errorMessage
}
override fun onAdLoaded(ad: Ad) {
if (nativeBannerAd == null || nativeBannerAd !== ad) {
// Race condition, load() called again before last ad was displayed
return
}
if (!isAdViewAdded) {
isAdViewAdded = true
nativeBannerAdContainer!!.addView(adView)
}
// Unregister last ad
nativeBannerAd!!.unregisterView()
nativeBannerAdStatusLabel?.text = ""
// Using the AdOptionsView is optional, but your native ad unit should
// be clearly delineated from the rest of your app content. See
// https://developers.facebook.com/docs/audience-network/guidelines/native-ads#native
// for details. We recommend using the AdOptionsView.
val adOptionsView =
AdOptionsView(
activity,
nativeBannerAd,
nativeBannerAdContainer,
AdOptionsView.Orientation.HORIZONTAL,
20,
)
adChoicesContainer?.removeAllViews()
adChoicesContainer?.addView(adOptionsView)
inflateAd(nativeBannerAd!!, adView!!)
// Registering a touch listener to log which ad component receives the touch event.
// We always return false from onTouch so that we don't swallow the touch event (which
// would prevent click events from reaching the NativeAd control).
// The touch listener could be used to do animations.
nativeBannerAd!!.setOnTouchListener { view, event ->
if (event.action == MotionEvent.ACTION_DOWN) {
when (view.id) {
R.id.native_ad_call_to_action -> Log.d(TAG, "Call to action button clicked")
R.id.native_icon_view -> Log.d(TAG, "Main image clicked")
else -> Log.d(TAG, "Other ad component clicked")
}
}
false
}
}
override fun onAdClicked(ad: Ad) {
Toast.makeText(activity, "Ad Clicked", Toast.LENGTH_SHORT).show()
}
override fun onLoggingImpression(ad: Ad) {
Log.d(TAG, "onLoggingImpression")
}
override fun onMediaDownloaded(ad: Ad) {
Log.d(TAG, "onMediaDownloaded")
}
private fun inflateAd(nativeBannerAd: NativeBannerAd, adView: View) {
// Create native UI using the ad metadata.
val nativeAdTitle = adView.findViewById(R.id.native_ad_title)
val nativeAdSocialContext = adView.findViewById(R.id.native_ad_social_context)
val sponsoredLabel = adView.findViewById(R.id.native_ad_sponsored_label)
val nativeAdIconView = adView.findViewById(R.id.native_icon_view)
val nativeAdCallToAction = adView.findViewById(R.id.native_ad_call_to_action)
// Setting the Text
nativeAdCallToAction.text = nativeBannerAd.adCallToAction
nativeAdCallToAction.visibility =
if (nativeBannerAd.hasCallToAction()) View.VISIBLE else View.INVISIBLE
nativeAdTitle.text = nativeBannerAd.advertiserName
nativeAdSocialContext.text = nativeBannerAd.adSocialContext
// You can use the following to specify the clickable areas.
val clickableViews = ArrayList()
clickableViews.add(nativeAdCallToAction)
nativeBannerAd.registerViewForInteraction(
nativeBannerAdContainer,
nativeAdIconView,
clickableViews,
)
sponsoredLabel.setText(R.string.sponsored)
}
override fun onDestroy() {
if (nativeBannerAd != null) {
nativeBannerAd!!.unregisterView()
nativeBannerAd = null
}
super.onDestroy()
}
companion object {
private val TAG = NativeBannerAdFragment::class.java.simpleName
}
}
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/java/com/facebook/samples/adunitssamplekotlin/fragments/NativeBannerAdTemplateFragment.kt
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.adunitssamplekotlin.fragments
import android.graphics.Color
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.fragment.app.Fragment
import com.facebook.ads.*
import com.facebook.samples.adunitssamplekotlin.R
class NativeBannerAdTemplateFragment : Fragment(), NativeAdListener {
private var nativeBannerAd: NativeBannerAd? = null
private var viewType: NativeBannerAdView.Type = NativeBannerAdView.Type.HEIGHT_100
private var adBackgroundColor: Int = 0
private var titleColor: Int = 0
private var linkColor: Int = 0
private var contentColor: Int = 0
private var ctaBgColor: Int = 0
private var statusText: TextView? = null
private var nativeAdContainer: ViewGroup? = null
private var backgroundColorSpinner: Spinner? = null
private var adViewTypeSpinner: Spinner? = null
private var showCodeButton: Button? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View? {
val view = inflater.inflate(R.layout.fragment_native_banner_ad_template, container, false)
statusText = view.findViewById(R.id.status)
nativeAdContainer = view.findViewById(R.id.templateContainer)
showCodeButton = view.findViewById(R.id.showCodeButton)
backgroundColorSpinner = view.findViewById(R.id.backgroundColorSpinner)
adViewTypeSpinner = view.findViewById(R.id.adViewTypeSpinner)
val backgroundColorSpinnerAdapter =
ArrayAdapter.createFromResource(
inflater.context,
R.array.background_color_array,
android.R.layout.simple_spinner_item,
)
backgroundColorSpinnerAdapter.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item
)
backgroundColorSpinner!!.adapter = backgroundColorSpinnerAdapter
val adViewTypeSpinnerAdapter =
ArrayAdapter.createFromResource(
inflater.context,
R.array.ad_bannerview_type_array,
android.R.layout.simple_spinner_item,
)
adViewTypeSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
adViewTypeSpinner!!.adapter = adViewTypeSpinnerAdapter
setSpinnerListeners()
setButtonListeners()
createAndLoadNativeAd()
return view
}
private fun createAndLoadNativeAd() {
// Create a native banner ad request with a unique placement ID
// (generate your own on the Facebook app settings).
// Use different ID for each ad placement in your app.
nativeBannerAd = NativeBannerAd(context, "YOUR_PLACEMENT_ID")
// Initiate a request to load an ad.
nativeBannerAd!!.loadAd(
nativeBannerAd!!
.buildLoadAdConfig()
// Set a listener to get notified when the ad was loaded.
.withAdListener(this)
.build()
)
statusText?.setText(R.string.ad_loading)
}
private fun reloadAdContainer() {
val activity = activity
if (activity != null && nativeBannerAd != null && nativeBannerAd!!.isAdLoaded) {
nativeAdContainer!!.removeAllViews()
// Create a NativeAdViewAttributes object and set the attributes
val attributes =
NativeAdViewAttributes(context)
.setBackgroundColor(adBackgroundColor)
.setTitleTextColor(titleColor)
.setDescriptionTextColor(contentColor)
.setButtonBorderColor(ctaBgColor)
.setButtonTextColor(linkColor)
.setButtonColor(ctaBgColor)
// Use NativeAdView.render to generate the ad View
val adView = NativeBannerAdView.render(activity, nativeBannerAd!!, viewType, attributes)
// Add adView to the container showing Ads
nativeAdContainer!!.addView(adView, 0)
nativeAdContainer!!.setBackgroundColor(Color.TRANSPARENT)
showCodeButton!!.setText(R.string.show_code)
}
}
private fun setSpinnerListeners() {
backgroundColorSpinner!!.onItemSelectedListener =
object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(arg0: AdapterView<*>, view: View, position: Int, id: Long) {
when (backgroundColorSpinner!!.selectedItemPosition) {
0 -> {
adBackgroundColor = Color.WHITE
titleColor = COLOR_DARK_GRAY
linkColor = Color.WHITE
contentColor = COLOR_LIGHT_GRAY
ctaBgColor = COLOR_CTA_BLUE_BG
}
1 -> {
adBackgroundColor = Color.BLACK
titleColor = Color.WHITE
contentColor = Color.LTGRAY
linkColor = Color.BLACK
ctaBgColor = Color.WHITE
}
}
reloadAdContainer()
}
override fun onNothingSelected(parent: AdapterView<*>) = Unit
}
adViewTypeSpinner!!.onItemSelectedListener =
object : android.widget.AdapterView.OnItemSelectedListener {
override fun onItemSelected(arg0: AdapterView<*>, view: View, position: Int, id: Long) {
when (adViewTypeSpinner!!.selectedItemPosition) {
0 -> viewType = NativeBannerAdView.Type.HEIGHT_50
1 -> viewType = NativeBannerAdView.Type.HEIGHT_100
2 -> viewType = NativeBannerAdView.Type.HEIGHT_120
}
reloadAdContainer()
}
override fun onNothingSelected(parent: AdapterView<*>) = Unit
}
}
private fun setButtonListeners() {
showCodeButton!!.setOnClickListener {
if (showCodeButton!!.text === resources.getString(R.string.show_ad)) {
reloadAdContainer()
} else {
showCodeInAdContainer()
}
}
}
private fun showCodeInAdContainer() {
val lines = resources.getStringArray(R.array.code_snippet_banner_template)
val codeSnippet = StringBuilder()
for (line in lines) {
codeSnippet.append(line).append("\r\n")
}
nativeAdContainer!!.removeAllViews()
val code = TextView(activity)
code.text = codeSnippet
code.setBackgroundColor(Color.WHITE)
code.setTextColor(Color.BLACK)
nativeAdContainer!!.addView(code, 0)
showCodeButton!!.setText(R.string.show_ad)
}
override fun onAdLoaded(ad: Ad) {
if (nativeBannerAd == null || nativeBannerAd !== ad) {
// Race condition, load() called again before last ad was displayed
return
}
statusText?.setText(R.string.ad_loaded)
reloadAdContainer()
}
override fun onError(ad: Ad, error: AdError) {
val msg = resources.getString(R.string.ad_load_failed, error.errorMessage)
statusText?.text = msg
}
override fun onAdClicked(ad: Ad) {
statusText?.setText(R.string.ad_clicked)
}
override fun onLoggingImpression(ad: Ad) {
Log.d(TAG, "onLoggingImpression")
}
override fun onMediaDownloaded(ad: Ad) {
Log.d(TAG, "onMediaDownloaded")
}
override fun onDestroy() {
nativeBannerAd = null
super.onDestroy()
}
companion object {
private val TAG = NativeBannerAdTemplateFragment::class.java.simpleName
private const val COLOR_LIGHT_GRAY = -0x6f6b64
private const val COLOR_DARK_GRAY = -0xb1a99b
private const val COLOR_CTA_BLUE_BG = -0xbf7f01
}
}
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/java/com/facebook/samples/adunitssamplekotlin/fragments/RectangleFragment.kt
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.adunitssamplekotlin.fragments
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.RelativeLayout
import android.widget.TextView
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.facebook.ads.*
import com.facebook.samples.adunitssamplekotlin.R
class RectangleFragment : Fragment(), AdListener {
private var rectangleAdContainer: RelativeLayout? = null
private var refreshRectangleButton: Button? = null
private var rectangleStatusLabel: TextView? = null
private var rectangleAdView: AdView? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View? {
val view = inflater.inflate(R.layout.fragment_rectangle, container, false)
rectangleStatusLabel = view.findViewById(R.id.rectangleStatusLabel)
rectangleAdContainer = view.findViewById(R.id.rectangleAdContainer)
refreshRectangleButton = view.findViewById(R.id.refreshRectangleButton)
refreshRectangleButton?.setOnClickListener { loadAdView() }
loadAdView()
return view
}
override fun onDestroyView() {
rectangleAdContainer?.removeView(rectangleAdView)
super.onDestroyView()
}
override fun onDestroy() {
rectangleAdView?.destroy()
rectangleAdView = null
super.onDestroy()
}
private fun loadAdView() {
rectangleAdView?.destroy()
rectangleAdView = null
// Update progress message
setLabel(getString(R.string.loading_status))
// Create a banner's ad view with a unique placement ID (generate your own on the Facebook
// app settings). Use different ID for each ad placement in your app.
rectangleAdView = AdView(activity, "YOUR_PLACEMENT_ID", AdSize.RECTANGLE_HEIGHT_250)
// Reposition the ad and add it to the view hierarchy.
rectangleAdContainer?.addView(rectangleAdView)
// Initiate a request to load an ad.
rectangleAdView?.buildLoadAdConfig()?.withAdListener(this)?.build()
}
override fun onError(ad: Ad, error: AdError) {
if (ad === rectangleAdView) {
setLabel("Ad failed to load: " + error.errorMessage)
}
}
override fun onAdLoaded(ad: Ad) {
if (ad === rectangleAdView) {
setLabel("")
}
}
override fun onAdClicked(ad: Ad) {
Toast.makeText(this.activity, "Ad Clicked", Toast.LENGTH_SHORT).show()
}
override fun onLoggingImpression(ad: Ad) {
Log.d(TAG, "onLoggingImpression")
}
private fun setLabel(status: String) {
rectangleStatusLabel?.text = status
if (status.isEmpty()) {
rectangleStatusLabel?.visibility = View.GONE
} else {
rectangleStatusLabel?.visibility = View.VISIBLE
}
}
companion object {
private val TAG = RectangleFragment::class.java.simpleName
}
}
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/java/com/facebook/samples/adunitssamplekotlin/fragments/RewardedInterstitialFragment.kt
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.adunitssamplekotlin.fragments
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.facebook.ads.Ad
import com.facebook.ads.AdError
import com.facebook.ads.RewardData
import com.facebook.ads.RewardedInterstitialAd
import com.facebook.ads.S2SRewardedInterstitialAdListener
import com.facebook.samples.adunitssamplekotlin.R
class RewardedInterstitialFragment : Fragment(), S2SRewardedInterstitialAdListener {
private lateinit var rewardedInterstitialAdStatusLabel: TextView
private lateinit var loadRewardedInterstitialButton: Button
private lateinit var showRewardedInterstitialButton: Button
private var rewardedInterstitialAd: RewardedInterstitialAd? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View? {
val view = inflater.inflate(R.layout.fragment_rewarded_interstitial, container, false)
rewardedInterstitialAdStatusLabel = view.findViewById(R.id.rewardedInterstitialAdStatusLabel)
loadRewardedInterstitialButton = view.findViewById(R.id.loadRewardedInterstitialButton)
showRewardedInterstitialButton = view.findViewById(R.id.showRewardedInterstitialButton)
loadRewardedInterstitialButton.setOnClickListener {
rewardedInterstitialAd?.destroy()
rewardedInterstitialAd = null
rewardedInterstitialAd =
RewardedInterstitialAd(this@RewardedInterstitialFragment.activity, "YOUR_PLACEMENT_ID")
rewardedInterstitialAd?.let { rewardedInterstitialAd ->
setStatusLabelText("Loading rewarded interstitial ad...")
rewardedInterstitialAd.loadAd(
rewardedInterstitialAd
.buildLoadAdConfig()
.withAdListener(this)
.withFailOnCacheFailureEnabled(true)
.withRewardData(RewardData("YOUR_USER_ID", "YOUR_REWARD"))
.build()
)
}
}
showRewardedInterstitialButton.setOnClickListener {
if (rewardedInterstitialAd?.isAdLoaded == true) {
rewardedInterstitialAd?.show()
setStatusLabelText("")
} else {
setStatusLabelText("Ad not loaded. Click load to request an ad.")
}
}
return view
}
override fun onError(ad: Ad, error: AdError) {
if (ad === rewardedInterstitialAd) {
setStatusLabelText("Rewarded interstitial ad failed to load: " + error.errorMessage)
}
}
override fun onAdLoaded(ad: Ad) {
if (ad === rewardedInterstitialAd) {
setStatusLabelText("Ad loaded. Click show to present!")
}
}
override fun onAdClicked(ad: Ad) {
showToast("Rewarded Interstitial Clicked")
}
private fun setStatusLabelText(label: String) {
rewardedInterstitialAdStatusLabel.text = label
}
private fun showToast(message: String) {
if (isAdded) {
Toast.makeText(activity, message, Toast.LENGTH_SHORT).show()
}
}
override fun onRewardedInterstitialCompleted() {
showToast("Rewarded Interstitial View Complete")
}
override fun onLoggingImpression(ad: Ad) {
showToast("Rewarded Interstitial Impression")
}
override fun onRewardedInterstitialClosed() {
showToast("Rewarded Interstitial Closed")
}
override fun onRewardServerFailed() {
showToast("Rewarded Interstitial Server Failed")
}
override fun onRewardServerSuccess() {
showToast("Rewarded Interstitial Server Succeeded")
}
}
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/java/com/facebook/samples/adunitssamplekotlin/fragments/RewardedVideoFragment.kt
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.adunitssamplekotlin.fragments
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.facebook.ads.*
import com.facebook.samples.adunitssamplekotlin.R
class RewardedVideoFragment : Fragment(), S2SRewardedVideoAdListener {
private var rewardedVideoAdStatusLabel: TextView? = null
private var loadRewardedVideoButton: Button? = null
private var showRewardedVideoButton: Button? = null
private var rewardedVideoAd: RewardedVideoAd? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View? {
val view = inflater.inflate(R.layout.fragment_rewarded_video, container, false)
rewardedVideoAdStatusLabel = view.findViewById(R.id.rewardedVideoAdStatusLabel)
loadRewardedVideoButton = view.findViewById(R.id.loadRewardedVideoButton)
showRewardedVideoButton = view.findViewById(R.id.showRewardedVideoButton)
loadRewardedVideoButton?.setOnClickListener {
rewardedVideoAd?.destroy()
rewardedVideoAd = null
rewardedVideoAd = RewardedVideoAd(this@RewardedVideoFragment.activity, "YOUR_PLACEMENT_ID")
setStatusLabelText("Loading rewarded video ad...")
rewardedVideoAd?.loadAd(
rewardedVideoAd!!
.buildLoadAdConfig()
.withAdListener(this)
.withFailOnCacheFailureEnabled(true)
.withRewardData(RewardData("YOUR_USER_ID", "YOUR_REWARD"))
.build()
)
}
showRewardedVideoButton?.setOnClickListener {
if (rewardedVideoAd == null || !rewardedVideoAd!!.isAdLoaded) {
setStatusLabelText("Ad not loaded. Click load to request an ad.")
} else {
rewardedVideoAd!!.show()
setStatusLabelText("")
}
}
return view
}
override fun onError(ad: Ad, error: AdError) {
if (ad === rewardedVideoAd) {
setStatusLabelText("Rewarded video ad failed to load: " + error.errorMessage)
}
}
override fun onAdLoaded(ad: Ad) {
if (ad === rewardedVideoAd) {
setStatusLabelText("Ad loaded. Click show to present!")
}
}
override fun onAdClicked(ad: Ad) {
showToast("Rewarded Video Clicked")
}
private fun setStatusLabelText(label: String) {
rewardedVideoAdStatusLabel?.text = label
}
private fun showToast(message: String) {
if (isAdded) {
Toast.makeText(activity, message, Toast.LENGTH_SHORT).show()
}
}
override fun onRewardedVideoCompleted() {
showToast("Rewarded Video View Complete")
}
override fun onLoggingImpression(ad: Ad) {
showToast("Rewarded Video Impression")
}
override fun onRewardedVideoClosed() {
showToast("Rewarded Video Closed")
}
override fun onRewardServerFailed() {
showToast("Reward Video Server Failed")
}
override fun onRewardServerSuccess() {
showToast("Reward Video Server Succeeded")
}
}
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/java/com/facebook/samples/adunitssamplekotlin/fragments/SampleListFragment.kt
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.adunitssamplekotlin.fragments
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ListView
import androidx.fragment.app.ListFragment
import com.facebook.samples.adunitssamplekotlin.AdUnitsSampleActivity
import com.facebook.samples.adunitssamplekotlin.AdUnitsSampleType
import com.facebook.samples.adunitssamplekotlin.adapters.SampleAdapter
class SampleListFragment : ListFragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View? {
listAdapter = SampleAdapter(inflater.context)
return super.onCreateView(inflater, container, savedInstanceState)
}
override fun onListItemClick(parent: ListView?, view: View?, position: Int, id: Long) {
val item: SampleAdapter.Item = listAdapter.getItem(position) as SampleAdapter.Item
val sampleName = item.title
val type = AdUnitsSampleType.getSampleTypeFromName(sampleName)
if (type != null) {
// Start sample activity
val intent = Intent(context, AdUnitsSampleActivity::class.java)
intent.putExtra(AdUnitsSampleActivity.SAMPLE_TYPE, type.sampleType)
startActivity(intent)
}
}
}
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/java/com/facebook/samples/adunitssamplekotlin/models/RecyclerPostItem.kt
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.samples.adunitssamplekotlin.models
class RecyclerPostItem(val postContent: String)
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/res/layout/activity_ad_sample.xml
================================================
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/res/layout/activity_sample_list.xml
================================================
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/res/layout/activity_splash.xml
================================================
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/res/layout/fragment_banner.xml
================================================
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/res/layout/fragment_interstitial.xml
================================================
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/res/layout/fragment_native_ad_hscroll.xml
================================================
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/res/layout/fragment_native_ad_recycler.xml
================================================
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/res/layout/fragment_native_ad_sample.xml
================================================
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/res/layout/fragment_native_ad_template.xml
================================================
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/res/layout/fragment_native_banner_ad.xml
================================================
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/res/layout/fragment_native_banner_ad_template.xml
================================================
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/res/layout/fragment_rectangle.xml
================================================
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/res/layout/fragment_rewarded_interstitial.xml
================================================
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/res/layout/fragment_rewarded_video.xml
================================================
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/res/layout/list_item_section.xml
================================================
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/res/layout/native_ad_unit.xml
================================================
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/res/layout/native_banner_ad_unit.xml
================================================
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/res/layout/recycler_post_item.xml
================================================
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/res/menu/ad_units_sample_menu.xml
================================================
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/res/values/colors.xml
================================================
#008577
#00574B
#D81B60
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/res/values/strings.xml
================================================
Copyright © Meta Platforms, Inc. and affiliates. All rights reserved.
Kotlin Ad Units Sample
Select an option
Debug Settings
Requesting an ad…
Load Interstitial
Refresh Now
Show!
Destroy Ad
Load Rewarded Video
Load Rewarded Interstitial
Load Native Ad
Check out more Native Ads examples in
hScroll
Template
RecyclerView
Ad icon
Ad image
Sponsored
Reload ads
Loading an ad…
Ad loaded
Ad failed to load: %s
Ad clicked
Style
Height
Show Code
- protected void onCreate(Bundle savedInstanceState) {
- \t…
- \tnativeAdContainer = (LinearLayout) findViewById(R.id.nativeAdContainer);
- \tnativeAd = new NativeAd(NativeTemplateActivity.this, "YOUR_PLACEMENT_ID");
- \tnativeAd.setAdListener(NativeTemplateActivity.this);
- \tnativeAd.loadAd();
- \t…
- }
-
- public void onAdLoaded(Ad ad) {
- \t…
- \tNativeAdViewAttributes adViewAttributes = new NativeAdViewAttributes();
- \tadViewAttributes.setBackgroundColor(adBackgroundColor);
- \tadViewAttributes.setTitleTextColor(adTitleColor);
- \t…
- \tView adView = NativeAdView.render(this, nativeAd, adViewAttributes);
- \tnativeAdContainer.addView(adView, 0);
- \t…
- }
- protected void onCreate(Bundle savedInstanceState) {
- \t…
- \tnativeAdContainer = (LinearLayout) findViewById(R.id.nativeAdContainer);
- \tnativeBannerAd = new NativeBannerAd(getContext(), "YOUR_PLACEMENT_ID");
- \tnativeBannerAd.setAdListener(this);
- \tnativeBannerAd.loadAd();
- \t…
- }
-
- public void onAdLoaded(Ad ad) {
- \t…
- \tNativeAdViewAttributes adViewAttributes = new NativeAdViewAttributes();
- \tadViewAttributes.setBackgroundColor(adBackgroundColor);
- \tadViewAttributes.setTitleTextColor(adTitleColor);
- \t…
- \tNativeBannerAdView.Type viewType = NativeBannerAdView.Type.HEIGHT_100;
- \tView adView = NativeBannerAdView.render(this, nativeBannerAd, viewType, adViewAttributes);
- \tnativeAdContainer.addView(adView, 0);
- \t…
- }
- White
- Black
- 50 DP
- 100 DP
- 120 DP
================================================
FILE: samples/android/KotlinAdUnitsSample/src/main/res/values/styles.xml
================================================
================================================
FILE: samples/android/README.md
================================================
Samples for Android Platform
============================
Facebook Audience Network allows you to monetize your Android apps with Facebook ads. Here we have a list of sample apps that implements different ad placements for your reference.
Please make sure that you have completed the [Audience Network Getting Started][1] and [Android Getting Started][2] guides before you proceed.
Sample list
-----------
### [AdUnitsSample](./AdUnitsSample)
This sample app demonstrates the implementation of
[Banners][3], [Rectangle Ad][3], [Interstitials][4] and [Rewarded Videos][8].
[Native Ads][5], [Native Ads Template][9], [Native Banner Ads][10] and [Native Banner Ads Template][9].
[Native Ad Horizontal Scroll][7] and [Native Ads in Recycler View][7].
### [KotlinAdUnitsSample](./KotlinAdUnitsSample)
Kotlin version of the `AdUnitsSample`, demonstrating the usage of Audience Network SDK with [Kotlin](11).
[1]: https://developers.facebook.com/docs/audience-network/getting-started
[2]: https://developers.facebook.com/docs/audience-network/android
[3]: https://developers.facebook.com/docs/audience-network/android-banners
[4]: https://developers.facebook.com/docs/audience-network/android-interstitial
[5]: https://developers.facebook.com/docs/audience-network/android-native
[7]: https://developers.facebook.com/docs/audience-network/android/nativeadsmanager
[8]: https://developers.facebook.com/docs/audience-network/android/rewarded-video
[9]: https://developers.facebook.com/docs/audience-network/android/nativeadtemplate
[10]: https://developers.facebook.com/docs/audience-network/android-native-banner
[11]: https://developer.android.com/kotlin
================================================
FILE: samples/android/build.gradle
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
buildscript {
repositories {
mavenCentral()
google()
}
dependencies {
classpath "com.android.tools.build:gradle:${project.GRADLE_VERSION}"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${project.KOTLIN_VERSION}"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
mavenCentral()
google()
}
}
================================================
FILE: samples/android/gradle.properties
================================================
# Ensure you update the following if making changes here:
# - samples/common/build.gradle.template
GRADLE_VERSION=7.0.2
LINT_VERSION=26.1.2
ANDROID_BUILD_MIN_SDK_VERSION=16
ANDROID_BUILD_TARGET_SDK_VERSION=33
ANDROID_BUILD_TOOLS_VERSION=30.0.2
ANDROID_BUILD_SDK_VERSION=33
ANDROIDX_VERSION=1.0.0
ANDROID_GOOGLE_PLAY_SERVICES_VERSION=15.0.1
KOTLIN_VERSION=1.3.40
android.useAndroidX=true
android.enableJetifier=true
================================================
FILE: samples/android/gradlew
================================================
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
================================================
FILE: samples/android/gradlew.bat
================================================
@REM Copyright (c) Meta Platforms, Inc. and affiliates.
@REM All rights reserved.
@REM
@REM This source code is licensed under the license found in the
@REM LICENSE file in the root directory of this source tree.
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: samples/android/settings.gradle
================================================
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*/
include ':AdUnitsSample'
include ':KotlinAdUnitsSample'
================================================
FILE: samples/ios/AdUnitsSample/.gitignore
================================================
# Xcode
## Build generated
build/
DerivedData/
## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata/
## Other
*.moved-aside
*.xccheckout
*.xcscmblueprint
# CocoaPods
Pods/
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/AdUnitsSample-Prefix.pch
================================================
//
// Prefix header
//
// The contents of this file are implicitly included at the beginning of every source file.
//
#import
#ifndef __IPHONE_3_0
#warning "This project uses features only available in iOS SDK 3.0 and later."
#endif
#ifdef __OBJC__
#import
#import
#endif
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/AdUnitsSample.entitlements
================================================
keychain-access-groups
$(AppIdentifierPrefix)com.facebook.audiencenetwork.AdUnitsSample
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/AdUnitsSampleStoryboard.storyboard
================================================
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/AppDelegate.h
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import
@interface AppDelegate : UIResponder
@property (nonatomic, strong) UIWindow *window;
@property (nonatomic, strong) UIViewController *viewController;
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/AppDelegate.m
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import "AppDelegate.h"
#import
@implementation AppDelegate
void installUncaughtExceptionHandler(void);
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Debug exception handler
installUncaughtExceptionHandler();
[FBAudienceNetworkAds initializeWithSettings:nil completionHandler:nil];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[UIStoryboard storyboardWithName:@"AdUnitsSampleStoryboard" bundle:nil] instantiateInitialViewController];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
#pragma mark Exception Handling (for debugging purposes)
NSString * const FBAdSignalExceptionName = @"handlerExceptionName";
NSString * const FBAdStackTraceKey = @"handlerStackTraceKey";
NSString * const FBAdSignalKey = @"handlerSignalKey";
void FBAdExceptionHandler(NSException *exception);
void FBAdSignalHandler(int signal);
static BOOL _displayExceptionMessage = YES;
void installUncaughtExceptionHandler()
{
NSSetUncaughtExceptionHandler(&FBAdExceptionHandler);
signal(SIGABRT, FBAdSignalHandler);
signal(SIGILL, FBAdSignalHandler);
signal(SIGSEGV, FBAdSignalHandler);
signal(SIGFPE, FBAdSignalHandler);
signal(SIGBUS, FBAdSignalHandler);
signal(SIGPIPE, FBAdSignalHandler);
}
void FBAdExceptionHandler(NSException *exception)
{
if (!exception) {
NSLog(@"Exception handler called with nil exception.");
__builtin_trap();
}
NSArray *callStack = [exception callStackSymbols];
NSLog(@"Stack trace: %@", callStack);
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSMutableDictionary *userInfo = [@{FBAdStackTraceKey: callStack} mutableCopy];
[userInfo addEntriesFromDictionary:exception.userInfo];
NSException *newException = [NSException exceptionWithName:exception.name reason:exception.reason userInfo:userInfo];
[delegate performSelectorOnMainThread:@selector(handleException:) withObject:newException waitUntilDone:YES];
}
void FBAdSignalHandler(int signal)
{
NSMutableDictionary *userInfo = [@{FBAdSignalKey: @(signal)} mutableCopy];
NSMutableArray *callStack = [[NSThread callStackSymbols] mutableCopy];
if (callStack) {
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 2)];
if ([callStack objectsAtIndexes:indexSet]) {
[callStack removeObjectsAtIndexes:indexSet];
}
userInfo[FBAdStackTraceKey] = callStack;
NSLog(@"Stack trace: %@", callStack);
}
NSString *reason = [NSString stringWithFormat:@"Signal %d was raised.", signal];
NSException *exception = [NSException exceptionWithName:FBAdSignalExceptionName reason:reason userInfo:userInfo];
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[delegate performSelectorOnMainThread:@selector(handleException:) withObject:exception waitUntilDone:YES];
}
- (void)handleException:(NSException *)exception
{
BOOL displayExceptionMessage = _displayExceptionMessage;
_displayExceptionMessage = NO;
if (displayExceptionMessage) {
NSString *message = [NSString stringWithFormat:@"The app has crashed due to an unhandled exception.\n\n"
@"Stack trace:\n%@\n%@", [exception reason], [[exception userInfo] objectForKey:FBAdStackTraceKey]];
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Unhandled Exception"
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil];
[alertController addAction:cancel];
[self.viewController presentViewController:alertController animated:YES completion:nil];
}
CFRunLoopRef runLoop = CFRunLoopGetCurrent();
CFArrayRef allModesCF = CFRunLoopCopyAllModes(runLoop);
NSArray *allModes = CFBridgingRelease(allModesCF);
while (true) {
for (NSString *mode in allModes) {
CFRunLoopRunInMode((CFStringRef)mode, 0.01, false);
}
}
}
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/BannerViewController.h
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import
@interface BannerViewController : UIViewController
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/BannerViewController.m
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import "BannerViewController.h"
#import
@interface BannerViewController ()
@property (nonatomic, strong) IBOutlet UILabel *adStatusLabel;
@property (nonatomic, strong) FBAdView *adView;
@end
@implementation BannerViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self loadAd];
}
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
FBAdSize adSize = [self fbAdSize];
CGSize viewSize = self.view.bounds.size;
CGSize tabBarSize = self.tabBarController.tabBar.frame.size;
viewSize = CGSizeMake(viewSize.width, viewSize.height - tabBarSize.height);
UIEdgeInsets insets = [self safeAreaInsets];
CGFloat bottomAlignedY = viewSize.height - adSize.size.height - insets.bottom;
self.adView.frame = CGRectMake(insets.left,
bottomAlignedY,
viewSize.width - insets.right - insets.left,
adSize.size.height);
}
- (UIEdgeInsets)safeAreaInsets
{
// Comment the following if-statement if you are not running XCode 9+
if (@available(iOS 11.0, *)) {
UIWindow *window = [[UIApplication sharedApplication].delegate window];
return [window safeAreaInsets];
}
return UIEdgeInsetsZero;
}
- (IBAction)refreshAd:(id)sender
{
self.adView.hidden = YES;
[self loadAd];
}
- (void)loadAd
{
if (nil != self.adView) {
[self.adView removeFromSuperview];
}
// Create a banner's ad view with a unique placement ID (generate your own on the Facebook app settings).
// Use different ID for each ad placement in your app.
FBAdSize adSize = [self fbAdSize];
self.adView = [[FBAdView alloc] initWithPlacementID:@"YOUR_PLACEMENT_ID"
adSize:adSize
rootViewController:self];
// Set a delegate to get notified on changes or when the user interact with the ad.
self.adView.delegate = self;
// When testing on a device, add its hashed ID to force test ads.
// The hash ID is printed to console when running on a device.
// [FBAdSettings addTestDevice:@"THE HASHED ID AS PRINTED TO CONSOLE"];
// Set autoresizingMask so the rotation is automatically handled
self.adView.autoresizingMask =
UIViewAutoresizingFlexibleRightMargin |
UIViewAutoresizingFlexibleLeftMargin|
UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleTopMargin;
// Add adView to the view hierarchy.
[self.view addSubview:self.adView];
self.adStatusLabel.text = @"Loading ad...";
[self.adView loadAd];
}
- (FBAdSize)fbAdSize
{
BOOL isIPAD = ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad);
return isIPAD ? kFBAdSizeHeight90Banner : kFBAdSizeHeight50Banner;
}
#pragma mark - FBAdViewDelegate implementation
// Implement this function if you want to change the viewController after the FBAdView
// is created. The viewController will be used to present the modal view (such as the
// in-app browser that can appear when an ad is clicked).
//- (UIViewController *)viewControllerForPresentingModalView
//{
// return self;
//}
- (void)adViewDidClick:(FBAdView *)adView
{
NSLog(@"Ad was clicked.");
}
- (void)adViewDidFinishHandlingClick:(FBAdView *)adView
{
NSLog(@"Ad did finish click handling.");
}
- (void)adViewDidLoad:(FBAdView *)adView
{
self.adStatusLabel.text = @"Ad loaded.";
NSLog(@"Ad was loaded.");
// Now that the ad was loaded, show the view in case it was hidden before.
self.adView.hidden = NO;
}
- (void)adView:(FBAdView *)adView didFailWithError:(NSError *)error
{
self.adStatusLabel.text = [NSString stringWithFormat:@"Ad failed to load. %@", error.localizedDescription];
NSLog(@"Ad failed to load with error: %@", error);
// Hide the unit since no ad is shown.
self.adView.hidden = YES;
}
- (void)adViewWillLogImpression:(FBAdView *)adView
{
NSLog(@"Ad impression is being captured.");
}
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/CollectionViewController.h
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import
@interface CollectionViewController : UIViewController
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/CollectionViewController.m
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import "CollectionViewController.h"
#import
static NSInteger const kRowStrideForAdCell = 3;
static NSString *const kDefaultCellIdentifier = @"kDefaultCellIdentifier";
@interface CollectionViewCell : UICollectionViewCell
@property (nonatomic, strong, nullable) UILabel *textLabel;
@end
@implementation CollectionViewCell
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
UILabel *label = [UILabel new];
label.textColor = [UIColor blackColor];
label.numberOfLines = 2;
self.textLabel = label;
[self.contentView addSubview:label];
}
return self;
}
@end
@interface CollectionViewController ()
@property (strong, nonatomic) IBOutlet UICollectionView *collectionView;
@property (strong, nonatomic) IBOutlet UIActivityIndicatorView *activityIndicator;
@property (strong, nonatomic) FBNativeAdsManager *adsManager;
@property (strong, nonatomic) FBNativeAdCollectionViewCellProvider *cellProvider;
@property (strong, nonatomic) NSMutableArray *collectionViewContentArray;
@property (assign, nonatomic) BOOL adCellsCreated;
@end
@implementation CollectionViewController
#pragma mark - Lazy Loading
- (NSMutableArray *)collectionViewContentArray
{
if (!_collectionViewContentArray) {
_collectionViewContentArray = [NSMutableArray array];
for (NSUInteger i = 0; i < 10; i++) {
[_collectionViewContentArray addObject:[NSString stringWithFormat:@"CollectionView\n Cell #%lu", (unsigned long)(i + 1)]];
}
}
return _collectionViewContentArray;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
[self.collectionView registerClass:[CollectionViewCell class] forCellWithReuseIdentifier:kDefaultCellIdentifier];
[self loadNativeAd];
}
- (IBAction)dismissViewController:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)refresh:(id)sender
{
[self loadNativeAd];
}
- (void)loadNativeAd
{
[self.activityIndicator startAnimating];
if (!self.adsManager) {
// Create a native ad manager with a unique placement ID (generate your own on the Facebook app settings)
// and how many ads you would like to create. Note that you may get fewer ads than you ask for.
// Use different ID for each ad placement in your app.
self.adsManager = [[FBNativeAdsManager alloc] initWithPlacementID:@"YOUR_PLACEMENT_ID"
forNumAdsRequested:5];
// Set a delegate to get notified when the ads are loaded.
self.adsManager.delegate = self;
// Configure native ad manager to wait to call nativeAdsLoaded until all ad assets are loaded
self.adsManager.mediaCachePolicy = FBNativeAdsCachePolicyAll;
// When testing on a device, add its hashed ID to force test ads.
// The hash ID is printed to console when running on a device.
// [FBAdSettings addTestDevice:@"THE HASHED ID AS PRINTED TO CONSOLE"];
}
// Load some ads
[self.adsManager loadAds];
}
#pragma mark FBNativeAdsManagerDelegate implementation
- (void)nativeAdsLoaded
{
NSLog(@"Native ad was loaded, constructing native UI...");
// After the native ads have loaded we create the native ad cell provider and let it take over
FBNativeAdsManager *manager = self.adsManager;
self.adsManager.delegate = nil;
self.adsManager = nil;
// The native ad cell provider operates over a loaded ads manager and can create table cells with native
// ad templates in them as well as help with the math to have a consistent distribution of ads within a table.
FBNativeAdCollectionViewCellProvider *cellProvider = [[FBNativeAdCollectionViewCellProvider alloc] initWithManager:manager forType:FBNativeAdViewTypeGenericHeight300];
self.cellProvider = cellProvider;
self.cellProvider.delegate = self;
[self.collectionView reloadData];
[self.activityIndicator stopAnimating];
}
- (void)nativeAdsFailedToLoadWithError:(NSError *)error
{
NSLog(@"Native ad failed to load with error: %@", error);
[self.activityIndicator stopAnimating];
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Native ad failed to load"
message:@"Check console for more details"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil];
[alertController addAction:cancel];
[self presentViewController:alertController animated:YES completion:nil];
}
#pragma mark FBNativeAdDelegate
- (void)nativeAdDidClick:(FBNativeAd *)nativeAd
{
NSLog(@"Native ad was clicked.");
}
- (void)nativeAdDidFinishHandlingClick:(FBNativeAd *)nativeAd
{
NSLog(@"Native ad did finish click handling.");
}
- (void)nativeAdWillLogImpression:(FBNativeAd *)nativeAd
{
NSLog(@"Native ad impression is being captured.");
}
#pragma mark
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
// In this example the ads are evenly distributed within the table every kRowStrideForAdCell-th cell.
NSUInteger count = [self.collectionViewContentArray count];
count = [self.cellProvider adjustCount:count forStride:kRowStrideForAdCell] ?: count;
return count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
if ([self.cellProvider isAdCellAtIndexPath:indexPath forStride:kRowStrideForAdCell]) {
return [self.cellProvider collectionView:collectionView cellForItemAtIndexPath:indexPath];
} else {
indexPath = [self.cellProvider adjustNonAdCellIndexPath:indexPath forStride:kRowStrideForAdCell] ?: indexPath;
CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kDefaultCellIdentifier forIndexPath:indexPath];
cell.textLabel.text = [self.collectionViewContentArray objectAtIndex:indexPath.row];
[cell.textLabel sizeToFit];
cell.textLabel.center = cell.contentView.center;
return cell;
}
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
if ([self.cellProvider isAdCellAtIndexPath:indexPath forStride:kRowStrideForAdCell]) {
return (CGSize){300.0, [self.cellProvider collectionView:collectionView heightForRowAtIndexPath:indexPath]};
} else {
return (CGSize){300.0, 100.0};
}
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
return 20.0;
}
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/DebugLogsViewController.h
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import
@interface DebugLogsViewController : UITableViewController
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/DebugLogsViewController.m
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import "DebugLogsViewController.h"
static NSString *const kDebugLogsCellIdentifier = @"kDebugLogsCellIdentifier";
@interface DebugLogsViewController ()
@property (nonatomic, strong, readonly) NSArray *tableViewCellLabels;
@end
@implementation DebugLogsViewController
@synthesize tableViewCellLabels = _tableViewCellLabels;
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (NSArray *)tableViewCellLabels
{
if (nil == _tableViewCellLabels) {
_tableViewCellLabels = @[@"Generic Error", @"Database Error", @"Exception App Crash", @"Signal App Crash", @"Exception SDK Crash"];
}
return _tableViewCellLabels;
}
- (void)generateGenericError
{
Class class = NSClassFromString(@"FBAdDebugLogging");
SEL selector = NSSelectorFromString(@"logDebugEventWithType:code:description:");
NSMethodSignature *signature = [class methodSignatureForSelector:selector];
NSUInteger errorCode = 0;
NSString *eventType = @"generic";
NSString *errorDescription = @"Generic error test message";
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setTarget:class];
[invocation setSelector:selector];
[invocation setArgument:&eventType atIndex:2];
[invocation setArgument:&errorCode atIndex:3];
[invocation setArgument:&errorDescription atIndex:4];
[invocation retainArguments];
[invocation invoke];
}
- (void)generateDatabaseError
{
Class class = NSClassFromString(@"FBAdDebugLogging");
SEL selector = NSSelectorFromString(@"logDebugEventWithType:code:description:");
NSMethodSignature *signature = [class methodSignatureForSelector:selector];
NSUInteger errorCode = 7;
NSString *eventType = @"database";
NSString *errorDescription = @"Database error cannot open database test message";
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setTarget:class];
[invocation setSelector:selector];
[invocation setArgument:&eventType atIndex:2];
[invocation setArgument:&errorCode atIndex:3];
[invocation setArgument:&errorDescription atIndex:4];
[invocation retainArguments];
[invocation invoke];
}
- (void)generateExceptionCrash
{
[[self class] staticGenerateExceptionCrash];
}
+ (void)staticGenerateExceptionCrash
{
NSString *string = nil;
NSArray *array = @[string];
array = nil;
}
- (void)generateSignalCrash
{
__unsafe_unretained NSNumber *number = @4.4;
[number description];
}
- (void)generateSDKCrash
{
Class class = NSClassFromString(@"FBAdReportingItem");
id reportingItem = [class alloc];
SEL selector = NSSelectorFromString(@"initWithIdentifier:title:heading:subItems:");
NSMethodSignature *signature = [reportingItem methodSignatureForSelector:selector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setTarget:reportingItem];
[invocation setSelector:selector];
[invocation setArgument:@"" atIndex:2];
[invocation setArgument:@"" atIndex:3];
[invocation setArgument:@"" atIndex:4];
[invocation retainArguments];
[invocation invoke];
selector = NSSelectorFromString(@"addSubItem:");
signature = [reportingItem methodSignatureForSelector:selector];
invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setTarget:reportingItem];
[invocation setSelector:selector];
[invocation retainArguments];
[invocation invoke];
}
#pragma mark - UITableViewDataSource implementation
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [@"Select one of the options below" uppercaseString];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.tableViewCellLabels.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kDebugLogsCellIdentifier forIndexPath:indexPath];
cell.textLabel.text = self.tableViewCellLabels[indexPath.row];
return cell;
}
#pragma mark - UITableViewDelegate implementation
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
switch (indexPath.row) {
case 0:
[self generateGenericError];
break;
case 1:
[self generateDatabaseError];
break;
case 2:
[self generateExceptionCrash];
break;
case 3:
[self generateSignalCrash];
break;
case 4:
[self generateSDKCrash];
break;
}
}
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/Images.xcassets/AppIcon.appiconset/Contents.json
================================================
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-Small@3x.png",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-Small-40@3x.png",
"scale" : "3x"
},
{
"size" : "57x57",
"idiom" : "iphone",
"filename" : "Icon.png",
"scale" : "1x"
},
{
"size" : "57x57",
"idiom" : "iphone",
"filename" : "Icon@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-Small-60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-Small-60@3x.png",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-Small.png",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-Small-40.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-Small-40@2x.png",
"scale" : "2x"
},
{
"size" : "50x50",
"idiom" : "ipad",
"filename" : "Icon-Small-50.png",
"scale" : "1x"
},
{
"size" : "50x50",
"idiom" : "ipad",
"filename" : "Icon-Small-50@2x.png",
"scale" : "2x"
},
{
"size" : "72x72",
"idiom" : "ipad",
"filename" : "Icon-72.png",
"scale" : "1x"
},
{
"size" : "72x72",
"idiom" : "ipad",
"filename" : "Icon-72@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-76.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-76@2x.png",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
},
{
"size" : "60x60",
"idiom" : "car",
"filename" : "Icon-60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "car",
"filename" : "Icon-60@3x.png",
"scale" : "3x"
},
{
"size" : "24x24",
"idiom" : "watch",
"scale" : "2x",
"role" : "notificationCenter",
"subtype" : "38mm"
},
{
"size" : "27.5x27.5",
"idiom" : "watch",
"scale" : "2x",
"role" : "notificationCenter",
"subtype" : "42mm"
},
{
"size" : "29x29",
"idiom" : "watch",
"filename" : "Icon-Small@2x.png",
"role" : "companionSettings",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "watch",
"role" : "companionSettings",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "watch",
"scale" : "2x",
"role" : "appLauncher",
"subtype" : "38mm"
},
{
"size" : "44x44",
"idiom" : "watch",
"scale" : "2x",
"role" : "appLauncher",
"subtype" : "40mm"
},
{
"size" : "50x50",
"idiom" : "watch",
"scale" : "2x",
"role" : "appLauncher",
"subtype" : "44mm"
},
{
"size" : "86x86",
"idiom" : "watch",
"scale" : "2x",
"role" : "quickLook",
"subtype" : "38mm"
},
{
"size" : "98x98",
"idiom" : "watch",
"scale" : "2x",
"role" : "quickLook",
"subtype" : "42mm"
},
{
"size" : "108x108",
"idiom" : "watch",
"scale" : "2x",
"role" : "quickLook",
"subtype" : "44mm"
},
{
"idiom" : "watch-marketing",
"size" : "1024x1024",
"scale" : "1x"
},
{
"size" : "44x44",
"idiom" : "watch",
"scale" : "2x",
"role" : "longLook",
"subtype" : "42mm"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/Images.xcassets/Contents.json
================================================
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/Info.plist
================================================
CFBundleDevelopmentRegion
en
CFBundleDisplayName
${PRODUCT_NAME}
CFBundleExecutable
${EXECUTABLE_NAME}
CFBundleIdentifier
$(PRODUCT_BUNDLE_IDENTIFIER)
CFBundleInfoDictionaryVersion
6.0
CFBundleName
${PRODUCT_NAME}
CFBundlePackageType
APPL
CFBundleShortVersionString
1.0
CFBundleSignature
????
CFBundleVersion
1.0
LSRequiresIPhoneOS
UILaunchStoryboardName
LaunchScreen
UIMainStoryboardFile
AdUnitsSampleStoryboard
UIRequiredDeviceCapabilities
armv7
UISupportedInterfaceOrientations
UIInterfaceOrientationPortrait
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
UISupportedInterfaceOrientations~ipad
UIInterfaceOrientationPortrait
UIInterfaceOrientationPortraitUpsideDown
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/InfoPlist.strings
================================================
/* Localized versions of Info.plist keys */
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/InstreamViewController.h
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import
@interface InstreamViewController : UIViewController
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/InstreamViewController.m
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import "InstreamViewController.h"
#import
@interface InstreamViewController ()
@property (nonatomic, strong) IBOutlet UILabel *adStatusLabel;
@property (nonatomic, strong) IBOutlet UIView *mediaView;
@property (nonatomic, strong) FBInstreamAdView *adView;
@end
@implementation InstreamViewController
- (IBAction)loadAd
{
// Create an instream ad view with a unique placement ID (generate your own on the Facebook app settings).
// Use different ID for each ad placement in your app.
[self.adView removeFromSuperview];
self.adView = [[FBInstreamAdView alloc] initWithPlacementID:@"YOUR_PLACEMENT_ID"];
// Set a delegate to get notified on changes or when the user interacts with the ad.
self.adView.delegate = self;
// Initiate a request to load an ad.
[self.adView loadAd];
self.adStatusLabel.text = @"Loading instream ad...";
}
- (IBAction)showAd
{
if (!self.adView || !self.adView.adValid) {
// Ad not ready to present.
self.adStatusLabel.text = @"Ad not loaded. Click load to request an ad.";
} else {
// Ad is ready, present it!
self.adStatusLabel.text = nil;
self.adView.frame = self.mediaView.bounds;
self.adView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.mediaView addSubview:self.adView];
[self.adView showAdFromRootViewController:self];
}
}
#pragma mark - FBInstreamAdViewDelegate implementation
- (void)adViewDidLoad:(FBInstreamAdView *)adView
{
self.adStatusLabel.text = @"Ad loaded";
}
- (void)adViewDidEnd:(FBInstreamAdView *)adView
{
self.adStatusLabel.text = @"Ad ended";
[self.adView removeFromSuperview];
self.adView = nil;
}
- (void)adView:(FBInstreamAdView *)adView didFailWithError:(NSError *)error
{
self.adStatusLabel.text = [NSString stringWithFormat:@"Ad failed: %@", error.localizedDescription];
[self.adView removeFromSuperview];
self.adView = nil;
}
- (void)adViewDidClick:(FBInstreamAdView *)adView
{
self.adStatusLabel.text = @"Ad clicked";
}
- (void)adViewWillLogImpression:(FBInstreamAdView *)adView
{
self.adStatusLabel.text = @"Ad impression";
}
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/InterstitialViewController.h
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import
@interface InterstitialViewController : UIViewController
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/InterstitialViewController.m
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import "InterstitialViewController.h"
#import
@interface InterstitialViewController ()
@property (nonatomic, strong) IBOutlet UILabel *adStatusLabel;
@property (nonatomic, strong) FBInterstitialAd *interstitialAd;
@end
@implementation InterstitialViewController
- (IBAction)loadAd
{
self.adStatusLabel.text = @"Loading interstitial ad...";
// Create the interstitial unit with a placement ID (generate your own on the Facebook app settings).
// Use different ID for each ad placement in your app.
self.interstitialAd = [[FBInterstitialAd alloc] initWithPlacementID:@"YOUR_PLACEMENT_ID"];
// Set a delegate to get notified on changes or when the user interact with the ad.
self.interstitialAd.delegate = self;
// Initiate the request to load the ad.
[self.interstitialAd loadAd];
}
- (IBAction)showAd
{
if (!self.interstitialAd || !self.interstitialAd.isAdValid)
{
// Ad not ready to present.
self.adStatusLabel.text = @"Ad not loaded. Click load to request an ad.";
} else {
self.adStatusLabel.text = @"1. Tap 'Load Ad'\n2. Once ad loads, tap 'Show!' to see the ad";
// Ad is ready, present it!
[self.interstitialAd showAdFromRootViewController:self];
}
}
#pragma mark - FBInterstitialAdDelegate implementation
- (void)interstitialAdDidLoad:(FBInterstitialAd *)interstitialAd
{
NSLog(@"Interstitial ad was loaded. Can present now.");
self.adStatusLabel.text = @"Ad loaded. Click show to present!";
}
- (void)interstitialAd:(FBInterstitialAd *)interstitialAd didFailWithError:(NSError *)error
{
NSLog(@"Interstitial failed to load with error: %@", error.description);
self.adStatusLabel.text = [NSString stringWithFormat:@"Interstitial ad failed to load. %@", error.localizedDescription];
}
- (void)interstitialAdDidClick:(FBInterstitialAd *)interstitialAd
{
NSLog(@"Interstitial was clicked.");
}
- (void)interstitialAdDidClose:(FBInterstitialAd *)interstitialAd
{
NSLog(@"Interstitial closed.");
// Optional, Cleaning up.
self.interstitialAd = nil;
}
- (void)interstitialAdWillClose:(FBInterstitialAd *)interstitialAd
{
NSLog(@"Interstitial will close.");
}
- (void)interstitialAdWillLogImpression:(FBInterstitialAd *)interstitialAd
{
NSLog(@"Interstitial impression is being captured.");
}
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/LaunchScreen.storyboard
================================================
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/MediumRectViewController.h
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import
@interface MediumRectViewController : UIViewController
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/MediumRectViewController.m
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import "MediumRectViewController.h"
#import
@interface MediumRectViewController ()
@property (nonatomic, strong) IBOutlet UIView *adContainer;
@property (nonatomic, strong) IBOutlet UILabel *adStatusLabel;
@property (nonatomic, strong) FBAdView *mediumRectAdView;
@end
@implementation MediumRectViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self loadAd];
}
- (IBAction)refreshAd:(id)sender
{
self.mediumRectAdView.hidden = YES;
[self loadAd];
}
- (void)loadAd
{
if (nil != self.mediumRectAdView) {
[self.mediumRectAdView removeFromSuperview];
}
// Create the medium rectangle unit with a placement ID (generate your own on the Facebook app settings).
// Use different ID for each ad placement in your app.
FBAdSize adSize = kFBAdSizeHeight250Rectangle;
self.mediumRectAdView = [[FBAdView alloc] initWithPlacementID:@"YOUR_PLACEMENT_ID"
adSize:adSize
rootViewController:self];
self.mediumRectAdView.hidden = YES;
// Set a delegate to get notified on changes or when the user interact with the ad.
self.mediumRectAdView.delegate = self;
// Reposition the adView
self.mediumRectAdView.frame = CGRectMake(0, 0, 300, 250);
[self.adContainer addSubview:self.mediumRectAdView];
self.adStatusLabel.text = @"Loading ad...";
[self.mediumRectAdView loadAd];
}
#pragma mark - FBAdViewDelegate implementation
// Implement this function if you want to change the viewController after the FBAdView
// is created. The viewController will be used to present the modal view (such as the
// in-app browser that can appear when an ad is clicked).
// - (UIViewController *)viewControllerForPresentingModalView
// {
// return self;
// }
- (void)adViewDidClick:(FBAdView *)adView
{
NSLog(@"Ad was clicked.");
}
- (void)adViewDidFinishHandlingClick:(FBAdView *)adView
{
NSLog(@"Ad did finish click handling.");
}
- (void)adViewDidLoad:(FBAdView *)adView
{
self.adStatusLabel.text = @"Ad loaded.";
NSLog(@"Ad was loaded.");
// Now that the ad was loaded, show the view in case it was hidden before.
self.mediumRectAdView.hidden = NO;
}
- (void)adView:(FBAdView *)adView didFailWithError:(NSError *)error
{
self.adStatusLabel.text = [NSString stringWithFormat:@"Ad failed to load. Check console for details. %@", error.localizedDescription];
NSLog(@"Ad failed to load with error: %@", error);
// Hide the unit since no ad is shown.
self.mediumRectAdView.hidden = YES;
}
- (void)adViewWillLogImpression:(FBAdView *)adView
{
NSLog(@"Ad impression is being captured.");
}
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/MenuTableViewController.h
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import
@interface MenuTableViewController : UITableViewController
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/MenuTableViewController.m
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import "MenuTableViewController.h"
@interface MenuTableViewController ()
@end
@implementation MenuTableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return @"Select one of the options below".uppercaseString;
}
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/NativeAdTemplateViewController.h
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import
@interface NativeAdTemplateViewController : UIViewController
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/NativeAdTemplateViewController.m
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import "NativeAdTemplateViewController.h"
#import
@interface NativeAdTemplateViewController ()
@property (strong, nonatomic) IBOutlet UILabel *adStatusLabel;
@property (strong, nonatomic) IBOutlet UIView *adContainerView;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *adContainerHeightConstraint;
@property (retain, nonatomic) IBOutlet NSLayoutConstraint *adContainerWidthConstraint;
@property (retain, nonatomic) IBOutlet UISlider *heightSlider;
@property (retain, nonatomic) IBOutlet UISlider *widthSlider;
@property (strong, nonatomic) FBNativeAd *nativeAd;
@property (strong, nonatomic) FBNativeAdViewAttributes *nativeAdAttributes;
@property (strong, nonatomic) FBNativeAdView *adView;
@end
@implementation NativeAdTemplateViewController
- (FBNativeAdViewAttributes *)nativeAdAttributes
{
FBNativeAdViewAttributes *attributes = _nativeAdAttributes;
if (!attributes) {
attributes = [[FBNativeAdViewAttributes alloc] init];
attributes.backgroundColor = [UIColor whiteColor];
attributes.advertiserNameColor = [UIColor colorWithRed:0.11 green:0.12 blue:0.13 alpha:1.0];
attributes.buttonColor = [UIColor colorWithRed:0.235 green:0.485 blue:1.000 alpha:1.000];
attributes.buttonTitleColor = [UIColor whiteColor];
attributes.titleColor = [UIColor darkGrayColor];
attributes.descriptionColor = [UIColor grayColor];
_nativeAdAttributes = attributes;
}
return attributes;
}
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
self.heightSlider.value = self.adContainerHeightConstraint.constant;
self.widthSlider.value = self.adContainerWidthConstraint.constant;
}
#pragma mark - Actions
- (IBAction)handleAdHeightChange:(id)sender
{
CGFloat height = ((UISlider *)sender).value;
self.adContainerHeightConstraint.constant = height;
}
- (IBAction)handleWidthChange:(id)sender
{
CGFloat width = ((UISlider *)sender).value;
self.adContainerWidthConstraint.constant = width;
}
- (IBAction)loadNativeAd
{
self.adStatusLabel.text = @"Requesting an ad...";
// Create a native ad request with a unique placement ID (generate your own on the Facebook app settings).
// Use different ID for each ad placement in your app.
FBNativeAd *nativeAd = [[FBNativeAd alloc] initWithPlacementID:@"YOUR_PLACEMENT_ID"];
// Set a delegate to get notified when the ad was loaded.
nativeAd.delegate = self;
// When testing on a device, add its hashed ID to force test ads.
// The hash ID is printed to console when running on a device.
// [FBAdSettings addTestDevice:@"THE HASHED ID AS PRINTED TO CONSOLE"];
// Initiate a request to load an ad.
[nativeAd loadAd];
[self.adView removeFromSuperview];
}
#pragma mark - FBNativeAdDelegate
- (void)nativeAdDidLoad:(FBNativeAd *)nativeAd
{
if (self.nativeAd) {
[self.nativeAd unregisterView];
}
self.nativeAd = nativeAd;
self.adStatusLabel.text = @"Ad loaded.";
if (nativeAd && nativeAd.isAdValid) {
FBNativeAdView *adView = [FBNativeAdView nativeAdViewWithNativeAd:nativeAd
withAttributes:[self nativeAdAttributes]];
adView.frame = self.adContainerView.bounds;
adView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.adContainerView addSubview:adView];
self.adView = adView;
}
}
- (void)nativeAd:(FBNativeAd *)nativeAd didFailWithError:(NSError *)error
{
self.adStatusLabel.text = @"Ad failed to load. Check console for details.";
NSLog(@"Native ad failed to load with error: %@", error);
}
- (void)nativeAdDidClick:(FBNativeAd *)nativeAd
{
NSLog(@"Native ad was clicked.");
}
- (void)nativeAdDidFinishHandlingClick:(FBNativeAd *)nativeAd
{
NSLog(@"Native ad did finish click handling.");
}
- (void)nativeAdWillLogImpression:(FBNativeAd *)nativeAd
{
NSLog(@"Native ad impression is being captured.");
}
#pragma mark - Orientation
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/NativeBannerAdTemplateViewController.h
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import
@interface NativeBannerAdTemplateViewController : UIViewController
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/NativeBannerAdTemplateViewController.m
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import "NativeBannerAdTemplateViewController.h"
#import
@interface NativeBannerAdTemplateViewController ()
@property (strong, nonatomic) IBOutlet UISegmentedControl *templateTypeControl;
@property (strong, nonatomic) IBOutlet UILabel *adStatusLabel;
@property (strong, nonatomic) IBOutlet UIView *adContainerView;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *adContainerHeightConstraint;
@property (strong, nonatomic) FBNativeBannerAd *nativeAd;
@property (strong, nonatomic) FBNativeAdViewAttributes *nativeAdAttributes;
@property (strong, nonatomic) FBNativeBannerAdView *adView;
@end
@implementation NativeBannerAdTemplateViewController
- (void)adjustAdContainerHeight
{
switch ([self templateType]) {
case FBNativeBannerAdViewTypeGenericHeight50:
self.adContainerHeightConstraint.constant = 50.0f;
break;
case FBNativeBannerAdViewTypeGenericHeight100:
self.adContainerHeightConstraint.constant = 100.f;
break;
case FBNativeBannerAdViewTypeGenericHeight120:
self.adContainerHeightConstraint.constant = 120.f;
break;
default:
break;
}
}
- (FBNativeBannerAdViewType)templateType
{
FBNativeBannerAdViewType type = FBNativeBannerAdViewTypeGenericHeight50;
switch (self.templateTypeControl.selectedSegmentIndex) {
case 0:
type = FBNativeBannerAdViewTypeGenericHeight50;
break;
case 1:
type = FBNativeBannerAdViewTypeGenericHeight100;
break;
case 2:
type = FBNativeBannerAdViewTypeGenericHeight120;
break;
};
return type;
}
#pragma mark - Actions
- (IBAction)loadNativeAd
{
self.adStatusLabel.text = @"Requesting an ad...";
// Create a native ad request with a unique placement ID (generate your own on the Facebook app settings).
// Use different ID for each ad placement in your app.
FBNativeBannerAd *nativeAd = [[FBNativeBannerAd alloc] initWithPlacementID:@"YOUR_PLACEMENT_ID"];
// Set a delegate to get notified when the ad was loaded.
nativeAd.delegate = self;
// When testing on a device, add its hashed ID to force test ads.
// The hash ID is printed to console when running on a device.
// [FBAdSettings addTestDevice:@"THE HASHED ID AS PRINTED TO CONSOLE"];
// Initiate a request to load an ad.
[nativeAd loadAd];
[self.adView removeFromSuperview];
[self adjustAdContainerHeight];
}
#pragma mark - FBNativeAdDelegate
- (void)nativeBannerAdDidLoad:(FBNativeBannerAd *)nativeBannerAd
{
if (self.nativeAd) {
[self.nativeAd unregisterView];
}
self.nativeAd = nativeBannerAd;
self.adStatusLabel.text = @"Ad loaded.";
if (nativeBannerAd && nativeBannerAd.isAdValid) {
FBNativeBannerAdView *adView = [FBNativeBannerAdView nativeBannerAdViewWithNativeBannerAd:nativeBannerAd
withType:[self templateType]];
adView.frame = self.adContainerView.bounds;
[self.adContainerView addSubview:adView];
self.adView = adView;
}
}
- (void)nativeBannerAd:(FBNativeBannerAd *)nativeBannerAd didFailWithError:(NSError *)error
{
self.adStatusLabel.text = @"Ad failed to load. Check console for details.";
NSLog(@"Native ad failed to load with error: %@", error);
}
- (void)nativeBannerAdDidClick:(FBNativeBannerAd *)nativeBannerAd
{
NSLog(@"Native ad was clicked.");
}
- (void)nativeBannerAdDidFinishHandlingClick:(FBNativeBannerAd *)nativeBannerAd
{
NSLog(@"Native ad did finish click handling.");
}
- (void)nativeBannerAdWillLogImpression:(FBNativeBannerAd *)nativeBannerAd
{
NSLog(@"Native ad impression is being captured.");
}
#pragma mark - Orientation
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/NativeBannerViewController.h
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import
@interface NativeBannerViewController : UIViewController
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/NativeBannerViewController.m
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import "NativeBannerViewController.h"
#import
@interface NativeBannerViewController ()
@property (nonatomic, strong) IBOutlet UILabel *adStatusLabel;
@property (nonatomic, strong) IBOutlet FBAdIconView *adIconView;
@property (nonatomic, strong) IBOutlet UILabel *adTitleLabel;
@property (nonatomic, strong) IBOutlet UIButton *adCallToActionButton;
@property (nonatomic, strong) IBOutlet UILabel *adSponsoredLabel;
@property (nonatomic, strong) IBOutlet FBAdOptionsView *adOptionsView;
@property (nonatomic, strong) IBOutlet UIView *adUIView;
@property (nonatomic, strong) FBNativeBannerAd *nativeBannerAd;
@end
@implementation NativeBannerViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.adOptionsView.hidden = YES;
}
#pragma mark - IB Actions
- (IBAction)loadAd:(id)sender
{
self.adStatusLabel.text = @"Requesting an ad...";
// Create a native ad request with a unique placement ID (generate your own on the Facebook app settings).
// Use different ID for each ad placement in your app.
FBNativeBannerAd *nativeBannerAd = [[FBNativeBannerAd alloc] initWithPlacementID:@"YOUR_PLACEMENT_ID"];
// Set a delegate to get notified when the ad was loaded.
nativeBannerAd.delegate = self;
// When testing on a device, add its hashed ID to force test ads.
// The hash ID is printed to console when running on a device.
// [FBAdSettings addTestDevice:@"THE HASHED ID AS PRINTED TO CONSOLE"];
// Initiate a request to load an ad.
[nativeBannerAd loadAd];
}
#pragma mark - FBNativeBannerAdDelegate implementation
- (void)nativeBannerAdDidLoad:(FBNativeBannerAd *)nativeBannerAd
{
NSLog(@"Native banner ad was loaded, constructing native UI...");
if (self.nativeBannerAd) {
[self.nativeBannerAd unregisterView];
}
self.nativeBannerAd = nativeBannerAd;
self.adStatusLabel.text = @"Ad loaded.";
// Render native ads onto UIView
self.adTitleLabel.text = self.nativeBannerAd.advertiserName;
self.adSponsoredLabel.text = self.nativeBannerAd.sponsoredTranslation;
[self setCallToActionButton:self.nativeBannerAd.callToAction];
NSLog(@"Register UIView for impression and click...");
// Set native banner ad view tags to declare roles of your views for better analysis in future
// We will be able to provide you statistics how often these views were clicked by users
// Views provided by Facebook already have appropriate tag set
self.adTitleLabel.nativeAdViewTag = FBNativeAdViewTagTitle;
self.adCallToActionButton.nativeAdViewTag = FBNativeAdViewTagCallToAction;
// Specify the clickable areas. View you were using to set ad view tags should be clickable.
NSArray *clickableViews = @[self.adCallToActionButton];
[nativeBannerAd registerViewForInteraction:self.adUIView
iconView:self.adIconView
viewController:self
clickableViews:clickableViews];
// In you don't want to provide native ad view tags you can simply
// Wire up UIView with the native banner ad; the whole UIView will be clickable.
// [nativeBannerAd registerViewForInteraction:self.adUIView
// iconView:self.adIconView
// viewController:self];
self.adOptionsView.nativeAd = nativeBannerAd;
self.adOptionsView.hidden = NO;
}
- (void)nativeBannerAd:(FBNativeBannerAd *)nativeBannerAd didFailWithError:(NSError *)error
{
self.adStatusLabel.text = @"Ad failed to load. Check console for details.";
NSLog(@"Native ad failed to load with error: %@", error);
}
- (void)nativeBannerAdDidClick:(FBNativeBannerAd *)nativeBannerAd
{
NSLog(@"Native ad was clicked.");
}
- (void)nativeBannerAdDidFinishHandlingClick:(FBNativeBannerAd *)nativeBannerAd
{
NSLog(@"Native ad did finish click handling.");
}
- (void)nativeBannerAdWillLogImpression:(FBNativeBannerAd *)nativeBannerAd
{
NSLog(@"Native ad impression is being captured.");
}
#pragma mark - Private Methods
- (void)setCallToActionButton:(NSString *)callToAction
{
if (callToAction) {
[self.adCallToActionButton setHidden:NO];
[self.adCallToActionButton setTitle:callToAction
forState:UIControlStateNormal];
} else {
[self.adCallToActionButton setHidden:YES];
}
}
#pragma mark - Orientation
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/NativeViewController.h
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import
@interface NativeViewController : UIViewController
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/NativeViewController.m
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import "NativeViewController.h"
#import
const NSUInteger LoadNativeAdCellRowIndex = 0;
@interface NativeViewController ()
@property (strong, nonatomic) IBOutlet UITableView *menuTableView;
@property (strong, nonatomic) IBOutlet UILabel *adStatusLabel;
@property (strong, nonatomic) IBOutlet FBMediaView *adIconView;
@property (strong, nonatomic) IBOutlet FBMediaView *adCoverMediaView;
@property (strong, nonatomic) IBOutlet UILabel *adTitleLabel;
@property (strong, nonatomic) IBOutlet UILabel *adBodyLabel;
@property (strong, nonatomic) IBOutlet UIButton *adCallToActionButton;
@property (strong, nonatomic) IBOutlet UILabel *adSocialContextLabel;
@property (strong, nonatomic) IBOutlet UILabel *sponsoredLabel;
@property (strong, nonatomic) IBOutlet FBAdOptionsView *adOptionsView;
@property (strong, nonatomic) IBOutlet UIView *adUIView;
@property (strong, nonatomic) FBNativeAd *nativeAd;
@end
@implementation NativeViewController
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
// Used in xib must be referenced here so linker won't eliminate it.
[FBMediaView class];
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.adOptionsView.hidden = YES;
self.menuTableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
}
#pragma mark - IB Actions
- (void)loadNativeAd
{
self.adStatusLabel.text = @"Requesting an ad...";
// Create a native ad request with a unique placement ID (generate your own on the Facebook app settings).
// Use different ID for each ad placement in your app.
FBNativeAd *nativeAd = [[FBNativeAd alloc] initWithPlacementID:@"YOUR_PLACEMENT_ID"];
// Set a delegate to get notified when the ad was loaded.
nativeAd.delegate = self;
// When testing on a device, add its hashed ID to force test ads.
// The hash ID is printed to console when running on a device.
// [FBAdSettings addTestDevice:@"THE HASHED ID AS PRINTED TO CONSOLE"];
// Initiate a request to load an ad.
[nativeAd loadAd];
}
#pragma mark - FBNativeAdDelegate implementation
- (void)nativeAdDidLoad:(FBNativeAd *)nativeAd
{
NSLog(@"Native ad was loaded, constructing native UI...");
if (self.nativeAd) {
[self.nativeAd unregisterView];
}
self.nativeAd = nativeAd;
// Create native UI using the ad metadata.
self.adCoverMediaView.delegate = self;
self.adStatusLabel.text = @"Ad loaded.";
// Render native ads onto UIView
self.adTitleLabel.text = self.nativeAd.advertiserName;
self.adBodyLabel.text = self.nativeAd.bodyText;
self.adSocialContextLabel.text = self.nativeAd.socialContext;
self.sponsoredLabel.text = self.nativeAd.sponsoredTranslation;
[self setCallToActionButton:self.nativeAd.callToAction];
// set the frame of the adBodyLabel depending on whether to show to call to action button
CGFloat gapToBorder = 9.0f;
CGFloat gapToCTAButton = 8.0f;
CGRect adBodyLabelFrame = self.adBodyLabel.frame;
if (!self.nativeAd.callToAction) {
adBodyLabelFrame.size.width = self.adCoverMediaView.bounds.size.width - gapToBorder * 2;
} else {
adBodyLabelFrame.size.width = self.adCoverMediaView.bounds.size.width - gapToCTAButton - gapToBorder - (self.adCoverMediaView.bounds.size.width - self.adCallToActionButton.frame.origin.x);
}
self.adBodyLabel.frame = adBodyLabelFrame;
NSLog(@"Register UIView for impression and click...");
// Set native ad view tags to declare roles of your views for better analysis in future
// We will be able to provide you statistics how often these views were clicked by users
// Views provided by Facebook already have appropriate tag set
self.adTitleLabel.nativeAdViewTag = FBNativeAdViewTagTitle;
self.adBodyLabel.nativeAdViewTag = FBNativeAdViewTagBody;
self.adSocialContextLabel.nativeAdViewTag = FBNativeAdViewTagSocialContext;
self.adCallToActionButton.nativeAdViewTag = FBNativeAdViewTagCallToAction;
// Specify the clickable areas. Views you were using to set ad view tags should be clickable.
NSArray *clickableViews = @[self.adIconView, self.adTitleLabel, self.adBodyLabel, self.adSocialContextLabel, self.adCallToActionButton];
[nativeAd registerViewForInteraction:self.adUIView
mediaView:self.adCoverMediaView
iconView:self.adIconView
viewController:self
clickableViews:clickableViews];
// // You may use this method if you want to have all adUIView's subviews clickable
// [nativeAd registerViewForInteraction:self.adUIView
// mediaView:self.adCoverMediaView
// iconView:self.adIconView
// viewController:self];
self.adOptionsView.hidden = NO;
self.adOptionsView.nativeAd = nativeAd;
}
- (void)nativeAd:(FBNativeAd *)nativeAd didFailWithError:(NSError *)error
{
self.adStatusLabel.text = @"Ad failed to load. Check console for details.";
NSLog(@"Native ad failed to load with error: %@", error);
}
- (void)nativeAdDidClick:(FBNativeAd *)nativeAd
{
NSLog(@"Native ad was clicked.");
}
- (void)nativeAdDidFinishHandlingClick:(FBNativeAd *)nativeAd
{
NSLog(@"Native ad did finish click handling.");
}
- (void)nativeAdWillLogImpression:(FBNativeAd *)nativeAd
{
NSLog(@"Native ad impression is being captured.");
}
#pragma mark - Menu Table View
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self menuItems].count;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == LoadNativeAdCellRowIndex) {
[self loadNativeAd];
return;
}
NSString *segue = [self segueIdentifierForIndexPath:indexPath];
[self performSegueWithIdentifier:segue sender:nil];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"menuCell" forIndexPath:indexPath];
cell.textLabel.text = [self menuItems][indexPath.row];
cell.accessoryType = [self accessoryTypeForIndexPath:indexPath];
return cell;
}
#pragma mark - Private Methods
- (UITableViewCellAccessoryType)accessoryTypeForIndexPath:(NSIndexPath *)indexPath
{
return indexPath.row == LoadNativeAdCellRowIndex ? UITableViewCellAccessoryNone : UITableViewCellAccessoryDisclosureIndicator;
}
- (NSString *)segueIdentifierForIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == LoadNativeAdCellRowIndex) { return nil; }
NSArray *segues = @[@"showTemplate",
@"showTableView",
@"showScrollView",
@"showCollectionView",
@"showNativeBanner",
@"showNativeBannerTemplate"];
return segues[indexPath.row - 1];
}
- (NSArray *)menuItems
{
return @[@"Load Native Ad",
@"Load Native Ad using Template",
@"Load Native Ad in TableView",
@"Load Native Ad in ScrollView",
@"Load Native Ad in CollectionView",
@"Load Native Banner Ad",
@"Load Native Banner Ad using Template"];
}
- (void)setCallToActionButton:(NSString *)callToAction
{
if (callToAction) {
[self.adCallToActionButton setHidden:NO];
[self.adCallToActionButton setTitle:callToAction
forState:UIControlStateNormal];
} else {
[self.adCallToActionButton setHidden:YES];
}
}
#pragma mark - Orientation
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (void)mediaViewDidLoad:(FBMediaView *)mediaView
{
}
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/NavigationController.h
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import
@interface NavigationController : UINavigationController
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/NavigationController.m
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import "NavigationController.h"
#import "NativeViewController.h"
@interface NavigationController ()
@end
@implementation NavigationController
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
UIInterfaceOrientationMask mask = UIInterfaceOrientationMaskAll;
NSArray *viewControllers = [self viewControllers];
for (UIViewController *viewController in viewControllers) {
if ([viewController isKindOfClass:[NativeViewController class]]) {
mask = UIInterfaceOrientationMaskPortrait;
break;
}
}
return mask;
}
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/RewardedVideoViewController.h
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import
@interface RewardedVideoViewController : UIViewController
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/RewardedVideoViewController.m
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import "RewardedVideoViewController.h"
#import
@interface RewardedVideoViewController ()
@property (nonatomic, strong) IBOutlet UILabel *adStatusLabel;
@property (nonatomic, strong) FBRewardedVideoAd *rewardedVideoAd;
@end
@implementation RewardedVideoViewController
- (IBAction)loadAd
{
self.adStatusLabel.text = @"Loading rewarded video ad...";
// Create the rewarded video unit with a placement ID (generate your own on the Facebook app settings).
// Use different ID for each ad placement in your app.
self.rewardedVideoAd = [[FBRewardedVideoAd alloc] initWithPlacementID:@"YOUR_PLACEMENT_ID"];
// Set a delegate to get notified on changes or when the user interact with the ad.
self.rewardedVideoAd.delegate = self;
// Initiate the request to load the ad.
[self.rewardedVideoAd loadAd];
// Optional: Set Reward data.
[self.rewardedVideoAd setRewardDataWithUserID:@"user1234" withCurrency:@"gold"];
}
- (IBAction)showAd
{
if (!self.rewardedVideoAd || !self.rewardedVideoAd.isAdValid)
{
// Ad not ready to present.
self.adStatusLabel.text = @"Ad not loaded. Click load to request an ad.";
} else {
self.adStatusLabel.text = @"1. Tap 'Load Ad'\n2. Once ad loads, tap 'Show!' to see the ad";
// Ad is ready, present it!
[self.rewardedVideoAd showAdFromRootViewController:self animated:NO];
}
}
#pragma mark - FBRewardedVideoAdDelegate implementation
- (void)rewardedVideoAdDidLoad:(FBRewardedVideoAd *)rewardedVideoAd
{
NSLog(@"Rewarded video ad was loaded. Can present now.");
self.adStatusLabel.text = @"Ad loaded. Click show to present!";
}
- (void)rewardedVideoAd:(FBRewardedVideoAd *)rewardedVideoAd didFailWithError:(NSError *)error
{
NSLog(@"Rewarded video failed to load with error: %@", error.description);
self.adStatusLabel.text = [NSString stringWithFormat:@"Rewarded Video ad failed to load. %@", error.localizedDescription];
}
- (void)rewardedVideoAdDidClick:(FBRewardedVideoAd *)rewardedVideoAd
{
NSLog(@"Rewarded video was clicked.");
}
- (void)rewardedVideoAdDidClose:(FBRewardedVideoAd *)rewardedVideoAd
{
NSLog(@"Rewarded video closed.");
}
- (void)rewardedVideoAdWillClose:(FBRewardedVideoAd *)rewardedVideoAd
{
NSLog(@"Rewarded video will close.");
}
- (void)rewardedVideoAdWillLogImpression:(FBRewardedVideoAd *)rewardedVideoAd
{
NSLog(@"Rewarded video impression is being captured.");
}
- (void)rewardedVideoAdVideoComplete:(FBRewardedVideoAd *)rewardedVideoAd
{
NSLog(@"Rewarded video was completed successfully.");
}
- (void)rewardedVideoAdServerRewardDidSucceed:(FBRewardedVideoAd *)rewardedVideoAd
{
NSLog(@"Rewarded video server side reward succeeded.");
//optional, cleanup
self.rewardedVideoAd = nil;
}
- (void)rewardedVideoAdServerRewardDidFail:(FBRewardedVideoAd *)rewardedVideoAd
{
NSLog(@"Rewarded video server side reward failed.");
//optional, cleanup
self.rewardedVideoAd = nil;
}
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/ScrollViewController.h
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import
@interface ScrollViewController : UIViewController
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/ScrollViewController.m
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import "ScrollViewController.h"
#import
@interface ScrollViewController ()
@property (nonatomic, strong) IBOutlet UIView *containerView;
@property (nonatomic, strong) IBOutlet UIActivityIndicatorView *activityIndicator;
@property (nonatomic, strong) FBNativeAdsManager *manager;
@property (nonatomic, weak) FBNativeAdScrollView *scrollView;
@end
@implementation ScrollViewController
- (void)viewDidLoad
{
[super viewDidLoad];
FBNativeAdsManager *manager = [[FBNativeAdsManager alloc] initWithPlacementID:@"YOUR_PLACEMENT_ID" forNumAdsRequested:5];
manager.delegate = self;
manager.mediaCachePolicy = FBNativeAdsCachePolicyAll;
[manager loadAds];
self.manager = manager;
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.scrollView.frame = self.containerView.bounds;
}
- (IBAction)refresh:(id)sender
{
[self.manager loadAds];
if (self.scrollView) {
[self.scrollView removeFromSuperview];
self.scrollView = nil;
}
[self.activityIndicator startAnimating];
}
#pragma mark FBNativeAdDelegate
- (void)nativeAdDidClick:(FBNativeAd *)nativeAd
{
NSLog(@"Native ad was clicked.");
}
- (void)nativeAdDidFinishHandlingClick:(FBNativeAd *)nativeAd
{
NSLog(@"Native ad did finish click handling.");
}
- (void)nativeAdWillLogImpression:(FBNativeAd *)nativeAd
{
NSLog(@"Native ad impression is being captured.");
}
#pragma mark FBNativeAdsManagerDelegate
- (void)nativeAdsLoaded
{
[self.activityIndicator stopAnimating];
NSLog(@"Native ads loaded, constructing native UI...");
if (self.scrollView) {
[self.scrollView removeFromSuperview];
self.scrollView = nil;
}
FBNativeAdScrollView *scrollView = [[FBNativeAdScrollView alloc] initWithNativeAdsManager:self.manager withType:FBNativeAdViewTypeGenericHeight300];
scrollView.delegate = self;
scrollView.frame = self.containerView.bounds;
[self.containerView addSubview:scrollView];
self.scrollView = scrollView;
}
- (void)nativeAdsFailedToLoadWithError:(NSError *)error
{
[self.activityIndicator stopAnimating];
NSLog(@"Native ads failed to load with error: %@", error);
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Native ad failed to load"
message:@"Check console for more details"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil];
[alertController addAction:cancel];
[self presentViewController:alertController animated:YES completion:nil];
}
#pragma mark - Orientation
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/SettingsLogLevelCell.h
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import
@interface SettingsLogLevelCell : UITableViewCell
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/SettingsLogLevelCell.m
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import "SettingsLogLevelCell.h"
#import
@interface SettingsLogLevelCell ()
@property (nonatomic, strong) IBOutlet UIStepper *stepper;
@property (nonatomic, strong) IBOutlet UILabel *logLevelLabel;
@property (nonatomic, copy) void (^onLogLevelChange)(FBAdLogLevel logLevel);
@end
@implementation SettingsLogLevelCell
- (void)awakeFromNib
{
[super awakeFromNib];
self.logLevelLabel.text = [self stringFromLogLevel:[FBAdSettings getLogLevel]];
self.stepper.value = [FBAdSettings getLogLevel];
}
- (IBAction)logValueDidChange:(UIStepper *)sender
{
[FBAdSettings setLogLevel:sender.value];
self.logLevelLabel.text = [self stringFromLogLevel:[FBAdSettings getLogLevel]];
if (self.onLogLevelChange) {
self.onLogLevelChange([FBAdSettings getLogLevel]);
}
}
- (NSString *)stringFromLogLevel:(FBAdLogLevel)logLevel
{
NSString *logLevelString = nil;
switch (logLevel) {
case FBAdLogLevelNone:
logLevelString = @"None";
break;
case FBAdLogLevelNotification:
logLevelString = @"Notification";
break;
case FBAdLogLevelError:
logLevelString = @"Error";
break;
case FBAdLogLevelWarning:
logLevelString = @"Warning";
break;
case FBAdLogLevelLog:
logLevelString = @"Log";
break;
case FBAdLogLevelDebug:
logLevelString = @"Debug";
break;
case FBAdLogLevelVerbose:
logLevelString = @"Verbose";
break;
default:
logLevelString = @"Unknown";
break;
}
return logLevelString;
}
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/SettingsSandboxCell.h
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import
@interface SettingsSandboxCell : UITableViewCell
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/SettingsSandboxCell.m
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import "SettingsSandboxCell.h"
#import
@interface SettingsSandboxCell ()
@property (nonatomic, strong) IBOutlet UITextField *sandboxTextField;
@end
@implementation SettingsSandboxCell
- (void)awakeFromNib
{
[super awakeFromNib];
self.sandboxTextField.text = [FBAdSettings urlPrefix];
self.sandboxTextField.delegate = self;
}
#pragma mark - Text field delegate
- (void)textFieldDidEndEditing:(UITextField *)textField
{
[FBAdSettings setUrlPrefix:textField.text];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/SettingsTableViewController.h
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import
@interface SettingsTableViewController : UITableViewController
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/SettingsTableViewController.m
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import "SettingsTableViewController.h"
#import
#import "SettingsTestModeCell.h"
@interface SettingsTableViewController ()
@property (nonatomic, strong, readonly) NSArray *reuseIdentifiers;
@end
@implementation SettingsTableViewController
@synthesize reuseIdentifiers = _reuseIdentifiers;
#pragma mark - Private
- (NSArray *)reuseIdentifiers
{
if (nil == _reuseIdentifiers) {
NSMutableArray *identifiers = [@[@"SettingsSandboxCell",
@"SettingsLogLevelCell",
@"SettingsTestModeCell",
@"SettingsTestAdCell"] mutableCopy];
if ([self isDebugLogsViewControllerAvailable]) {
[identifiers insertObject:@"SettingsDebugEventCell" atIndex:2];
}
_reuseIdentifiers = [identifiers copy];
}
return _reuseIdentifiers;
}
- (NSString *)reuseIdentifierForIndexPath:(NSIndexPath *)indexPath
{
return self.reuseIdentifiers[indexPath.row];
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (BOOL)isDebugLogsViewControllerAvailable
{
return NSClassFromString(@"DebugLogsViewController") != nil;
}
#pragma mark - UITableViewDataSource implementation
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger numberOfRows = [FBAdSettings isTestMode] ? 4 : 3;
if ([self isDebugLogsViewControllerAvailable]) {
numberOfRows++;
}
return numberOfRows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *reuseId = [self reuseIdentifierForIndexPath:indexPath];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseId
forIndexPath:indexPath];
if ([reuseId isEqualToString:@"SettingsTestModeCell"]) {
((SettingsTestModeCell *)cell).onTestModeChange = ^(BOOL enabled) {
[self.tableView reloadData];
};
}
return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [NSString stringWithFormat:@"SDK Version %@", FB_AD_SDK_VERSION];
}
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/SettingsTestAdCell.h
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import
@interface SettingsTestAdCell : UITableViewCell
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/SettingsTestAdCell.m
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import "SettingsTestAdCell.h"
#import
@interface SettingsTestAdCell ()
@property (nonatomic, strong) IBOutlet UITextField *testAdTextField;
@property (nonatomic, strong) UIPickerView *pickerView;
@property (nonatomic, copy) NSDictionary *testsAds;
@end
@implementation SettingsTestAdCell
- (void)awakeFromNib
{
[super awakeFromNib];
self.pickerView.delegate = self;
self.testsAds = @{
@(FBAdTestAdType_Default) : @"default",
@(FBAdTestAdType_Img_16_9_App_Install) : @"image_install",
@(FBAdTestAdType_Img_16_9_Link) : @"image_link",
@(FBAdTestAdType_Vid_HD_16_9_46s_App_Install) : @"video_16x9_46s_install",
@(FBAdTestAdType_Vid_HD_16_9_46s_Link) : @"video_16x9_46s_link",
@(FBAdTestAdType_Vid_HD_16_9_15s_App_Install) : @"video_16x9_15s_install",
@(FBAdTestAdType_Vid_HD_16_9_15s_Link) : @"video_16x9_15s_link",
@(FBAdTestAdType_Vid_HD_9_16_39s_App_Install) : @"video_9x16_39s_install",
@(FBAdTestAdType_Vid_HD_9_16_39s_Link) : @"video_9x16_39s_link",
@(FBAdTestAdType_Carousel_Img_Square_App_Install) : @"carousel_install",
@(FBAdTestAdType_Carousel_Img_Square_Link) : @"carousel_link"
};
[self setupPickerView];
[self setupAdTextField];
}
- (void)setupPickerView
{
self.pickerView = [UIPickerView new];
self.pickerView.delegate = self;
self.pickerView.dataSource = self;
[self.pickerView selectRow:FBAdSettings.testAdType inComponent:0 animated:NO];
}
- (UIToolbar *)toolbar
{
UIToolbar* toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth([UIScreen mainScreen].bounds), 44)];
UIBarButtonItem *flex = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil action:nil];
UIBarButtonItem *done = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(done:)];
toolbar.items = @[flex, done];
[toolbar sizeToFit];
return toolbar;
}
- (void)setupAdTextField
{
self.testAdTextField.inputView = self.pickerView;
self.testAdTextField.inputAccessoryView = [self toolbar];
self.testAdTextField.text = self.testsAds[@(FBAdSettings.testAdType)];
}
- (void)done:(id)sender
{
[self.testAdTextField resignFirstResponder];
}
#pragma mark - Picker view delegate
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
NSString *title = self.testsAds[@(row)];
if (!title) {
title = @"None";
}
return title;
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component
{
return self.testsAds.count;
}
- (void)pickerView:(UIPickerView *)thePickerView
didSelectRow:(NSInteger)row
inComponent:(NSInteger)component
{
self.testAdTextField.text = self.testsAds[@(row)] ? self.testsAds[@(row)] : @"None";
FBAdSettings.testAdType = row;
}
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/SettingsTestModeCell.h
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import
@interface SettingsTestModeCell : UITableViewCell
@property (nonatomic, copy) void (^onTestModeChange)(BOOL enabled);
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/SettingsTestModeCell.m
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import "SettingsTestModeCell.h"
#import
@interface SettingsTestModeCell ()
@property (nonatomic, strong) IBOutlet UISwitch *switcher;
@end
@implementation SettingsTestModeCell
- (void)awakeFromNib
{
[super awakeFromNib];
[self.switcher setOn:[FBAdSettings isTestMode]];
}
- (IBAction)switcherValueChanged:(UISwitch *)sender
{
if ([sender isOn]) {
[FBAdSettings addTestDevice:[FBAdSettings testDeviceHash]];
} else {
[FBAdSettings clearTestDevice:[FBAdSettings testDeviceHash]];
}
if (self.onTestModeChange) {
self.onTestModeChange([FBAdSettings isTestMode]);
}
}
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/TableViewController.h
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import
@interface TableViewController : UIViewController
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/TableViewController.m
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import "TableViewController.h"
#import
static NSInteger const kRowStrideForAdCell = 9;
static NSString *const kDefaultCellIdentifier = @"kDefaultCellIdentifier";
@interface TableViewController ()
@property (nonatomic, strong) IBOutlet UITableView *tableView;
@property (nonatomic, strong) IBOutlet UIActivityIndicatorView *activityIndicator;
@property (nonatomic, strong) FBNativeAdsManager *adsManager;
@property (nonatomic, strong) FBNativeAdTableViewCellProvider *cellProvider;
@property (nonatomic, strong) NSMutableArray *tableViewContentArray;
@property (nonatomic, assign) BOOL adCellsCreated;
@end
@implementation TableViewController
#pragma mark - Lazy Loading
- (NSMutableArray *)tableViewContentArray
{
if (!_tableViewContentArray) {
_tableViewContentArray = [NSMutableArray array];
for (NSUInteger i = 0; i < 45; i++) {
[_tableViewContentArray addObject:[NSString stringWithFormat:@"TableView Cell #%lu", (unsigned long)(i + 1)]];
}
}
return _tableViewContentArray;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:kDefaultCellIdentifier];
[self loadNativeAd];
}
- (IBAction)refresh:(id)sender
{
[self loadNativeAd];
}
- (void)loadNativeAd
{
[self.activityIndicator startAnimating];
if (!self.adsManager) {
// Create a native ad manager with a unique placement ID (generate your own on the Facebook app settings)
// and how many ads you would like to create. Note that you may get fewer ads than you ask for.
// Use different ID for each ad placement in your app.
self.adsManager = [[FBNativeAdsManager alloc] initWithPlacementID:@"YOUR_PLACEMENT_ID"
forNumAdsRequested:5];
// Set a delegate to get notified when the ads are loaded.
self.adsManager.delegate = self;
// Configure native ad manager to wait to call nativeAdsLoaded until all ad assets are loaded
self.adsManager.mediaCachePolicy = FBNativeAdsCachePolicyAll;
// When testing on a device, add its hashed ID to force test ads.
// The hash ID is printed to console when running on a device.
// [FBAdSettings addTestDevice:@"THE HASHED ID AS PRINTED TO CONSOLE"];
}
// Load some ads
[self.adsManager loadAds];
}
#pragma mark FBNativeAdsManagerDelegate implementation
- (void)nativeAdsLoaded
{
NSLog(@"Native ad was loaded, constructing native UI...");
// After the native ads have loaded we create the native ad cell provider and let it take over
FBNativeAdsManager *manager = self.adsManager;
self.adsManager.delegate = nil;
self.adsManager = nil;
// The native ad cell provider operates over a loaded ads manager and can create table cells with native
// ad templates in them as well as help with the math to have a consistent distribution of ads within a table.
FBNativeAdTableViewCellProvider *cellProvider = [[FBNativeAdTableViewCellProvider alloc] initWithManager:manager forType:FBNativeAdViewTypeGenericHeight300];
self.cellProvider = cellProvider;
self.cellProvider.delegate = self;
[self.tableView reloadData];
[self.activityIndicator stopAnimating];
}
- (void)nativeAdsFailedToLoadWithError:(NSError *)error
{
NSLog(@"Native ad failed to load with error: %@", error);
[self.activityIndicator stopAnimating];
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Native ad failed to load"
message:@"Check console for more details"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil];
[alertController addAction:cancel];
[self presentViewController:alertController animated:YES completion:nil];
}
#pragma mark FBNativeAdDelegate
- (void)nativeAdDidClick:(FBNativeAd *)nativeAd
{
NSLog(@"Native ad was clicked.");
}
- (void)nativeAdDidFinishHandlingClick:(FBNativeAd *)nativeAd
{
NSLog(@"Native ad did finish click handling.");
}
- (void)nativeAdWillLogImpression:(FBNativeAd *)nativeAd
{
NSLog(@"Native ad impression is being captured.");
}
#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// In this example the ads are evenly distributed within the table every kRowStrideForAdCell-th cell.
NSUInteger count = [self.tableViewContentArray count];
count = [self.cellProvider adjustCount:count forStride:kRowStrideForAdCell] ?: count;
return count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// For ad cells just as the ad cell provider, for normal cells do whatever you would do.
if ([self.cellProvider isAdCellAtIndexPath:indexPath forStride:kRowStrideForAdCell]) {
return [self.cellProvider tableView:tableView cellForRowAtIndexPath:indexPath];
} else {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kDefaultCellIdentifier forIndexPath:indexPath];
// In this example we need to adjust the index back to the domain of the data.
indexPath = [self.cellProvider adjustNonAdCellIndexPath:indexPath forStride:kRowStrideForAdCell] ?: indexPath;
cell.textLabel.text = [self.tableViewContentArray objectAtIndex:indexPath.row];
return cell;
}
}
#pragma mark - UITableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// The ad cell provider knows the height of ad cells based on its configuration
if ([self.cellProvider isAdCellAtIndexPath:indexPath forStride:kRowStrideForAdCell]) {
return [self.cellProvider tableView:tableView heightForRowAtIndexPath:indexPath];
} else {
return 80;
}
}
#pragma mark - Orientation
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
@end
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample/main.m
================================================
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#import
#import "AppDelegate.h"
int main(int argc, char * argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
58D92D5C18C7A6B10090E7E2 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 58D92D5A18C7A6B10090E7E2 /* AppDelegate.m */; };
58D92D5D18C7A6B10090E7E2 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 58D92D5B18C7A6B10090E7E2 /* Images.xcassets */; };
58D92D6C18C7A6D00090E7E2 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 58D92D6818C7A6D00090E7E2 /* main.m */; };
7DB6D5831D2EF6020095B2E3 /* CollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DB6D5811D2EF6020095B2E3 /* CollectionViewController.m */; };
821E0AB21FC5923300F6C1DC /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 821E0AB11FC5923200F6C1DC /* LaunchScreen.storyboard */; };
825B69E321400B0900C130F6 /* NativeAdTemplateViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 825B69E121400B0900C130F6 /* NativeAdTemplateViewController.m */; };
825B69E421400B0900C130F6 /* NativeBannerAdTemplateViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 825B69E221400B0900C130F6 /* NativeBannerAdTemplateViewController.m */; };
825B76321FE00ED4002E9410 /* MediumRectViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 825B76261FE00ED2002E9410 /* MediumRectViewController.m */; };
825B76331FE00ED4002E9410 /* RewardedVideoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 825B762A1FE00ED3002E9410 /* RewardedVideoViewController.m */; };
825B76341FE00ED4002E9410 /* InstreamViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 825B762B1FE00ED3002E9410 /* InstreamViewController.m */; };
825B76351FE00ED4002E9410 /* InterstitialViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 825B762D1FE00ED3002E9410 /* InterstitialViewController.m */; };
825B76361FE00ED4002E9410 /* BannerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 825B762E1FE00ED3002E9410 /* BannerViewController.m */; };
825B76371FE00ED4002E9410 /* MenuTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 825B762F1FE00ED4002E9410 /* MenuTableViewController.m */; };
829C8D1A1FBF35BE00B784C1 /* SettingsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 829C8D0E1FBF35BD00B784C1 /* SettingsTableViewController.m */; };
829C8D1B1FBF35BE00B784C1 /* AdUnitsSampleStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 829C8D0F1FBF35BD00B784C1 /* AdUnitsSampleStoryboard.storyboard */; };
829C8D1C1FBF35BE00B784C1 /* SettingsTestAdCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 829C8D131FBF35BD00B784C1 /* SettingsTestAdCell.m */; };
829C8D1D1FBF35BE00B784C1 /* SettingsSandboxCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 829C8D141FBF35BD00B784C1 /* SettingsSandboxCell.m */; };
829C8D1E1FBF35BE00B784C1 /* NavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 829C8D151FBF35BD00B784C1 /* NavigationController.m */; };
829C8D1F1FBF35BE00B784C1 /* SettingsTestModeCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 829C8D181FBF35BE00B784C1 /* SettingsTestModeCell.m */; };
829C8D201FBF35BE00B784C1 /* SettingsLogLevelCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 829C8D191FBF35BE00B784C1 /* SettingsLogLevelCell.m */; };
90E89CD41A99AE95005D3430 /* ScrollViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 90E89CD21A99AE95005D3430 /* ScrollViewController.m */; };
9981CCDC1F696FF100935A60 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 9981CCDB1F696FF100935A60 /* libc++.tbd */; };
9C86FDA720F8CF4C00077F54 /* NativeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C86FDA520F8CF4C00077F54 /* NativeViewController.m */; };
9CF70F3A207E0C6D002D30D2 /* NativeBannerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF70F39207E0C6D002D30D2 /* NativeBannerViewController.m */; };
EE23E6E8198B0B0600215C81 /* TableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EE23E6E6198B0B0600215C81 /* TableViewController.m */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
B87B1D2D1DDE5CA6004828BC /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
58D92D1E18C7A6100090E7E2 /* AdUnitsSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AdUnitsSample.app; sourceTree = BUILT_PRODUCTS_DIR; };
58D92D5918C7A6B10090E7E2 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
58D92D5A18C7A6B10090E7E2 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
58D92D5B18C7A6B10090E7E2 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
58D92D6618C7A6D00090E7E2 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
58D92D6718C7A6D00090E7E2 /* InfoPlist.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; path = InfoPlist.strings; sourceTree = ""; };
58D92D6818C7A6D00090E7E2 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
58D92D6918C7A6D00090E7E2 /* AdUnitsSample-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AdUnitsSample-Prefix.pch"; sourceTree = ""; };
7DB6D5801D2EF6020095B2E3 /* CollectionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CollectionViewController.h; sourceTree = ""; };
7DB6D5811D2EF6020095B2E3 /* CollectionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CollectionViewController.m; sourceTree = ""; };
821E0AB11FC5923200F6C1DC /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; };
825B69DF21400B0800C130F6 /* NativeBannerAdTemplateViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeBannerAdTemplateViewController.h; sourceTree = ""; };
825B69E021400B0900C130F6 /* NativeAdTemplateViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeAdTemplateViewController.h; sourceTree = ""; };
825B69E121400B0900C130F6 /* NativeAdTemplateViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NativeAdTemplateViewController.m; sourceTree = ""; };
825B69E221400B0900C130F6 /* NativeBannerAdTemplateViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NativeBannerAdTemplateViewController.m; sourceTree = ""; };
825B76261FE00ED2002E9410 /* MediumRectViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MediumRectViewController.m; sourceTree = ""; };
825B76271FE00ED2002E9410 /* InterstitialViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InterstitialViewController.h; sourceTree = ""; };
825B76281FE00ED2002E9410 /* BannerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BannerViewController.h; sourceTree = ""; };
825B76291FE00ED2002E9410 /* RewardedVideoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RewardedVideoViewController.h; sourceTree = ""; };
825B762A1FE00ED3002E9410 /* RewardedVideoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RewardedVideoViewController.m; sourceTree = ""; };
825B762B1FE00ED3002E9410 /* InstreamViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InstreamViewController.m; sourceTree = ""; };
825B762C1FE00ED3002E9410 /* InstreamViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InstreamViewController.h; sourceTree = ""; };
825B762D1FE00ED3002E9410 /* InterstitialViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InterstitialViewController.m; sourceTree = ""; };
825B762E1FE00ED3002E9410 /* BannerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BannerViewController.m; sourceTree = ""; };
825B762F1FE00ED4002E9410 /* MenuTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MenuTableViewController.m; sourceTree = ""; };
825B76301FE00ED4002E9410 /* MediumRectViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediumRectViewController.h; sourceTree = ""; };
825B76311FE00ED4002E9410 /* MenuTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MenuTableViewController.h; sourceTree = ""; };
829C8D0D1FBF35BD00B784C1 /* SettingsLogLevelCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsLogLevelCell.h; sourceTree = ""; };
829C8D0E1FBF35BD00B784C1 /* SettingsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsTableViewController.m; sourceTree = ""; };
829C8D0F1FBF35BD00B784C1 /* AdUnitsSampleStoryboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = AdUnitsSampleStoryboard.storyboard; sourceTree = ""; };
829C8D101FBF35BD00B784C1 /* SettingsSandboxCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsSandboxCell.h; sourceTree = ""; };
829C8D111FBF35BD00B784C1 /* SettingsTestAdCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsTestAdCell.h; sourceTree = ""; };
829C8D121FBF35BD00B784C1 /* NavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NavigationController.h; sourceTree = ""; };
829C8D131FBF35BD00B784C1 /* SettingsTestAdCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsTestAdCell.m; sourceTree = ""; };
829C8D141FBF35BD00B784C1 /* SettingsSandboxCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsSandboxCell.m; sourceTree = ""; };
829C8D151FBF35BD00B784C1 /* NavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NavigationController.m; sourceTree = ""; };
829C8D161FBF35BE00B784C1 /* SettingsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsTableViewController.h; sourceTree = ""; };
829C8D171FBF35BE00B784C1 /* SettingsTestModeCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsTestModeCell.h; sourceTree = ""; };
829C8D181FBF35BE00B784C1 /* SettingsTestModeCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsTestModeCell.m; sourceTree = ""; };
829C8D191FBF35BE00B784C1 /* SettingsLogLevelCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsLogLevelCell.m; sourceTree = ""; };
90E89CD11A99AE95005D3430 /* ScrollViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollViewController.h; sourceTree = ""; };
90E89CD21A99AE95005D3430 /* ScrollViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ScrollViewController.m; sourceTree = ""; };
9981CCDB1F696FF100935A60 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
9C86FDA520F8CF4C00077F54 /* NativeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NativeViewController.m; sourceTree = ""; };
9C86FDA620F8CF4C00077F54 /* NativeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeViewController.h; sourceTree = ""; };
9CF70F38207E0C6D002D30D2 /* NativeBannerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeBannerViewController.h; sourceTree = ""; };
9CF70F39207E0C6D002D30D2 /* NativeBannerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NativeBannerViewController.m; sourceTree = ""; };
B81CBE1E1DC7F21400651A52 /* AdUnitsSample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AdUnitsSample.entitlements; sourceTree = ""; };
EE23E6E5198B0B0600215C81 /* TableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TableViewController.h; sourceTree = ""; };
EE23E6E6198B0B0600215C81 /* TableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TableViewController.m; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
58D92D1B18C7A6100090E7E2 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9981CCDC1F696FF100935A60 /* libc++.tbd in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
58D92D1518C7A6100090E7E2 = {
isa = PBXGroup;
children = (
58D92D2718C7A6100090E7E2 /* AdUnitsSample */,
58D92D2018C7A6100090E7E2 /* Frameworks */,
58D92D1F18C7A6100090E7E2 /* Products */,
);
indentWidth = 4;
sourceTree = "";
tabWidth = 4;
};
58D92D1F18C7A6100090E7E2 /* Products */ = {
isa = PBXGroup;
children = (
58D92D1E18C7A6100090E7E2 /* AdUnitsSample.app */,
);
name = Products;
sourceTree = "";
};
58D92D2018C7A6100090E7E2 /* Frameworks */ = {
isa = PBXGroup;
children = (
9981CCDB1F696FF100935A60 /* libc++.tbd */,
);
name = Frameworks;
sourceTree = "";
};
58D92D2718C7A6100090E7E2 /* AdUnitsSample */ = {
isa = PBXGroup;
children = (
58D92D5918C7A6B10090E7E2 /* AppDelegate.h */,
58D92D5A18C7A6B10090E7E2 /* AppDelegate.m */,
9C6C3B9F20F8C2C800149EF6 /* FormatSamples */,
9C6C3B9E20F8C2A200149EF6 /* SettingsMenu */,
9C41349120F8C1D70032CC52 /* Resources */,
58D92D2818C7A6100090E7E2 /* Supporting Files */,
);
path = AdUnitsSample;
sourceTree = "";
};
58D92D2818C7A6100090E7E2 /* Supporting Files */ = {
isa = PBXGroup;
children = (
58D92D6618C7A6D00090E7E2 /* Info.plist */,
58D92D6718C7A6D00090E7E2 /* InfoPlist.strings */,
58D92D6818C7A6D00090E7E2 /* main.m */,
58D92D6918C7A6D00090E7E2 /* AdUnitsSample-Prefix.pch */,
);
name = "Supporting Files";
sourceTree = "";
};
9C41349120F8C1D70032CC52 /* Resources */ = {
isa = PBXGroup;
children = (
821E0AB11FC5923200F6C1DC /* LaunchScreen.storyboard */,
829C8D0F1FBF35BD00B784C1 /* AdUnitsSampleStoryboard.storyboard */,
58D92D5B18C7A6B10090E7E2 /* Images.xcassets */,
B81CBE1E1DC7F21400651A52 /* AdUnitsSample.entitlements */,
);
name = Resources;
sourceTree = "";
};
9C6C3B9E20F8C2A200149EF6 /* SettingsMenu */ = {
isa = PBXGroup;
children = (
829C8D0D1FBF35BD00B784C1 /* SettingsLogLevelCell.h */,
829C8D191FBF35BE00B784C1 /* SettingsLogLevelCell.m */,
829C8D101FBF35BD00B784C1 /* SettingsSandboxCell.h */,
829C8D141FBF35BD00B784C1 /* SettingsSandboxCell.m */,
829C8D161FBF35BE00B784C1 /* SettingsTableViewController.h */,
829C8D0E1FBF35BD00B784C1 /* SettingsTableViewController.m */,
829C8D111FBF35BD00B784C1 /* SettingsTestAdCell.h */,
829C8D131FBF35BD00B784C1 /* SettingsTestAdCell.m */,
829C8D171FBF35BE00B784C1 /* SettingsTestModeCell.h */,
829C8D181FBF35BE00B784C1 /* SettingsTestModeCell.m */,
825B76311FE00ED4002E9410 /* MenuTableViewController.h */,
825B762F1FE00ED4002E9410 /* MenuTableViewController.m */,
829C8D121FBF35BD00B784C1 /* NavigationController.h */,
829C8D151FBF35BD00B784C1 /* NavigationController.m */,
);
name = SettingsMenu;
sourceTree = "";
};
9C6C3B9F20F8C2C800149EF6 /* FormatSamples */ = {
isa = PBXGroup;
children = (
825B69E021400B0900C130F6 /* NativeAdTemplateViewController.h */,
825B69E121400B0900C130F6 /* NativeAdTemplateViewController.m */,
825B69DF21400B0800C130F6 /* NativeBannerAdTemplateViewController.h */,
825B69E221400B0900C130F6 /* NativeBannerAdTemplateViewController.m */,
825B76281FE00ED2002E9410 /* BannerViewController.h */,
825B762E1FE00ED3002E9410 /* BannerViewController.m */,
9CF70F38207E0C6D002D30D2 /* NativeBannerViewController.h */,
9CF70F39207E0C6D002D30D2 /* NativeBannerViewController.m */,
825B762C1FE00ED3002E9410 /* InstreamViewController.h */,
825B762B1FE00ED3002E9410 /* InstreamViewController.m */,
825B76271FE00ED2002E9410 /* InterstitialViewController.h */,
825B762D1FE00ED3002E9410 /* InterstitialViewController.m */,
825B76301FE00ED4002E9410 /* MediumRectViewController.h */,
825B76261FE00ED2002E9410 /* MediumRectViewController.m */,
825B76291FE00ED2002E9410 /* RewardedVideoViewController.h */,
825B762A1FE00ED3002E9410 /* RewardedVideoViewController.m */,
EE23E6E5198B0B0600215C81 /* TableViewController.h */,
EE23E6E6198B0B0600215C81 /* TableViewController.m */,
90E89CD11A99AE95005D3430 /* ScrollViewController.h */,
90E89CD21A99AE95005D3430 /* ScrollViewController.m */,
7DB6D5801D2EF6020095B2E3 /* CollectionViewController.h */,
7DB6D5811D2EF6020095B2E3 /* CollectionViewController.m */,
9C86FDA620F8CF4C00077F54 /* NativeViewController.h */,
9C86FDA520F8CF4C00077F54 /* NativeViewController.m */,
);
name = FormatSamples;
sourceTree = "";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
58D92D1D18C7A6100090E7E2 /* AdUnitsSample */ = {
isa = PBXNativeTarget;
buildConfigurationList = 58D92D5318C7A6110090E7E2 /* Build configuration list for PBXNativeTarget "AdUnitsSample" */;
buildPhases = (
58D92D1A18C7A6100090E7E2 /* Sources */,
58D92D1C18C7A6100090E7E2 /* Resources */,
58D92D1B18C7A6100090E7E2 /* Frameworks */,
B87B1D2D1DDE5CA6004828BC /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = AdUnitsSample;
productName = AdUnitsSample;
productReference = 58D92D1E18C7A6100090E7E2 /* AdUnitsSample.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
58D92D1618C7A6100090E7E2 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0700;
ORGANIZATIONNAME = Facebook;
TargetAttributes = {
58D92D1D18C7A6100090E7E2 = {
ProvisioningStyle = Automatic;
SystemCapabilities = {
};
};
};
};
buildConfigurationList = 58D92D1918C7A6100090E7E2 /* Build configuration list for PBXProject "AdUnitsSample" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 58D92D1518C7A6100090E7E2;
productRefGroup = 58D92D1F18C7A6100090E7E2 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
58D92D1D18C7A6100090E7E2 /* AdUnitsSample */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
58D92D1C18C7A6100090E7E2 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
821E0AB21FC5923300F6C1DC /* LaunchScreen.storyboard in Resources */,
829C8D1B1FBF35BE00B784C1 /* AdUnitsSampleStoryboard.storyboard in Resources */,
58D92D5D18C7A6B10090E7E2 /* Images.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
58D92D1A18C7A6100090E7E2 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
9C86FDA720F8CF4C00077F54 /* NativeViewController.m in Sources */,
829C8D1A1FBF35BE00B784C1 /* SettingsTableViewController.m in Sources */,
829C8D1F1FBF35BE00B784C1 /* SettingsTestModeCell.m in Sources */,
825B76351FE00ED4002E9410 /* InterstitialViewController.m in Sources */,
825B69E321400B0900C130F6 /* NativeAdTemplateViewController.m in Sources */,
825B76331FE00ED4002E9410 /* RewardedVideoViewController.m in Sources */,
825B76361FE00ED4002E9410 /* BannerViewController.m in Sources */,
58D92D5C18C7A6B10090E7E2 /* AppDelegate.m in Sources */,
829C8D1D1FBF35BE00B784C1 /* SettingsSandboxCell.m in Sources */,
829C8D201FBF35BE00B784C1 /* SettingsLogLevelCell.m in Sources */,
7DB6D5831D2EF6020095B2E3 /* CollectionViewController.m in Sources */,
58D92D6C18C7A6D00090E7E2 /* main.m in Sources */,
90E89CD41A99AE95005D3430 /* ScrollViewController.m in Sources */,
829C8D1C1FBF35BE00B784C1 /* SettingsTestAdCell.m in Sources */,
825B69E421400B0900C130F6 /* NativeBannerAdTemplateViewController.m in Sources */,
825B76321FE00ED4002E9410 /* MediumRectViewController.m in Sources */,
829C8D1E1FBF35BE00B784C1 /* NavigationController.m in Sources */,
EE23E6E8198B0B0600215C81 /* TableViewController.m in Sources */,
825B76371FE00ED4002E9410 /* MenuTableViewController.m in Sources */,
825B76341FE00ED4002E9410 /* InstreamViewController.m in Sources */,
9CF70F3A207E0C6D002D30D2 /* NativeBannerViewController.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
58D92D5118C7A6110090E7E2 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = NO;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
58D92D5218C7A6110090E7E2 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = NO;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
ENABLE_NS_ASSERTIONS = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
58D92D5418C7A6110090E7E2 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = AdUnitsSample/AdUnitsSample.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = "";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(SRCROOT)/../../..//Static",
);
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "AdUnitsSample/AdUnitsSample-Prefix.pch";
HEADER_SEARCH_PATHS = "";
INFOPLIST_FILE = AdUnitsSample/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.audiencenetwork.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "8d2650e7-a3c0-4b70-a158-1df747083300";
PROVISIONING_PROFILE_SPECIFIER = "";
WRAPPER_EXTENSION = app;
};
name = Debug;
};
58D92D5518C7A6110090E7E2 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_OBJC_ARC = YES;
CODE_SIGN_ENTITLEMENTS = AdUnitsSample/AdUnitsSample.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = "";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(SRCROOT)/../../..//Static",
);
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "AdUnitsSample/AdUnitsSample-Prefix.pch";
HEADER_SEARCH_PATHS = "";
INFOPLIST_FILE = AdUnitsSample/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.audiencenetwork.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "e7603b38-718e-4f37-98d5-3a5668531043";
PROVISIONING_PROFILE_SPECIFIER = "";
WRAPPER_EXTENSION = app;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
58D92D1918C7A6100090E7E2 /* Build configuration list for PBXProject "AdUnitsSample" */ = {
isa = XCConfigurationList;
buildConfigurations = (
58D92D5118C7A6110090E7E2 /* Debug */,
58D92D5218C7A6110090E7E2 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
58D92D5318C7A6110090E7E2 /* Build configuration list for PBXNativeTarget "AdUnitsSample" */ = {
isa = XCConfigurationList;
buildConfigurations = (
58D92D5418C7A6110090E7E2 /* Debug */,
58D92D5518C7A6110090E7E2 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 58D92D1618C7A6100090E7E2 /* Project object */;
}
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
IDEDidComputeMac32BitWarning
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample.xcodeproj/xcshareddata/xcschemes/AdUnitsSample.xcscheme
================================================
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample.xcworkspace/contents.xcworkspacedata
================================================
================================================
FILE: samples/ios/AdUnitsSample/AdUnitsSample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
IDEDidComputeMac32BitWarning
================================================
FILE: samples/ios/AdUnitsSample/Podfile
================================================
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
target 'AdUnitsSample' do
# Uncomment the next line if you're using Swift or would like to use dynamic frameworks
# use_frameworks!
# Pods for AdUnitsSample
pod 'FBAudienceNetwork'
end
================================================
FILE: samples/ios/AdUnitsSample/ReadMe.txt
================================================
AdUnitsSample
In this sample we demonstrate how to use the Native Ad API (FBNativeAd) from the Facebook Ads SDK for iOS. FBNativeAd gives the flexibility to the to allow developer to render the ad in a more native format that blends into their app. We also show how to wire up the delegate to get notified when the ad status changes over time or when the user interacts with the ad.
When running the sample on the simulator, test ads are served by default. On a device however, real ads will be served unless you specify otherwise. If you test your app on a device, please make sure to call the following API to enable test ads: [FBAdSettings addTestDevice:@""].
How to use the sample?
1/ Launch the AdUnitsSample project using Xcode from the /samples/AdUnitsSample directory.
2/ Open the file ViewController.m and replace "YOUR_PLACEMENT_ID" with the Placement ID you created through developer.facebook.com.
3/ Run the sample on the simulator or on a device.
================================================
FILE: samples/ios/AdUnitsSample/VERSION.bzl
================================================
VERSION_CONFIG = {
# These are bumped by automation
# See https://our.intern.facebook.com/intern/wiki/index.php/Releng/Mobile/Version_numbers
"FB_BUNDLE_VERSION_SHORT": "7.0",
"FB_APP_VERSION": "7.0.0.19.473",
}
================================================
FILE: samples/ios/FANSample/.gitignore
================================================
# Xcode
## Build generated
build/
DerivedData/
## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata/
## Other
*.moved-aside
*.xccheckout
*.xcscmblueprint
# CocoaPods
Pods/
Podfile.lock
================================================
FILE: samples/ios/FANSample/FANSample/AppDelegate.swift
================================================
// (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
import UIKit
import FBAudienceNetwork
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FBAudienceNetworkAds.initialize(with: nil, completionHandler: nil)
FBAdSettings.setAdvertiserTrackingEnabled(true)
return true
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}
================================================
FILE: samples/ios/FANSample/FANSample/Assets.xcassets/AppIcon.appiconset/Contents.json
================================================
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x",
"filename" : "icon_20@2x.png"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x",
"filename" : "icon_20@3x.png"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x",
"filename" : "icon_29@2x.png"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x",
"filename" : "icon_29@3x.png"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x",
"filename" : "icon_40@2x.png"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x",
"filename" : "icon_40@3x.png"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x",
"filename" : "icon_60@2x.png"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x",
"filename" : "icon_60@3x.png"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x",
"filename" : "icon_20@1x.png"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x",
"filename" : "icon_20@2x.png"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x",
"filename" : "icon_29@1x.png"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x",
"filename" : "icon_29@2x.png"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x",
"filename" : "icon_40@1x.png"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x",
"filename" : "icon_40@2x.png"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x",
"filename" : "icon_76@1x.png"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x",
"filename" : "icon_76@2x.png"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x",
"filename" : "icon_83.5@2x.png"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x",
"filename" : "icon_1024@1x.png"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: samples/ios/FANSample/FANSample/Assets.xcassets/Contents.json
================================================
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: samples/ios/FANSample/FANSample/Assets.xcassets/fan.imageset/Contents.json
================================================
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "fan.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
================================================
FILE: samples/ios/FANSample/FANSample/Base.lproj/LaunchScreen.storyboard
================================================
================================================
FILE: samples/ios/FANSample/FANSample/Base.lproj/Main.storyboard
================================================
================================================
FILE: samples/ios/FANSample/FANSample/Extensions/NSObject+ClassName.swift
================================================
// (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
import Foundation
extension NSObject {
var className: String {
return String(describing: type(of: self))
}
class var className: String {
return String(describing: self)
}
}
================================================
FILE: samples/ios/FANSample/FANSample/Extensions/UIView+NibContent.swift
================================================
// (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
import UIKit
extension UIView {
@discardableResult
func fromNib() -> T? {
guard let contentView = Bundle(for: type(of: self)).loadNibNamed(type(of: self).className, owner: self, options: nil)?.first as? T else {
return nil
}
addSubview(contentView)
contentView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
contentView.leadingAnchor.constraint(equalTo: safeAreaLayoutGuide.leadingAnchor),
contentView.trailingAnchor.constraint(equalTo: safeAreaLayoutGuide.trailingAnchor),
contentView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor),
contentView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor)
])
return contentView
}
}
================================================
FILE: samples/ios/FANSample/FANSample/Extensions/UIViewController+Storyboard.swift
================================================
// (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
import UIKit
extension UIViewController {
static func create() -> ViewControllerType {
UIStoryboard(
name: "Main",
bundle: nil
)
.instantiateViewController(
identifier: Self.className
) as! ViewControllerType
}
}
================================================
FILE: samples/ios/FANSample/FANSample/Info.plist
================================================
CFBundleDevelopmentRegion
$(DEVELOPMENT_LANGUAGE)
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleIdentifier
$(PRODUCT_BUNDLE_IDENTIFIER)
CFBundleInfoDictionaryVersion
6.0
CFBundleName
$(PRODUCT_NAME)
CFBundlePackageType
$(PRODUCT_BUNDLE_PACKAGE_TYPE)
CFBundleShortVersionString
1.0
CFBundleVersion
1
LSRequiresIPhoneOS
UIApplicationSceneManifest
UIApplicationSupportsMultipleScenes
UISceneConfigurations
UIWindowSceneSessionRoleApplication
UISceneConfigurationName
Default Configuration
UISceneDelegateClassName
$(PRODUCT_MODULE_NAME).SceneDelegate
UISceneStoryboardFile
Main
UILaunchStoryboardName
LaunchScreen
UIMainStoryboardFile
Main
UIRequiredDeviceCapabilities
armv7
UIStatusBarTintParameters
UINavigationBar
Style
UIBarStyleDefault
Translucent
UISupportedInterfaceOrientations
UIInterfaceOrientationPortrait
UIInterfaceOrientationLandscapeRight
UIInterfaceOrientationLandscapeLeft
UISupportedInterfaceOrientations~ipad
UIInterfaceOrientationPortrait
UIInterfaceOrientationPortraitUpsideDown
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
================================================
FILE: samples/ios/FANSample/FANSample/Samples/BannerSampleViewController.swift
================================================
// (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
import UIKit
import FBAudienceNetwork
enum BannerAdType {
case banner, mediumRect
var title: String {
switch self {
case .banner:
return "Banner"
case .mediumRect:
return "Medium Rectangle"
}
}
}
final class BannerSampleViewController: UIViewController {
// MARK: - Properties
private var adType: BannerAdType
private var adView: FBAdView?
private var adSize: FBAdSize {
switch adType {
case .banner:
let isRegularWidth = traitCollection.horizontalSizeClass == .regular
return isRegularWidth ? kFBAdSizeHeight90Banner : kFBAdSizeHeight50Banner
case .mediumRect:
return kFBAdSizeHeight250Rectangle
}
}
private let statusLabel = UILabel()
@IBOutlet private weak var bottomBarView: BottomBarView!
// MARK: - Setup and Lifecylce
static func create(adType: BannerAdType) -> BannerSampleViewController {
let vc: BannerSampleViewController = BannerSampleViewController.create()
vc.adType = adType
return vc
}
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = adType.title
setupStatusLabel()
loadAd()
bottomBarView.tapHandler = { [weak self] in
self?.loadAd()
}
}
required init?(coder: NSCoder) {
self.adType = .banner
super.init(coder: coder)
}
private func setupStatusLabel() {
view.addSubview(statusLabel)
statusLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
statusLabel.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 16),
statusLabel.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -16),
statusLabel.bottomAnchor.constraint(equalTo: bottomBarView.topAnchor, constant: -16)
])
statusLabel.textAlignment = .center
statusLabel.numberOfLines = 0
}
// MARK: Helpers
private func loadAd() {
adView?.removeFromSuperview()
adView = createNewAd()
adView?.loadAd()
statusLabel.text = AdStatus.isLoading.debugDescription
}
private func createNewAd() -> FBAdView {
let adView = FBAdView(placementID: "YOUR_PLACEMENT_ID", adSize: adSize, rootViewController: self)
adView.delegate = self
return adView
}
}
// MARK: FBAdViewDelegate
extension BannerSampleViewController: FBAdViewDelegate {
func adViewDidLoad(_ adView: FBAdView) {
statusLabel.text = AdStatus.didLoad.debugDescription
adView.backgroundColor = .clear
adView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(adView)
NSLayoutConstraint.activate([
adView.heightAnchor.constraint(equalToConstant: adSize.size.height),
adView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
adView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 30)
])
if adSize.size == kFBAdSizeHeight250Rectangle.size {
NSLayoutConstraint.activate([adView.widthAnchor.constraint(equalToConstant: 300)])
} else {
NSLayoutConstraint.activate([
adView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
adView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor)
])
}
}
func adViewDidClick(_ adView: FBAdView) {
statusLabel.text = AdStatus.didClick.debugDescription
}
func adViewDidFinishHandlingClick(_ adView: FBAdView) {
statusLabel.text = AdStatus.didFinishHandlingClick.debugDescription
}
func adView(_ adView: FBAdView, didFailWithError error: Error) {
statusLabel.text = AdStatus.failure(error).debugDescription
}
func adViewWillLogImpression(_ adView: FBAdView) {
statusLabel.text = AdStatus.willLogImpression.debugDescription
}
}
================================================
FILE: samples/ios/FANSample/FANSample/Samples/FullscreenAdSampleViewController.swift
================================================
// (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
import os
import UIKit
import FBAudienceNetwork
protocol FullscreenAd {
func load()
func show(from viewController: UIViewController)
}
extension FBInterstitialAd: FullscreenAd {
func show(from viewController: UIViewController) {
self.show(fromRootViewController: viewController)
}
}
extension FBRewardedVideoAd: FullscreenAd {
func show(from viewController: UIViewController) {
self.show(fromRootViewController: viewController)
}
}
extension FBRewardedInterstitialAd: FullscreenAd {
func show(from viewController: UIViewController) {
self.show(fromRootViewController: viewController, animated: true)
}
}
enum FullscreenAdType {
case interstitial, rewardedVideo, rewardedInterstitial
var title: String {
switch self {
case .interstitial:
return "Interstitial"
case .rewardedVideo:
return "Rewarded video"
case .rewardedInterstitial:
return "Rewarded interstitial"
}
}
}
final class FullscreenAdSampleViewController: UIViewController {
// MARK: - Properties
private var adType: FullscreenAdType
private var ad: FullscreenAd? {
didSet {
if let ad = ad as? FBInterstitialAd {
ad.delegate = self
} else if let ad = ad as? FBRewardedVideoAd {
ad.delegate = self
} else if let ad = ad as? FBRewardedInterstitialAd {
ad.delegate = self
}
}
}
private var state: LoadingState = .initial {
didSet {
switch state {
case .initial:
bottomBarView.set(buttonTitle: "Load Ad", isEnabled: true)
case .loading:
bottomBarView.set(buttonTitle: "Loading", isEnabled: false)
case .loaded:
bottomBarView.set(buttonTitle: "Show Ad", isEnabled: true)
case .error(let message):
bottomBarView.set(buttonTitle: "Retry", isEnabled: true)
let alert = UIAlertController(title: "Error", message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Close", style: .cancel, handler: nil))
present(alert, animated: true)
}
}
}
@IBOutlet private var bottomBarView: BottomBarView!
// MARK: - Lifecycle and Setup
static func create(adType: FullscreenAdType) -> UIViewController {
let vc: FullscreenAdSampleViewController = FullscreenAdSampleViewController.create()
vc.adType = adType
return vc
}
required init?(coder: NSCoder) {
self.adType = .interstitial
super.init(coder: coder)
}
override func viewDidLoad() {
super.viewDidLoad()
ad = createNewAd()
navigationItem.title = "\(adType.title) Ad"
bottomBarView.tapHandler = { [weak self] in
self?.handleTap()
}
}
// MARK: - Helpers
private func handleTap() {
switch state {
case .initial:
loadAd()
case .loading, .error:
ad = createNewAd()
loadAd()
case .loaded:
ad?.show(from: self)
}
}
private func loadAd() {
state = .loading
ad?.load()
}
private func createNewAd() -> FullscreenAd {
let placementID = "YOUR_PLACEMENT_ID"
switch adType {
case .interstitial:
return FBInterstitialAd(placementID: placementID)
case .rewardedVideo:
return FBRewardedVideoAd(placementID: placementID)
case .rewardedInterstitial:
return FBRewardedInterstitialAd(placementID: placementID)
}
}
}
// MARK: - FBInterstitialAdDelegate
extension FullscreenAdSampleViewController: FBInterstitialAdDelegate {
func interstitialAdDidLoad(_ interstitialAd: FBInterstitialAd) {
ad = interstitialAd
state = .loaded
}
func interstitialAd(_ interstitialAd: FBInterstitialAd, didFailWithError error: Error) {
state = .error(message: error.localizedDescription)
}
func interstitialAdDidClick(_ interstitialAd: FBInterstitialAd) {
}
func interstitialAdDidClose(_ interstitialAd: FBInterstitialAd) {
ad = createNewAd()
state = .initial
}
func interstitialAdWillClose(_ interstitialAd: FBInterstitialAd) {
}
func interstitialAdWillLogImpression(_ interstitialAd: FBInterstitialAd) {
}
}
// MARK: - FBRewardedVideoAdDelegate
extension FullscreenAdSampleViewController: FBRewardedVideoAdDelegate {
func rewardedVideoAdDidLoad(_ rewardedVideoAd: FBRewardedVideoAd) {
ad = rewardedVideoAd
state = .loaded
}
func rewardedVideoAd(_ rewardedVideoAd: FBRewardedVideoAd, didFailWithError error: Error) {
state = .error(message: error.localizedDescription)
}
func rewardedVideoAdDidClick(_ rewardedVideoAd: FBRewardedVideoAd) {
}
func rewardedVideoAdDidClose(_ rewardedVideoAd: FBRewardedVideoAd) {
ad = createNewAd()
state = .initial
}
func rewardedVideoAdServerRewardDidFail(_ rewardedVideoAd: FBRewardedVideoAd) {
}
func rewardedVideoAdVideoComplete(_ rewardedVideoAd: FBRewardedVideoAd) {
}
func rewardedVideoAdServerRewardDidSucceed(_ rewardedVideoAd: FBRewardedVideoAd) {
}
func rewardedVideoAdWillClose(_ rewardedVideoAd: FBRewardedVideoAd) {
}
func rewardedVideoAdWillLogImpression(_ rewardedVideoAd: FBRewardedVideoAd) {
}
}
extension FullscreenAdSampleViewController: FBRewardedInterstitialAdDelegate {
func rewardedInterstitialAdDidLoad(_ rewardedInterstitialAd: FBRewardedInterstitialAd) {
os_log("Rewarded interstitial ad was loaded. Can present now.")
ad = rewardedInterstitialAd
state = .loaded
}
func rewardedInterstitialAd(_ rewardedInterstitialAd: FBRewardedInterstitialAd, didFailWithError error: Error) {
let error = error as NSError
os_log("Rewarded interstitial failed to load with error: %@", error.description)
state = .error(message: "Rewarded interstitial ad failed to load. \(error.localizedDescription)")
}
func rewardedInterstitialAdDidClick(_ rewardedInterstitialAd: FBRewardedInterstitialAd) {
os_log("Rewarded interstitial was clicked.")
}
func rewardedInterstitialAdDidClose(_ rewardedInterstitialAd: FBRewardedInterstitialAd) {
os_log("Rewarded interstitial closed.")
}
func rewardedInterstitialAdWillClose(_ rewardedInterstitialAd: FBRewardedInterstitialAd) {
os_log("Rewarded interstitial will close.")
}
func rewardedInterstitialAdWillLogImpression(_ rewardedInterstitialAd: FBRewardedInterstitialAd) {
os_log("Rewarded impression is being captured.")
}
func rewardedInterstitialAdVideoComplete(_ rewardedInterstitialAd: FBRewardedInterstitialAd) {
os_log("Rewarded interstitial ad video completed.")
}
}
================================================
FILE: samples/ios/FANSample/FANSample/Samples/Native/NativeAdScreenViewController.swift
================================================
// (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
import UIKit
final class NativeAdScreenViewController: UIViewController {
// MARK: - Properties
override var shouldAutorotate: Bool {
false
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
[.portrait, .portraitUpsideDown]
}
@IBOutlet private var bottomBarView: BottomBarView!
private var adView: NativeAdView!
private let statusLabel = UILabel()
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = AdFormatInfo.native.title
setupSubviews()
bottomBarView.tapHandler = { [weak adView] in
adView?.load()
}
}
// MARK: - UI Setup
private func setupSubviews() {
// Configure a status label that reports ad load status
view.addSubview(statusLabel)
statusLabel.translatesAutoresizingMaskIntoConstraints = false
statusLabel.textAlignment = .center
statusLabel.numberOfLines = 0
// Configure an Ad view that shows the layout of the ad
adView = NativeAdView(ownerViewController: self) { [weak self] status in
self?.statusLabel.text = status.debugDescription
}
view.addSubview(adView)
adView.translatesAutoresizingMaskIntoConstraints = false
// Setup constraints
NSLayoutConstraint.activate([
statusLabel.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 16),
statusLabel.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -16),
statusLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16)
])
NSLayoutConstraint.activate([
adView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 16),
adView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -16),
adView.bottomAnchor.constraint(equalTo: bottomBarView.safeAreaLayoutGuide.topAnchor, constant: -32),
adView.heightAnchor.constraint(equalToConstant: 300)
])
}
}
================================================
FILE: samples/ios/FANSample/FANSample/Samples/Native/NativeAdView.swift
================================================
// (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
import UIKit
import FBAudienceNetwork
final class NativeAdView: UIView {
// MARK: - Properties
@IBOutlet private var iconView: FBMediaView!
@IBOutlet private var coverView: FBMediaView!
@IBOutlet private var optionsView: FBAdOptionsView!
@IBOutlet private var titleLabel: UILabel!
@IBOutlet private var bodyLabel: UILabel!
@IBOutlet private var sponsoredLabel: UILabel!
@IBOutlet private var socialContextLabel: UILabel!
@IBOutlet private var callToActionButton: UIButton!
@IBOutlet private var bodyLabelTrailingToCTAButtonConstraint: NSLayoutConstraint!
@IBOutlet private var bodyLabelTrailingToSuperviewConstraint: NSLayoutConstraint!
private var ad: FBNativeAd?
private let updateStatus: AdStatusUpdate
private weak var ownerViewController: UIViewController?
// MARK: - Setup
init(ownerViewController: UIViewController, updateStatus: @escaping AdStatusUpdate) {
self.ownerViewController = ownerViewController
self.updateStatus = updateStatus
super.init(frame: .zero)
fromNib()
coverView.delegate = self
optionsView.isHidden = true
}
@available(*, unavailable)
required init?(coder: NSCoder) { nil }
func load() {
updateStatus(.isLoading)
/// Hide the view before loading a new one
isHidden = true
// Create a native ad request with a unique placement ID (generate your own on the Facebook app settings).
// Use different ID for each ad placement in your app.
let ad = FBNativeAd(placementID: "YOUR_PLACEMENT_ID")
// Set the delegate of the ad object before loading the ad
ad.delegate = self
// Initiate a request to load an ad.
ad.loadAd()
}
private func setupCallToActionButton(with title: String?) {
guard let title = title else {
callToActionButton.isHidden = true
return
}
callToActionButton.isHidden = false
callToActionButton.setTitle(title, for: .normal)
}
}
// MARK - FBNativeAdDelegate
extension NativeAdView: FBNativeAdDelegate {
func nativeAdDidLoad(_ nativeAd: FBNativeAd) {
updateStatus(.didLoad)
if let ad = ad {
ad.unregisterView()
}
isHidden = false
ad = nativeAd
titleLabel.text = nativeAd.advertiserName
bodyLabel.text = nativeAd.bodyText
socialContextLabel.text = nativeAd.socialContext
sponsoredLabel.text = nativeAd.sponsoredTranslation
setupCallToActionButton(with: nativeAd.callToAction)
if let callToAction = nativeAd.callToAction, !callToAction.isEmpty {
bodyLabelTrailingToCTAButtonConstraint.priority = .defaultHigh
bodyLabelTrailingToSuperviewConstraint.priority = .defaultLow
} else {
bodyLabelTrailingToSuperviewConstraint.priority = .defaultHigh
bodyLabelTrailingToCTAButtonConstraint.priority = .defaultLow
}
print("Register UIView for impression and click...")
// Set native ad view tags to declare roles of your views for better analysis in future
// We will be able to provide you statistics how often these views were clicked by users
// Views provided by Facebook already have appropriate tag set
titleLabel.nativeAdViewTag = .title
bodyLabel.nativeAdViewTag = .body
socialContextLabel.nativeAdViewTag = .socialContext
callToActionButton.nativeAdViewTag = .callToAction
// Specify the clickable areas. Views you were using to set ad view tags should be clickable.
let clickableViews: [UIView] = [
iconView,
titleLabel,
bodyLabel,
socialContextLabel,
callToActionButton
]
nativeAd.registerView(
forInteraction: self,
mediaView: coverView,
iconView: iconView,
viewController: ownerViewController,
clickableViews: clickableViews
)
// You may want to use this method if you want to have all subviews clickable
// nativeAd.registerView(
// forInteraction: self,
// mediaView: coverView,
// iconView: iconView,
// viewController: ownerViewController
// )
optionsView.isHidden = false
optionsView.nativeAd = nativeAd
layoutIfNeeded()
}
func nativeAdDidClick(_ nativeAd: FBNativeAd) {
updateStatus(.didClick)
}
func nativeAdDidDownloadMedia(_ nativeAd: FBNativeAd) {
updateStatus(.didDownloadMedia)
}
func nativeAdWillLogImpression(_ nativeAd: FBNativeAd) {
updateStatus(.willLogImpression)
}
func nativeAdDidFinishHandlingClick(_ nativeAd: FBNativeAd) {
updateStatus(.didFinishHandlingClick)
}
func nativeAd(_ nativeAd: FBNativeAd, didFailWithError error: Error) {
updateStatus(.failure(error))
}
}
// MARK: - FBMediaViewDelegate
extension NativeAdView: FBMediaViewDelegate {
func mediaViewDidLoad(_ mediaView: FBMediaView) {
print("Media view did load")
}
}
================================================
FILE: samples/ios/FANSample/FANSample/Samples/Native/NativeAdView.xib
================================================
================================================
FILE: samples/ios/FANSample/FANSample/Samples/NativeBanner/NativeBannerAdScreenViewController.swift
================================================
// (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
import UIKit
final class NativeBannerAdScreenViewController: UIViewController {
// MARK: - Properties
@IBOutlet private var bottomBarView: BottomBarView!
private var adView: NativeBannerAdView!
private let statusLabel = UILabel()
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = AdFormatInfo.nativeBanner.title
setupStatusLabel()
setupAdView()
bottomBarView.tapHandler = { [weak adView] in
adView?.load()
}
}
// MARK: - UI Setup
private func setupStatusLabel() {
view.addSubview(statusLabel)
statusLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
statusLabel.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 16),
statusLabel.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -16),
statusLabel.centerYAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerYAnchor)
])
statusLabel.textAlignment = .center
statusLabel.numberOfLines = 0
}
private func setupAdView() {
adView = NativeBannerAdView(ownerViewController: self) { [weak self] status in
self?.statusLabel.text = status.debugDescription
}
view.addSubview(adView)
adView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
adView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
adView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
adView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
])
}
}
================================================
FILE: samples/ios/FANSample/FANSample/Samples/NativeBanner/NativeBannerAdView.swift
================================================
// (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
import UIKit
import FBAudienceNetwork
final class NativeBannerAdView: UIView {
// MARK: - Properties
@IBOutlet private var iconView: FBMediaView!
@IBOutlet private var optionsView: FBAdOptionsView!
@IBOutlet private var titleLabel: UILabel!
@IBOutlet private var callToActionButton: UIButton!
@IBOutlet private var sponsoredLabel: UILabel!
private var ad: FBNativeBannerAd?
private let updateStatus: AdStatusUpdate
private weak var ownerViewController: UIViewController?
// MARK: - Setup
init(ownerViewController: UIViewController, updateStatus: @escaping AdStatusUpdate) {
self.ownerViewController = ownerViewController
self.updateStatus = updateStatus
super.init(frame: .zero)
fromNib()
optionsView.isHidden = true
}
@available(*, unavailable)
required init?(coder: NSCoder) { nil }
func load() {
updateStatus(.isLoading)
/// Hide the view before loading a new one
isHidden = true
// Create a native ad request with a unique placement ID (generate your own on the Facebook app settings).
// Use different ID for each ad placement in your app.
let ad = FBNativeBannerAd(placementID: "YOUR_PLACEMENT_ID")
// Set the delegate of the ad object before loading the ad
ad.delegate = self
// Initiate a request to load an ad.
ad.loadAd()
}
private func setupCallToActionButton(with title: String?) {
guard let title = title else {
callToActionButton.isHidden = true
return
}
callToActionButton.isHidden = false
callToActionButton.setTitle(title, for: .normal)
}
}
// MARK: - FBNativeBannerAdDelegate
extension NativeBannerAdView: FBNativeBannerAdDelegate {
func nativeBannerAdDidLoad(_ nativeBannerAd: FBNativeBannerAd) {
updateStatus(.didLoad)
if let ad = ad {
ad.unregisterView()
}
ad = nativeBannerAd
isHidden = false
titleLabel.text = nativeBannerAd.advertiserName
sponsoredLabel.text = nativeBannerAd.sponsoredTranslation
setupCallToActionButton(with: nativeBannerAd.callToAction)
print("Register UIView for impression and click...")
// Set native banner ad view tags to declare roles of your views for better analysis in future
// We will be able to provide you statistics how often these views were clicked by users
// Views provided by Facebook already have appropriate tag set
titleLabel.nativeAdViewTag = .title
callToActionButton.nativeAdViewTag = FBNativeAdViewTag.callToAction
// Specify the clickable areas. View you were using to set ad view tags should be clickable.
let clickableViews: [UIView] = [callToActionButton]
nativeBannerAd.registerView(
forInteraction: self,
iconView: iconView,
viewController: ownerViewController,
clickableViews: clickableViews
)
// If you don't want to provide native ad view tags you can simply
// wire up UIView with the native banner ad and the whole UIView will be clickable.
// nativeBannerAd.registerView(
// forInteraction: iconView,
// iconView: iconView,
// viewController: ownerViewController
// )
optionsView.nativeAd = nativeBannerAd
optionsView.isHidden = false
}
func nativeBannerAdDidDownloadMedia(_ nativeBannerAd: FBNativeBannerAd) {
updateStatus(.didDownloadMedia)
}
func nativeBannerAdWillLogImpression(_ nativeBannerAd: FBNativeBannerAd) {
updateStatus(.willLogImpression)
}
func nativeBannerAd(_ nativeBannerAd: FBNativeBannerAd, didFailWithError error: Error) {
updateStatus(.failure(error))
}
func nativeBannerAdDidClick(_ nativeBannerAd: FBNativeBannerAd) {
updateStatus(.didClick)
}
func nativeBannerAdDidFinishHandlingClick(_ nativeBannerAd: FBNativeBannerAd) {
updateStatus(.didFinishHandlingClick)
}
}
================================================
FILE: samples/ios/FANSample/FANSample/Samples/NativeBanner/NativeBannerAdView.xib
================================================
================================================
FILE: samples/ios/FANSample/FANSample/Samples/NativeBannerTemplate/NativeBannerTemplateAdScreenViewController.swift
================================================
// (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
import UIKit
final class NativeBannerTemplateAdScreenViewController: UIViewController {
// MARK: - Properties
@IBOutlet private var bottomBarView: BottomBarView!
private var adView: NativeBannerTemplateAdView!
private let statusLabel = UILabel()
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = AdFormatInfo.nativeBannerTemplate.title
setupSubviews()
bottomBarView.tapHandler = { [weak adView] in
adView?.load()
}
}
private func setupSubviews() {
adView = NativeBannerTemplateAdView { [weak self] status in
self?.statusLabel.text = status.debugDescription
}
view.addSubview(adView)
view.addSubview(statusLabel)
statusLabel.textAlignment = .center
statusLabel.numberOfLines = 0
adView.adViewType = .genericHeight50
statusLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
statusLabel.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 16),
statusLabel.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -16),
statusLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16)
])
NSLayoutConstraint.activate([
adView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
adView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
adView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
])
}
// MARK: - IBActions
@IBAction private func segmentedControlValueChanged(sender: UISegmentedControl) {
switch sender.selectedSegmentIndex {
case 0:
adView.adViewType = .genericHeight50
case 1:
adView.adViewType = .genericHeight100
default:
adView.adViewType = .genericHeight120
}
}
}
================================================
FILE: samples/ios/FANSample/FANSample/Samples/NativeBannerTemplate/NativeBannerTemplateAdView.swift
================================================
// (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
import UIKit
import FBAudienceNetwork
extension FBNativeBannerAdViewType {
var heightInPoints: CGFloat {
switch self {
case .genericHeight50:
return 50
case .genericHeight100:
return 100
case .genericHeight120:
return 120
@unknown default:
print("Unknown `FBNativeBannerAdViewType` type. Returning \(FBNativeBannerAdViewType.genericHeight50) instead.")
return FBNativeBannerAdViewType.genericHeight50.heightInPoints
}
}
}
final class NativeBannerTemplateAdView: UIView {
// MARK: - Properties
var adViewType: FBNativeBannerAdViewType = .genericHeight50 {
didSet {
heightConstraint.constant = adViewType.heightInPoints
load()
}
}
private var adView: FBNativeBannerAdView!
private var ad: FBNativeBannerAd?
private let updateStatus: AdStatusUpdate
private var heightConstraint: NSLayoutConstraint!
// MARK: - Setup
init(updateStatus: @escaping AdStatusUpdate) {
self.updateStatus = updateStatus
super.init(frame: .zero)
translatesAutoresizingMaskIntoConstraints = false
heightConstraint = heightAnchor.constraint(equalToConstant: adViewType.heightInPoints)
heightConstraint.isActive = true
}
@available(*, unavailable)
required init?(coder: NSCoder) { nil }
func load() {
/// Hide the view before loading a new one
adView?.removeFromSuperview()
// Create a native ad request with a unique placement ID (generate your own on the Facebook app settings).
// Use different ID for each ad placement in your app.
let ad = FBNativeBannerAd(placementID: "YOUR_PLACEMENT_ID")
// Set the delegate of the ad object before loading the ad
ad.delegate = self
// Initiate a request to load an ad.
ad.loadAd()
}
}
extension NativeBannerTemplateAdView: FBNativeBannerAdDelegate {
func nativeBannerAdDidLoad(_ nativeBannerAd: FBNativeBannerAd) {
updateStatus(.didLoad)
if let ad = ad {
ad.unregisterView()
adView?.removeFromSuperview()
adView = nil
}
guard nativeBannerAd.isAdValid else {
updateStatus(.invalid)
return
}
ad = nativeBannerAd
adView = FBNativeBannerAdView(nativeBannerAd: nativeBannerAd, with: adViewType)
adView.frame = bounds
adView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
addSubview(adView)
layoutIfNeeded()
}
func nativeBannerAdDidDownloadMedia(_ nativeBannerAd: FBNativeBannerAd) {
updateStatus(.didDownloadMedia)
}
func nativeBannerAdWillLogImpression(_ nativeBannerAd: FBNativeBannerAd) {
updateStatus(.willLogImpression)
}
func nativeBannerAd(_ nativeBannerAd: FBNativeBannerAd, didFailWithError error: Error) {
updateStatus(.failure(error))
}
func nativeBannerAdDidClick(_ nativeBannerAd: FBNativeBannerAd) {
updateStatus(.didClick)
}
func nativeBannerAdDidFinishHandlingClick(_ nativeBannerAd: FBNativeBannerAd) {
updateStatus(.didFinishHandlingClick)
}
}
================================================
FILE: samples/ios/FANSample/FANSample/Samples/NativeTemplate/NativeTemplateAdView.swift
================================================
// (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
import UIKit
import FBAudienceNetwork
final class NativeTemplateAdView: UIView {
// MARK: - Properties
private lazy var adAttributes: FBNativeAdViewAttributes = {
let attributes = FBNativeAdViewAttributes()
attributes.backgroundColor = .white
attributes.advertiserNameColor = UIColor(red: 0.11, green: 0.12, blue: 0.13, alpha: 1)
attributes.buttonColor = UIColor(red: 0.235, green: 0.485, blue: 1, alpha: 1)
attributes.buttonTitleColor = .white
attributes.titleColor = .darkGray
attributes.descriptionColor = .gray
return attributes
}()
private var ad: FBNativeAd?
private var adView: FBNativeAdView!
private let updateStatus: AdStatusUpdate
// MARK: - Setup
init(updateStatus: @escaping AdStatusUpdate) {
self.updateStatus = updateStatus
super.init(frame: .zero)
backgroundColor = .white
}
@available(*, unavailable)
required init?(coder: NSCoder) { nil }
func load() {
updateStatus(.isLoading)
// Remove the previous view before loading a new one
adView?.removeFromSuperview()
// Create a native ad request with a unique placement ID (generate your own on the Facebook app settings).
// Use different ID for each ad placement in your app.
let ad = FBNativeAd(placementID: "YOUR_PLACEMENT_ID")
// Set the delegate of the ad object before loading the ad
ad.delegate = self
// Initiate a request to load an ad.
ad.loadAd()
}
}
// MARK - FBNativeAdDelegate
extension NativeTemplateAdView: FBNativeAdDelegate {
func nativeAdDidLoad(_ nativeAd: FBNativeAd) {
updateStatus(.didLoad)
if let ad = ad {
ad.unregisterView()
adView?.removeFromSuperview()
adView = nil
}
guard nativeAd.isAdValid else {
updateStatus(.invalid)
return
}
ad = nativeAd
adView = FBNativeAdView(nativeAd: nativeAd, with: adAttributes)
adView.frame = bounds
adView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
addSubview(adView)
layoutIfNeeded()
}
func nativeAdDidClick(_ nativeAd: FBNativeAd) {
updateStatus(.didClick)
}
func nativeAdDidDownloadMedia(_ nativeAd: FBNativeAd) {
updateStatus(.didDownloadMedia)
}
func nativeAdWillLogImpression(_ nativeAd: FBNativeAd) {
updateStatus(.willLogImpression)
}
func nativeAdDidFinishHandlingClick(_ nativeAd: FBNativeAd) {
updateStatus(.didFinishHandlingClick)
}
func nativeAd(_ nativeAd: FBNativeAd, didFailWithError error: Error) {
updateStatus(.failure(error))
}
}
================================================
FILE: samples/ios/FANSample/FANSample/Samples/NativeTemplate/NativeTemplateScreenViewController.swift
================================================
// (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
import UIKit
final class NativeTemplateScreenViewController: UIViewController {
// MARK: - Constants
private enum Constants {
enum Width {
static let min: Float = 120
static let `default`: Float = 250
static let max: Float = 320
}
enum Height {
static let min: Float = 150
static let `default`: Float = 250
static let max: Float = 400
}
}
override var shouldAutorotate: Bool {
false
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
[.portrait, .portraitUpsideDown]
}
@IBOutlet private var widthSlider: UISlider!
@IBOutlet private var heightSlider: UISlider!
@IBOutlet private var slidersStackView: UIStackView!
@IBOutlet private var bottomBarView: BottomBarView!
private var heightConstraint: NSLayoutConstraint!
private var widthConstraint: NSLayoutConstraint!
private var adView: NativeTemplateAdView!
private let statusLabel = UILabel()
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = AdFormatInfo.nativeTemplate.title
setupSubviews()
bottomBarView.tapHandler = { [weak adView] in
adView?.load()
}
}
// MARK: - UI Setup
private func setupSubviews() {
adView = NativeTemplateAdView { [weak self] status in
self?.statusLabel.text = status.debugDescription
}
view.addSubview(adView)
view.addSubview(statusLabel)
statusLabel.textAlignment = .center
statusLabel.numberOfLines = 0
widthSlider.minimumValue = Constants.Width.min
widthSlider.maximumValue = Constants.Width.max
widthSlider.value = Constants.Width.default
heightSlider.minimumValue = Constants.Height.min
heightSlider.maximumValue = Constants.Height.max
heightSlider.value = Constants.Height.default
statusLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
statusLabel.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 16),
statusLabel.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -16),
statusLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16)
])
adView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
adView.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor),
adView.bottomAnchor.constraint(equalTo: slidersStackView.topAnchor, constant: -32)
])
heightConstraint = adView.heightAnchor.constraint(equalToConstant: CGFloat(heightSlider.value))
heightConstraint.isActive = true
widthConstraint = adView.widthAnchor.constraint(equalToConstant: CGFloat(widthSlider.value))
widthConstraint.isActive = true
}
// MARK: - IBActions
@IBAction private func widthSliderValueChanged(sender: UISlider) {
widthConstraint.constant = CGFloat(sender.value)
}
@IBAction private func heightSliderValueChanged(sender: UISlider) {
heightConstraint.constant = CGFloat(sender.value)
}
}
================================================
FILE: samples/ios/FANSample/FANSample/SamplesViewController.swift
================================================
// (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
import UIKit
import FBAudienceNetwork
final class SamplesViewController: UITableViewController {
// MARK: - Types
private struct Section {
let title: String
let objects: [AdFormatInfo]
}
// MARK: - Properties
private let sections: [Section] = {
let nativeSection = Section(
title: "Native",
objects: [.native, .nativeTemplate, .nativeBanner, .nativeBannerTemplate]
)
let bannerSection = Section(
title: "Banner",
objects: [.banner, .mediumRect]
)
let fullscreenSection = Section(
title: "Fullscreen",
objects: [.interstitial, .rewardedVideo, .rewardedInterstitial]
)
return [nativeSection, bannerSection, fullscreenSection]
}()
private let sdkInfoLabel: UILabel = {
let sdkInfoLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 50))
sdkInfoLabel.textAlignment = .center
sdkInfoLabel.text = "AN SDK \(FB_AD_SDK_VERSION)"
return sdkInfoLabel
}()
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableFooterView = sdkInfoLabel
}
private func createViewController(for adFormat: AdFormatInfo) -> UIViewController? {
let vc: UIViewController?
switch adFormat {
case .interstitial:
vc = FullscreenAdSampleViewController.create(adType: .interstitial)
case .rewardedVideo:
vc = FullscreenAdSampleViewController.create(adType: .rewardedVideo)
case .rewardedInterstitial:
vc = FullscreenAdSampleViewController.create(adType: .rewardedInterstitial)
case .banner:
vc = BannerSampleViewController.create(adType: .banner)
case .native:
vc = NativeAdScreenViewController.create()
case .nativeBanner:
vc = NativeBannerAdScreenViewController.create()
case .nativeTemplate:
vc = NativeTemplateScreenViewController.create()
case .mediumRect:
vc = BannerSampleViewController.create(adType: .mediumRect)
case .nativeBannerTemplate:
vc = NativeBannerTemplateAdScreenViewController.create()
}
return vc
}
// MARK: - Settings
@IBAction private func settingsButtonTapped() {
let navigationController = NavigationController(nibName: nil, bundle: nil)
navigationController.viewControllers = [SettingScreenViewController.create()]
self.navigationController?.present(navigationController, animated: true, completion: nil)
}
// MARK: - Table View
override func numberOfSections(in tableView: UITableView) -> Int {
sections.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
sections[section].objects.count
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let currentObject = sections[indexPath.section].objects[indexPath.row]
guard let vc = createViewController(for: currentObject) else { return }
navigationController?.pushViewController(vc, animated: true)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let currentSection = sections[indexPath.section]
let cell = tableView.dequeueReusableCell(withIdentifier: "AdFormatCell",
for: indexPath)
cell.textLabel?.text = currentSection.objects[indexPath.row].title
return cell
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
sections[section].title
}
}
================================================
FILE: samples/ios/FANSample/FANSample/SceneDelegate.swift
================================================
// (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate, UISplitViewControllerDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
}
func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}
func sceneWillResignActive(_ scene: UIScene) {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
func sceneDidEnterBackground(_ scene: UIScene) {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
}
}
================================================
FILE: samples/ios/FANSample/FANSample/Settings/Picker/PickerTableViewCell.swift
================================================
// (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
import UIKit
final class PickerTableViewCell: UITableViewCell {
// MARK: - Properties
var dataSource: PickerCellViewModelAPI? {
didSet {
guard let dataSource = dataSource else { return }
pickerView.selectRow(dataSource.selectedRow, inComponent: 0, animated: false)
titleLabel.text = dataSource.title
textField.text = dataSource.name(by: dataSource.selectedRow)
}
}
private let pickerView = UIPickerView()
@IBOutlet private var titleLabel: UILabel!
@IBOutlet private var textField: UITextField!
// MARK: - Lifecycle
override func awakeFromNib() {
super.awakeFromNib()
pickerView.dataSource = self
pickerView.delegate = self
textField.inputView = pickerView
textField.inputAccessoryView = createToolbar()
}
override func prepareForReuse() {
super.prepareForReuse()
dataSource = nil
}
private func createToolbar() -> UIToolbar {
let toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 44))
let flexItem = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let doneItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(doneButtonTapped))
toolbar.items = [flexItem, doneItem]
toolbar.sizeToFit()
return toolbar
}
// MARK: - Actions
@objc
private func doneButtonTapped() {
textField.resignFirstResponder()
}
}
// MARK: - UIPickerViewDelegate, UIPickerViewDataSource
extension PickerTableViewCell: UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int { 1 }
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
dataSource?.numberOfRows ?? 0
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
dataSource?.name(by: row)
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
dataSource?.select(index: row)
textField.text = dataSource?.name(by: row)
}
}
================================================
FILE: samples/ios/FANSample/FANSample/Settings/Picker/PickerTableViewCell.xib
================================================
================================================
FILE: samples/ios/FANSample/FANSample/Settings/Picker/ViewModels.swift
================================================
// (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
import Foundation
import FBAudienceNetwork
protocol PickerCellViewModelAPI {
var title: String { get }
var selectedRow: Int { get }
var numberOfRows: Int { get }
func name(by index: Int) -> String?
func select(index: Int)
}
struct LogLevelCellViewModel: PickerCellViewModelAPI {
let title = "Log Level"
var numberOfRows: Int { nameByLevel.count }
var selectedRow: Int { FBAdSettings.getLogLevel().rawValue }
private let nameByLevel: [FBAdLogLevel: String] = [
.none : "None",
.notification : "Notification",
.error : "Error",
.warning : "Warning",
.log : "Log",
.debug : "Debug",
.verbose : "Verbose"
]
func name(by index: Int) -> String? {
guard let type = FBAdLogLevel(rawValue: index) else {
print("Error: unable to map index to `FBAdLogLevel`")
return nil
}
return nameByLevel[type]
}
func select(index: Int) {
guard let level = FBAdLogLevel(rawValue: index) else {
return
}
FBAdSettings.setLogLevel(level)
}
}
struct AdTypeCellViewModel: PickerCellViewModelAPI {
let title = "Ad Type"
var numberOfRows: Int { nameByType.count }
var selectedRow: Int { FBAdSettings.testAdType.rawValue }
private let nameByType: [FBAdTestAdType: String] = [
.default : "default",
.img_16_9_App_Install : "image_install",
.img_16_9_Link : "image_link",
.vid_HD_16_9_46s_App_Install : "video_16x9_46s_install",
.vid_HD_16_9_46s_Link : "video_16x9_46s_link",
.vid_HD_16_9_15s_App_Install : "video_16x9_15s_install",
.vid_HD_16_9_15s_Link : "video_16x9_15s_link",
.vid_HD_9_16_39s_App_Install : "video_9x16_39s_install",
.vid_HD_9_16_39s_Link : "video_9x16_39s_link",
.carousel_Img_Square_App_Install : "carousel_install",
.carousel_Img_Square_Link : "carousel_link",
.carousel_Vid_Square_Link : "carousel_video",
.playable : "playable"
]
func name(by index: Int) -> String? {
guard let type = FBAdTestAdType(rawValue: index) else {
print("Error: unable to map index to `FBAdTestAdType`")
return nil
}
return nameByType[type]
}
func select(index: Int) {
guard let type = FBAdTestAdType(rawValue: index) else {
return
}
FBAdSettings.testAdType = type
}
}
================================================
FILE: samples/ios/FANSample/FANSample/Settings/SettingScreenViewController.swift
================================================
// (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
import UIKit
import FBAudienceNetwork
final class SettingScreenViewController: UITableViewController {
// MARK: - Properties
private lazy var adTypeCellViewModel = AdTypeCellViewModel()
private lazy var logLevelCellViewModel = LogLevelCellViewModel()
// MARK: - Lifecylce
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "Settings"
tableView.register(
UINib(nibName: "TestModeTableViewCell", bundle: nil),
forCellReuseIdentifier: "TestModeTableViewCell"
)
tableView.register(
UINib(nibName: "PickerTableViewCell", bundle: nil),
forCellReuseIdentifier: "PickerTableViewCell"
)
tableView.rowHeight = 48
tableView.allowsSelection = false
}
// MARK: - Table View
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 3 }
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.row {
case 0:
let cell = tableView.dequeueReusableCell(withIdentifier: "TestModeTableViewCell", for: indexPath) as! TestModeTableViewCell
return cell
case 1:
let cell = tableView.dequeueReusableCell(withIdentifier: "PickerTableViewCell", for: indexPath) as! PickerTableViewCell
cell.dataSource = adTypeCellViewModel
return cell
case 2:
let cell = tableView.dequeueReusableCell(withIdentifier: "PickerTableViewCell", for: indexPath) as! PickerTableViewCell
cell.dataSource = logLevelCellViewModel
return cell
default:
return UITableViewCell()
}
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
"SDK Version \(FB_AD_SDK_VERSION)"
}
// MARK: - Actions
@IBAction private func dismissButtonTapped() {
dismiss(animated: true, completion: nil)
}
}
================================================
FILE: samples/ios/FANSample/FANSample/Settings/TestMode/TestModeTableViewCell.swift
================================================
// (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
import UIKit
import FBAudienceNetwork
final class TestModeTableViewCell: UITableViewCell {
@IBOutlet private var testModeSwitch: UISwitch!
override func awakeFromNib() {
super.awakeFromNib()
testModeSwitch.isOn = FBAdSettings.isTestMode()
}
@IBAction private func testModeSwitchValueChanged(sender: UISwitch) {
let testDeviceHash = FBAdSettings.testDeviceHash()
if sender.isOn {
FBAdSettings.addTestDevice(testDeviceHash)
} else {
FBAdSettings.clearTestDevice(testDeviceHash)
}
}
}
================================================
FILE: samples/ios/FANSample/FANSample/Settings/TestMode/TestModeTableViewCell.xib
================================================
================================================
FILE: samples/ios/FANSample/FANSample/Utils/AdUtils.swift
================================================
// (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
import Foundation
typealias AdStatusUpdate = (AdStatus) -> Void
enum AdStatus: CustomDebugStringConvertible {
case willLogImpression
case failure(Error)
case invalid
case didClick
case didFinishHandlingClick
case isLoading
case didLoad
case didDownloadMedia
var debugDescription: String {
switch self {
case .didClick:
return "Ad was clicked"
case .failure(let error):
return "Ad failed to load with error: " + error.localizedDescription
case .invalid:
return "Ad is invalid"
case .didLoad:
return "Ad did load"
case .isLoading:
return "Ad is loading"
case .didDownloadMedia:
return "Ad did download media"
case .willLogImpression:
return "Ad impression is being captured"
case .didFinishHandlingClick:
return "Ad did finish handling click"
}
}
}
enum LoadingState {
case initial
case loading
case loaded
case error(message: String)
}
enum AdFormatInfo {
case native
case nativeTemplate
case nativeBanner
case nativeBannerTemplate
case banner
case mediumRect
case interstitial
case rewardedVideo
case rewardedInterstitial
var title: String {
switch self {
case .native: return "Native"
case .nativeTemplate: return "Native (Template)"
case .nativeBanner: return "Native Banner"
case .nativeBannerTemplate: return "Native Banner (Template)"
case .banner: return "Banner"
case .mediumRect: return "Medium Rectangle"
case .interstitial: return "Interstitial"
case .rewardedVideo: return "Rewarded Video"
case .rewardedInterstitial: return "Rewarded Interstitial"
}
}
}
================================================
FILE: samples/ios/FANSample/FANSample/Utils/BottomBarView.swift
================================================
// (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
import UIKit
import FBAudienceNetwork
final class BottomBarView: UIView {
// MARK: - Types
typealias TapHandler = () -> Void
// MARK: - Properties
var tapHandler: TapHandler!
@IBOutlet private var button: UIButton!
@IBOutlet private var testModeSwitch: UISwitch!
// MARK: - Setup
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setup()
}
private func setup() {
fromNib()
testModeSwitch.isOn = FBAdSettings.isTestMode()
}
// MARK: - Actions
@IBAction private func buttonTapped() {
tapHandler()
}
@IBAction private func testModeSwitchValueChanged(sender: UISwitch) {
let testDeviceHash = FBAdSettings.testDeviceHash()
if sender.isOn {
FBAdSettings.addTestDevice(testDeviceHash)
} else {
FBAdSettings.clearTestDevice(testDeviceHash)
}
}
func set(buttonTitle: String, isEnabled: Bool) {
button.setTitle(buttonTitle, for: .normal)
button.isEnabled = isEnabled
}
}
================================================
FILE: samples/ios/FANSample/FANSample/Utils/BottomBarView.xib
================================================
================================================
FILE: samples/ios/FANSample/FANSample/Utils/NavigationController.swift
================================================
// (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
import UIKit
final class NavigationController: UINavigationController {
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
topViewController?.supportedInterfaceOrientations ?? .all
}
override var shouldAutorotate: Bool {
topViewController?.shouldAutorotate ?? false
}
}
================================================
FILE: samples/ios/FANSample/FANSample.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 51;
objects = {
/* Begin PBXBuildFile section */
1437CFB92538A405003DB489 /* UIViewController+Storyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1437CFB82538A405003DB489 /* UIViewController+Storyboard.swift */; };
14548A11253E0DC000E62C49 /* AdUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14548A10253E0DC000E62C49 /* AdUtils.swift */; };
145A31CE253ED12000A83B62 /* PickerTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 145A31CC253ED12000A83B62 /* PickerTableViewCell.swift */; };
145A31CF253ED12000A83B62 /* PickerTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 145A31CD253ED12000A83B62 /* PickerTableViewCell.xib */; };
145A31D6253EE15A00A83B62 /* ViewModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 145A31D5253EE15A00A83B62 /* ViewModels.swift */; };
145A31F8253EF50300A83B62 /* FullscreenAdSampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 145A31E8253EF50300A83B62 /* FullscreenAdSampleViewController.swift */; };
145A31F9253EF50300A83B62 /* NativeAdView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 145A31EA253EF50300A83B62 /* NativeAdView.swift */; };
145A31FA253EF50300A83B62 /* NativeAdScreenViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 145A31EB253EF50300A83B62 /* NativeAdScreenViewController.swift */; };
145A31FB253EF50300A83B62 /* NativeAdView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 145A31EC253EF50300A83B62 /* NativeAdView.xib */; };
145A31FC253EF50300A83B62 /* NativeBannerTemplateAdScreenViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 145A31EE253EF50300A83B62 /* NativeBannerTemplateAdScreenViewController.swift */; };
145A31FD253EF50300A83B62 /* NativeBannerTemplateAdView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 145A31EF253EF50300A83B62 /* NativeBannerTemplateAdView.swift */; };
145A31FE253EF50300A83B62 /* NativeBannerAdScreenViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 145A31F1253EF50300A83B62 /* NativeBannerAdScreenViewController.swift */; };
145A31FF253EF50300A83B62 /* NativeBannerAdView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 145A31F2253EF50300A83B62 /* NativeBannerAdView.xib */; };
145A3200253EF50300A83B62 /* NativeBannerAdView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 145A31F3253EF50300A83B62 /* NativeBannerAdView.swift */; };
145A3201253EF50300A83B62 /* NativeTemplateAdView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 145A31F5253EF50300A83B62 /* NativeTemplateAdView.swift */; };
145A3202253EF50300A83B62 /* NativeTemplateScreenViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 145A31F6253EF50300A83B62 /* NativeTemplateScreenViewController.swift */; };
145A3203253EF50300A83B62 /* BannerSampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 145A31F7253EF50300A83B62 /* BannerSampleViewController.swift */; };
145A3206253EF57800A83B62 /* SamplesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 145A3205253EF57800A83B62 /* SamplesViewController.swift */; };
145A320A253EF5BC00A83B62 /* BottomBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 145A3208253EF5BC00A83B62 /* BottomBarView.swift */; };
145A320B253EF5BC00A83B62 /* BottomBarView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 145A3209253EF5BC00A83B62 /* BottomBarView.xib */; };
145A320E253EF61D00A83B62 /* NavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 145A320D253EF61D00A83B62 /* NavigationController.swift */; };
1468FC7A252F33B7004E2CD9 /* NSObject+ClassName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1468FC79252F33B7004E2CD9 /* NSObject+ClassName.swift */; };
1468FC7C252F33D1004E2CD9 /* UIView+NibContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1468FC7B252F33D1004E2CD9 /* UIView+NibContent.swift */; };
1499C93E253E495A003E0FE5 /* SettingScreenViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1499C93D253E495A003E0FE5 /* SettingScreenViewController.swift */; };
1499C945253E4DA3003E0FE5 /* TestModeTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1499C943253E4DA3003E0FE5 /* TestModeTableViewCell.swift */; };
1499C946253E4DA3003E0FE5 /* TestModeTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1499C944253E4DA3003E0FE5 /* TestModeTableViewCell.xib */; };
82B89F4623F7F95900DF6E14 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82B89F4523F7F95900DF6E14 /* AppDelegate.swift */; };
82B89F4823F7F95900DF6E14 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82B89F4723F7F95900DF6E14 /* SceneDelegate.swift */; };
82B89F4F23F7F95900DF6E14 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 82B89F4D23F7F95900DF6E14 /* Main.storyboard */; };
82B89F5123F7F95B00DF6E14 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 82B89F5023F7F95B00DF6E14 /* Assets.xcassets */; };
82B89F5423F7F95B00DF6E14 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 82B89F5223F7F95B00DF6E14 /* LaunchScreen.storyboard */; };
9E769FD66DA26D7240AE192E /* Pods_FANSample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A2B6B472CA61D8834794B3B /* Pods_FANSample.framework */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
1437CFB82538A405003DB489 /* UIViewController+Storyboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Storyboard.swift"; sourceTree = ""; };
14548A10253E0DC000E62C49 /* AdUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdUtils.swift; sourceTree = ""; };
145A31CC253ED12000A83B62 /* PickerTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickerTableViewCell.swift; sourceTree = ""; };
145A31CD253ED12000A83B62 /* PickerTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PickerTableViewCell.xib; sourceTree = ""; };
145A31D5253EE15A00A83B62 /* ViewModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewModels.swift; sourceTree = ""; };
145A31E8253EF50300A83B62 /* FullscreenAdSampleViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FullscreenAdSampleViewController.swift; sourceTree = ""; };
145A31EA253EF50300A83B62 /* NativeAdView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NativeAdView.swift; sourceTree = ""; };
145A31EB253EF50300A83B62 /* NativeAdScreenViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NativeAdScreenViewController.swift; sourceTree = ""; };
145A31EC253EF50300A83B62 /* NativeAdView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NativeAdView.xib; sourceTree = ""; };
145A31EE253EF50300A83B62 /* NativeBannerTemplateAdScreenViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NativeBannerTemplateAdScreenViewController.swift; sourceTree = ""; };
145A31EF253EF50300A83B62 /* NativeBannerTemplateAdView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NativeBannerTemplateAdView.swift; sourceTree = ""; };
145A31F1253EF50300A83B62 /* NativeBannerAdScreenViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NativeBannerAdScreenViewController.swift; sourceTree = ""; };
145A31F2253EF50300A83B62 /* NativeBannerAdView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NativeBannerAdView.xib; sourceTree = ""; };
145A31F3253EF50300A83B62 /* NativeBannerAdView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NativeBannerAdView.swift; sourceTree = ""; };
145A31F5253EF50300A83B62 /* NativeTemplateAdView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NativeTemplateAdView.swift; sourceTree = ""; };
145A31F6253EF50300A83B62 /* NativeTemplateScreenViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NativeTemplateScreenViewController.swift; sourceTree = ""; };
145A31F7253EF50300A83B62 /* BannerSampleViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BannerSampleViewController.swift; sourceTree = ""; };
145A3205253EF57800A83B62 /* SamplesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SamplesViewController.swift; sourceTree = ""; };
145A3208253EF5BC00A83B62 /* BottomBarView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BottomBarView.swift; sourceTree = ""; };
145A3209253EF5BC00A83B62 /* BottomBarView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = BottomBarView.xib; sourceTree = ""; };
145A320D253EF61D00A83B62 /* NavigationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationController.swift; sourceTree = ""; };
145A321B253F22C800A83B62 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = SOURCE_ROOT; };
1468FC79252F33B7004E2CD9 /* NSObject+ClassName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSObject+ClassName.swift"; sourceTree = ""; };
1468FC7B252F33D1004E2CD9 /* UIView+NibContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+NibContent.swift"; sourceTree = ""; };
1499C93D253E495A003E0FE5 /* SettingScreenViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingScreenViewController.swift; sourceTree = ""; };
1499C943253E4DA3003E0FE5 /* TestModeTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestModeTableViewCell.swift; sourceTree = ""; };
1499C944253E4DA3003E0FE5 /* TestModeTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TestModeTableViewCell.xib; sourceTree = ""; };
4F0CF2FBCD28B527F12C5658 /* Pods-FANSample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FANSample.debug.xcconfig"; path = "Target Support Files/Pods-FANSample/Pods-FANSample.debug.xcconfig"; sourceTree = ""; };
5A2B6B472CA61D8834794B3B /* Pods_FANSample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FANSample.framework; sourceTree = BUILT_PRODUCTS_DIR; };
7344E3D24EBE09AC50121E89 /* Pods-FANSample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FANSample.release.xcconfig"; path = "Target Support Files/Pods-FANSample/Pods-FANSample.release.xcconfig"; sourceTree = ""; };
82B89F4223F7F95900DF6E14 /* FANSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FANSample.app; sourceTree = BUILT_PRODUCTS_DIR; };
82B89F4523F7F95900DF6E14 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
82B89F4723F7F95900DF6E14 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; };
82B89F4E23F7F95900DF6E14 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
82B89F5023F7F95B00DF6E14 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
82B89F5323F7F95B00DF6E14 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
82B89F5523F7F95B00DF6E14 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
82B89F3F23F7F95900DF6E14 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9E769FD66DA26D7240AE192E /* Pods_FANSample.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
14548A0F253E0DA300E62C49 /* Utils */ = {
isa = PBXGroup;
children = (
145A320D253EF61D00A83B62 /* NavigationController.swift */,
145A3208253EF5BC00A83B62 /* BottomBarView.swift */,
145A3209253EF5BC00A83B62 /* BottomBarView.xib */,
14548A10253E0DC000E62C49 /* AdUtils.swift */,
);
path = Utils;
sourceTree = "";
};
145A31D3253EE13800A83B62 /* Picker */ = {
isa = PBXGroup;
children = (
145A31CC253ED12000A83B62 /* PickerTableViewCell.swift */,
145A31CD253ED12000A83B62 /* PickerTableViewCell.xib */,
145A31D5253EE15A00A83B62 /* ViewModels.swift */,
);
path = Picker;
sourceTree = "";
};
145A31D4253EE14600A83B62 /* TestMode */ = {
isa = PBXGroup;
children = (
1499C943253E4DA3003E0FE5 /* TestModeTableViewCell.swift */,
1499C944253E4DA3003E0FE5 /* TestModeTableViewCell.xib */,
);
path = TestMode;
sourceTree = "";
};
145A31E7253EF50300A83B62 /* Samples */ = {
isa = PBXGroup;
children = (
145A31F7253EF50300A83B62 /* BannerSampleViewController.swift */,
145A31E8253EF50300A83B62 /* FullscreenAdSampleViewController.swift */,
145A31E9253EF50300A83B62 /* Native */,
145A31ED253EF50300A83B62 /* NativeBannerTemplate */,
145A31F0253EF50300A83B62 /* NativeBanner */,
145A31F4253EF50300A83B62 /* NativeTemplate */,
);
path = Samples;
sourceTree = "";
};
145A31E9253EF50300A83B62 /* Native */ = {
isa = PBXGroup;
children = (
145A31EA253EF50300A83B62 /* NativeAdView.swift */,
145A31EB253EF50300A83B62 /* NativeAdScreenViewController.swift */,
145A31EC253EF50300A83B62 /* NativeAdView.xib */,
);
path = Native;
sourceTree = "";
};
145A31ED253EF50300A83B62 /* NativeBannerTemplate */ = {
isa = PBXGroup;
children = (
145A31EE253EF50300A83B62 /* NativeBannerTemplateAdScreenViewController.swift */,
145A31EF253EF50300A83B62 /* NativeBannerTemplateAdView.swift */,
);
path = NativeBannerTemplate;
sourceTree = "";
};
145A31F0253EF50300A83B62 /* NativeBanner */ = {
isa = PBXGroup;
children = (
145A31F1253EF50300A83B62 /* NativeBannerAdScreenViewController.swift */,
145A31F2253EF50300A83B62 /* NativeBannerAdView.xib */,
145A31F3253EF50300A83B62 /* NativeBannerAdView.swift */,
);
path = NativeBanner;
sourceTree = "";
};
145A31F4253EF50300A83B62 /* NativeTemplate */ = {
isa = PBXGroup;
children = (
145A31F5253EF50300A83B62 /* NativeTemplateAdView.swift */,
145A31F6253EF50300A83B62 /* NativeTemplateScreenViewController.swift */,
);
path = NativeTemplate;
sourceTree = "";
};
1468FC78252F33A5004E2CD9 /* Extensions */ = {
isa = PBXGroup;
children = (
1468FC79252F33B7004E2CD9 /* NSObject+ClassName.swift */,
1468FC7B252F33D1004E2CD9 /* UIView+NibContent.swift */,
1437CFB82538A405003DB489 /* UIViewController+Storyboard.swift */,
);
path = Extensions;
sourceTree = "";
};
1499C942253E4CDF003E0FE5 /* Settings */ = {
isa = PBXGroup;
children = (
1499C93D253E495A003E0FE5 /* SettingScreenViewController.swift */,
145A31D4253EE14600A83B62 /* TestMode */,
145A31D3253EE13800A83B62 /* Picker */,
);
path = Settings;
sourceTree = "";
};
57008FCE14BB49DABB99EE2F /* Pods */ = {
isa = PBXGroup;
children = (
4F0CF2FBCD28B527F12C5658 /* Pods-FANSample.debug.xcconfig */,
7344E3D24EBE09AC50121E89 /* Pods-FANSample.release.xcconfig */,
);
path = Pods;
sourceTree = "";
};
82B89F3923F7F95900DF6E14 = {
isa = PBXGroup;
children = (
82B89F4423F7F95900DF6E14 /* FANSample */,
82B89F4323F7F95900DF6E14 /* Products */,
57008FCE14BB49DABB99EE2F /* Pods */,
D1A18B97378710965348E129 /* Frameworks */,
);
sourceTree = "";
};
82B89F4323F7F95900DF6E14 /* Products */ = {
isa = PBXGroup;
children = (
82B89F4223F7F95900DF6E14 /* FANSample.app */,
);
name = Products;
sourceTree = "";
};
82B89F4423F7F95900DF6E14 /* FANSample */ = {
isa = PBXGroup;
children = (
145A321B253F22C800A83B62 /* README.md */,
82B89F5523F7F95B00DF6E14 /* Info.plist */,
82B89F5023F7F95B00DF6E14 /* Assets.xcassets */,
82B89F5223F7F95B00DF6E14 /* LaunchScreen.storyboard */,
82B89F4D23F7F95900DF6E14 /* Main.storyboard */,
82B89F4523F7F95900DF6E14 /* AppDelegate.swift */,
82B89F4723F7F95900DF6E14 /* SceneDelegate.swift */,
145A3205253EF57800A83B62 /* SamplesViewController.swift */,
145A31E7253EF50300A83B62 /* Samples */,
1499C942253E4CDF003E0FE5 /* Settings */,
1468FC78252F33A5004E2CD9 /* Extensions */,
14548A0F253E0DA300E62C49 /* Utils */,
);
path = FANSample;
sourceTree = "";
};
D1A18B97378710965348E129 /* Frameworks */ = {
isa = PBXGroup;
children = (
5A2B6B472CA61D8834794B3B /* Pods_FANSample.framework */,
);
name = Frameworks;
sourceTree = "";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
82B89F4123F7F95900DF6E14 /* FANSample */ = {
isa = PBXNativeTarget;
buildConfigurationList = 82B89F5823F7F95B00DF6E14 /* Build configuration list for PBXNativeTarget "FANSample" */;
buildPhases = (
A1609BF6C269CF969F41C6B1 /* [CP] Check Pods Manifest.lock */,
82B89F3E23F7F95900DF6E14 /* Sources */,
82B89F3F23F7F95900DF6E14 /* Frameworks */,
82B89F4023F7F95900DF6E14 /* Resources */,
63A734DE5EB10572F77F4766 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = FANSample;
productName = FANSample;
productReference = 82B89F4223F7F95900DF6E14 /* FANSample.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
82B89F3A23F7F95900DF6E14 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1130;
LastUpgradeCheck = 1130;
ORGANIZATIONNAME = "Facebook, Inc.";
TargetAttributes = {
82B89F4123F7F95900DF6E14 = {
CreatedOnToolsVersion = 11.3;
LastSwiftMigration = 1160;
};
};
};
buildConfigurationList = 82B89F3D23F7F95900DF6E14 /* Build configuration list for PBXProject "FANSample" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 82B89F3923F7F95900DF6E14;
productRefGroup = 82B89F4323F7F95900DF6E14 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
82B89F4123F7F95900DF6E14 /* FANSample */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
82B89F4023F7F95900DF6E14 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
82B89F5423F7F95B00DF6E14 /* LaunchScreen.storyboard in Resources */,
82B89F5123F7F95B00DF6E14 /* Assets.xcassets in Resources */,
82B89F4F23F7F95900DF6E14 /* Main.storyboard in Resources */,
1499C946253E4DA3003E0FE5 /* TestModeTableViewCell.xib in Resources */,
145A31FF253EF50300A83B62 /* NativeBannerAdView.xib in Resources */,
145A31FB253EF50300A83B62 /* NativeAdView.xib in Resources */,
145A31CF253ED12000A83B62 /* PickerTableViewCell.xib in Resources */,
145A320B253EF5BC00A83B62 /* BottomBarView.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
63A734DE5EB10572F77F4766 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-FANSample/Pods-FANSample-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-FANSample/Pods-FANSample-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FANSample/Pods-FANSample-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
A1609BF6C269CF969F41C6B1 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-FANSample-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
82B89F3E23F7F95900DF6E14 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
145A3200253EF50300A83B62 /* NativeBannerAdView.swift in Sources */,
1499C945253E4DA3003E0FE5 /* TestModeTableViewCell.swift in Sources */,
1468FC7C252F33D1004E2CD9 /* UIView+NibContent.swift in Sources */,
145A31FE253EF50300A83B62 /* NativeBannerAdScreenViewController.swift in Sources */,
14548A11253E0DC000E62C49 /* AdUtils.swift in Sources */,
145A3202253EF50300A83B62 /* NativeTemplateScreenViewController.swift in Sources */,
1499C93E253E495A003E0FE5 /* SettingScreenViewController.swift in Sources */,
145A31FD253EF50300A83B62 /* NativeBannerTemplateAdView.swift in Sources */,
82B89F4623F7F95900DF6E14 /* AppDelegate.swift in Sources */,
145A31CE253ED12000A83B62 /* PickerTableViewCell.swift in Sources */,
145A320A253EF5BC00A83B62 /* BottomBarView.swift in Sources */,
82B89F4823F7F95900DF6E14 /* SceneDelegate.swift in Sources */,
145A3203253EF50300A83B62 /* BannerSampleViewController.swift in Sources */,
145A31FA253EF50300A83B62 /* NativeAdScreenViewController.swift in Sources */,
145A31FC253EF50300A83B62 /* NativeBannerTemplateAdScreenViewController.swift in Sources */,
145A320E253EF61D00A83B62 /* NavigationController.swift in Sources */,
145A31D6253EE15A00A83B62 /* ViewModels.swift in Sources */,
1468FC7A252F33B7004E2CD9 /* NSObject+ClassName.swift in Sources */,
145A3206253EF57800A83B62 /* SamplesViewController.swift in Sources */,
145A3201253EF50300A83B62 /* NativeTemplateAdView.swift in Sources */,
145A31F8253EF50300A83B62 /* FullscreenAdSampleViewController.swift in Sources */,
1437CFB92538A405003DB489 /* UIViewController+Storyboard.swift in Sources */,
145A31F9253EF50300A83B62 /* NativeAdView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
82B89F4D23F7F95900DF6E14 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
82B89F4E23F7F95900DF6E14 /* Base */,
);
name = Main.storyboard;
sourceTree = "";
};
82B89F5223F7F95B00DF6E14 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
82B89F5323F7F95B00DF6E14 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
82B89F5623F7F95B00DF6E14 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.2;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
82B89F5723F7F95B00DF6E14 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.2;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
82B89F5923F7F95B00DF6E14 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 4F0CF2FBCD28B527F12C5658 /* Pods-FANSample.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
DEVELOPMENT_TEAM = V9WTTPBFK9;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
INFOPLIST_FILE = FANSample/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.facebook.audiencenetwork.FANSample;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "Facebook Generic";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
82B89F5A23F7F95B00DF6E14 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7344E3D24EBE09AC50121E89 /* Pods-FANSample.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
DEVELOPMENT_TEAM = V9WTTPBFK9;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
INFOPLIST_FILE = FANSample/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.facebook.audiencenetwork.FANSample;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "Facebook Generic";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
82B89F3D23F7F95900DF6E14 /* Build configuration list for PBXProject "FANSample" */ = {
isa = XCConfigurationList;
buildConfigurations = (
82B89F5623F7F95B00DF6E14 /* Debug */,
82B89F5723F7F95B00DF6E14 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
82B89F5823F7F95B00DF6E14 /* Build configuration list for PBXNativeTarget "FANSample" */ = {
isa = XCConfigurationList;
buildConfigurations = (
82B89F5923F7F95B00DF6E14 /* Debug */,
82B89F5A23F7F95B00DF6E14 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 82B89F3A23F7F95900DF6E14 /* Project object */;
}
================================================
FILE: samples/ios/FANSample/FANSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
================================================
FILE: samples/ios/FANSample/FANSample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
IDEDidComputeMac32BitWarning
================================================
FILE: samples/ios/FANSample/FANSample.xcodeproj/xcshareddata/xcschemes/FANSample.xcscheme
================================================
================================================
FILE: samples/ios/FANSample/FANSample.xcworkspace/contents.xcworkspacedata
================================================
================================================
FILE: samples/ios/FANSample/FANSample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
IDEDidComputeMac32BitWarning
================================================
FILE: samples/ios/FANSample/Podfile
================================================
# Uncomment the next line to define a global platform for your project
platform :ios, '9.0'
use_frameworks!
target 'FANSample' do
pod 'FBAudienceNetwork'
end
================================================
FILE: samples/ios/FANSample/README.md
================================================
# FANSample
This Swift sample project demonstrates how to use various ad units supported by our Facebook Ads SDK.
Native ads will give you the flexibility to render the ad in a more native format that blends into your app.
We also show how to wire up the delegate to get notified when the ad status changes over time or when the user interacts with the ad.
### Brief usage example
`FBNativeAd` can be used to show a native ad with a few simple steps:
```Swift
// Instantiate an ad with placement ID
let ad = FBNativeAd(placementID: "YOUR_PLACEMENT_ID")
// Wire up the FBNativeAdDelegate delegate (See documentation for more information).
// It is a good practice to set the delegate of the ad and implement the callback methods.
ad.delegate = self
// Load the ad
ad.loadAd()
```
More information regarding API usage can be found in the sample project.
### Samples shown in this project
- Interstitial ad (a full screen ad)
- Rewarded video ad (a full screen ad that shows a video).
- Native banner ad composed of native views.
- Native ad from template (layout that can be shown in various sizes)
- Native banner ad from template (layout that can be shown in various sizes).
### How to setup the project
1. Make sure [CocoaPods](https://cocoapods.org/) is installed on your machine.
2. Go to the project directory and run `pod install`.
3. A workspace file named `FANSample.xcworkspace` will be generated. Open it using Xcode.
4. You can find the samples under `FANSamples/Samples`. Replace "YOUR_PLACEMENT_ID" with the Placement ID you created through [developer.facebook.com](https://developers.facebook.com/).
5. Run the project either on a simulator or a device.
### Test ads
When running the project on a simulator, test ads are served by default. However, on a device real ads will be served unless you specify otherwise.
If you test your app on a device, please make sure to call the following API to enable test ads:
`FBAdSettings.addTestDevice("")`
### Additional resources
- [Audience Network Docs](https://developers.facebook.com/docs/audience-network)
- [Getting Started](https://developers.facebook.com/docs/audience-network/get-started/ios)
- [SDK Reference Documentation](https://developers.facebook.com/docs/audience-network/reference/)
================================================
FILE: samples/ios/README.md
================================================
Samples for iOS
===============
Facebook Audience Network allows you to monetize your iOS apps with Facebook ads. Here we have a list of sample apps that implements different ad placements for your reference.
Please make sure that you have completed the [Audience Network Getting Started][1] and [iOS Getting Started][2] guides before you proceed.
The sample projects are setup with [Cocoa Pods][7]. You would need to run `pod install` in the project folder from command line to download the latest Audience Network SDK.
Sample list
-----------
These sample projects include demonstration for different placement formats including [Banner][3], [Interstitial][4], [Rewarded Video][9], [In-stream Video][8] [Native][5] and [Native Banner Ads][10].
- [AdUnitsSample](./AdUnitsSample) - An Objective C sample project.
- [FANSample](./FANSample) - A Swift sample project.
[1]: https://developers.facebook.com/docs/audience-network/getting-started
[2]: https://developers.facebook.com/docs/audience-network/ios
[3]: https://developers.facebook.com/docs/audience-network/ios-banners
[4]: https://developers.facebook.com/docs/audience-network/ios-interstitial
[5]: https://developers.facebook.com/docs/audience-network/ios-native
[8]: https://developers.facebook.com/docs/audience-network/ios/instream-video
[9]: https://developers.facebook.com/docs/audience-network/ios/rewarded-video
[10]: https://developers.facebook.com/docs/audience-network/ios-native-banner
================================================
FILE: samples/python/ReportingAPISamples/.gitignore
================================================
# Created by .ignore support plugin (hsz.mobi)
### Python template
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# IPython Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# dotenv
.env
# virtualenv
venv/
ENV/
# Spyder project settings
.spyderproject
# Rope project settings
.ropeproject
### VirtualEnv template
# Virtualenv
# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/
.Python
[Bb]in
[Ii]nclude
[Ll]ib
[Ll]ib64
[Ll]ocal
[Ss]cripts
pyvenv.cfg
.venv
pip-selfcheck.json
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff:
.idea/workspace.xml
.idea/tasks.xml
.idea/dictionaries
.idea/vcs.xml
.idea/jsLibraryMappings.xml
# Sensitive or high-churn files:
.idea/dataSources.ids
.idea/dataSources.xml
.idea/dataSources.local.xml
.idea/sqlDataSources.xml
.idea/dynamic.xml
.idea/uiDesigner.xml
# Gradle:
.idea/gradle.xml
.idea/libraries
# Mongo Explorer plugin:
.idea/mongoSettings.xml
.idea/
## File-based project format:
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
================================================
FILE: samples/python/ReportingAPISamples/CONTRIBUTING.md
================================================
# Contributing to audience-network-reporting-api-samples
We want to make contributing to this project as easy and transparent as possible.
## Our Development Process
audience-network-reporting-api-samples is maintained and developed on github.
Send us your pull requests, and we'd be happy to provide feedback and merge as appropriate.
## Pull Requests
We actively welcome your pull requests.
1. Fork the repo and create your branch from `master`.
2. If you've added code that should be tested, add tests
3. If you've changed APIs, update the documentation.
4. Make sure your code lints (e.g., pyflakes, PEP8, etc)
5. If you haven't already, complete the Contributor License Agreement ("CLA").
## Contributor License Agreement ("CLA")
In order to accept your pull request, we need you to submit a CLA. You only need
to do this once to work on any of Facebook's open source projects.
Complete your CLA here:
## Issues
We use GitHub issues to track public bugs. Please ensure your description is
clear and has sufficient instructions to be able to reproduce the issue.
## License
By contributing to audience-network-reporting-api-samples, you agree that your contributions will be licensed
under the LICENSE file in the root directory of this source tree.
================================================
FILE: samples/python/ReportingAPISamples/LICENSE.md
================================================
BSD License
For audience-network-reporting-api-samples software
Copyright (c) 2017-present, Facebook, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name Facebook nor the names of its contributors may be used to
endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================
FILE: samples/python/ReportingAPISamples/PATENTS.md
================================================
Additional Grant of Patent Rights Version 2
"Software" means the audience-network-reporting-api-samples software contributed by Facebook, Inc.
Facebook, Inc. ("Facebook") hereby grants to each recipient of the Software
("you") a perpetual, worldwide, royalty-free, non-exclusive, irrevocable
(subject to the termination provision below) license under any Necessary
Claims, to make, have made, use, sell, offer to sell, import, and otherwise
transfer the Software. For avoidance of doubt, no license is granted under
Facebook’s rights in any patent claims that are infringed by (i) modifications
to the Software made by you or any third party or (ii) the Software in
combination with any software or other technology.
The license granted hereunder will terminate, automatically and without notice,
if you (or any of your subsidiaries, corporate affiliates or agents) initiate
directly or indirectly, or take a direct financial interest in, any Patent
Assertion: (i) against Facebook or any of its subsidiaries or corporate
affiliates, (ii) against any party if such Patent Assertion arises in whole or
in part from any software, technology, product or service of Facebook or any of
its subsidiaries or corporate affiliates, or (iii) against any party relating
to the Software. Notwithstanding the foregoing, if Facebook or any of its
subsidiaries or corporate affiliates files a lawsuit alleging patent
infringement against you in the first instance, and you respond by filing a
patent infringement counterclaim in that lawsuit against that party that is
unrelated to the Software, the license granted hereunder will not terminate
under section (i) of this paragraph due to such counterclaim.
A "Necessary Claim" is a claim of a patent owned by Facebook that is
necessarily infringed by the Software standing alone.
A "Patent Assertion" is any lawsuit or other action alleging direct, indirect,
or contributory infringement or inducement to infringe any patent, including a
cross-claim or counterclaim.
================================================
FILE: samples/python/ReportingAPISamples/README.md
================================================
# Audience Network Reporting API Samples
The Audience Network Reporting API lets you automate downloading performance data for
your Business and Properties. This sample project walks through key API features and use cases
in Python to send requests (sync or async) to fetch performance data and save them as .csv file.
The API now supports sync (GET request) and async (POST request). Sync requests are
light and immediately return data. Async requests are designed to handle heavier data
loads and return a query ID for you to retrieve the data at a later time. More info below.
This repository includes contents as follows:
## Recommendation
We highly recommend you include our adnw_examples.py into your project because those examples are the best practices for
accessing our end point.
After you fetch query ids successfully, please wait for a few seconds (i.e. 10 seconds) before you send another "async" request with
query ids such that you are guaranteed to get results. Also, please do not try to request more than 50 times within 60 seconds.
## Run Reporting API Examples
In adnw_examples.py, it provides examples using adnw_requests to build sync and async requests
to get data. Uncomment corresponding test cases in adnw_examples.py and run it.
## Versions
The python version is 3.6.
The [requests library](https://github.com/requests/requests) version is 2.18.4.
================================================
FILE: samples/python/ReportingAPISamples/adnw_examples.py
================================================
from adnw_requests import *
from adnw_utils import *
from adnw_response import *
from time import sleep
import datetime
""" Run sync request, but there are some limitations.
Support only one metric and two max breakdowns per request.
"""
def run_sync_request(app_id, access_token):
builder = ADNWRequestBuilder(app_id, access_token)
builder.add_metric(Metric.ADNW_REQUEST)
builder.add_filter(Filter(Breakdown.COUNTRY, FilterOperator.IN, ['US', 'JP']))
builder.add_filter(Filter(Breakdown.PLATFORM, FilterOperator.IN, ['ios', 'android', 'unknown']))
builder.add_breakdown(Breakdown.COUNTRY)
builder.add_breakdown(Breakdown.PLATFORM)
builder.set_date_range(datetime.date(2018, 4, 1), datetime.date(2018, 4, 1))
builder.set_limit(MAX_ROW_LIMIT_SYNC)
sync_request = builder.build_sync_request()
ADNWResponse.get_instance().validate_response(sync_request)
adnw_utils.write_to_csv(sync_request.json())
""" Run async request to get request id (no limitations on params),
then run sync request with request id.
No max metric and breakdowns per request.
"""
def run_async_request_1(app_id, access_token):
builder = ADNWRequestBuilder(app_id, access_token)
builder.add_metric(Metric.ADNW_IMPRESSION)
builder.add_metric(Metric.ADNW_REQUEST)
builder.add_filter(Filter(Breakdown.COUNTRY, FilterOperator.IN, ['US', 'JP']))
builder.add_filter(Filter(Breakdown.PLATFORM, FilterOperator.IN, ['ios', 'android']))
builder.add_breakdown(Breakdown.COUNTRY)
builder.add_breakdown(Breakdown.PLACEMENT)
builder.set_date_range(datetime.date(2018, 4, 1), datetime.date(2018, 4, 1))
builder.set_limit(MAX_ROW_LIMIT_ASYNC)
async_request = builder.build_async_request()
adnw_response = ADNWResponse.get_instance()
adnw_response.validate_response(async_request)
query_id = adnw_response.get_query_id(async_request.json())
print("Successfully get valid query id: " + query_id)
return query_id
""" Run multiple async request to get request ids (no limitations on params),
then run sync request with multiple request ids.
No max metric and breakdowns per request.
"""
def run_async_request_2(app_id, access_token):
builder = ADNWRequestBuilder(app_id, access_token)
builder.add_metric(Metric.ADNW_CMP)
builder.add_metric(Metric.ADNW_CLICK)
builder.add_filter(Filter(Breakdown.COUNTRY, FilterOperator.IN, ['MK', 'SB']))
builder.add_filter(Filter(Breakdown.PLATFORM, FilterOperator.IN, ['ios', 'unknown']))
builder.add_breakdown(Breakdown.PLATFORM)
builder.add_breakdown(Breakdown.PLACEMENT)
builder.set_limit(MAX_ROW_LIMIT_ASYNC)
async_request = builder.build_async_request()
adnw_response = ADNWResponse.get_instance()
adnw_response.validate_response(async_request)
query_id = adnw_response.get_query_id(async_request.json())
print("Successfully get valid query id: " + query_id)
return query_id
def run_async_request_for_result_1(app_id, access_token):
query_id = run_async_request_1(app_id, access_token)
"""The waiting period here is to make sure the results have been generated on our backend."""
sleep(10)
try_run_async_request_with_query_ids(app_id, access_token, [query_id])
def run_async_request_for_result_2(app_id, access_token):
query_id_1 = run_async_request_1(app_id, access_token)
query_id_2 = run_async_request_2(app_id, access_token)
"""The waiting period here is to make sure the results have been generated on our backend."""
sleep(10)
try_run_async_request_with_query_ids(app_id, access_token, [query_id_1, query_id_2])
def try_run_async_request_with_query_ids(app_id, access_token, query_ids: [string]):
for i in range(0, 3):
try:
run_async_request_with_query_ids(app_id, access_token, query_ids)
break
except adnw_exception.ValidationError as error:
print(error.message)
"""Waiting 60 seconds if first async request fails, because clustering too many requests
in our backend will slow your process of fetching results."""
sleep(60)
continue
def run_async_request_with_query_ids(app_id, access_token, query_ids: [string]):
builder = ADNWRequestBuilder(app_id, access_token)
builder.set_query_ids(query_ids)
sync_request = builder.build_sync_request_with_query_ids()
ADNWResponse.get_instance().validate_response(sync_request)
adnw_utils.write_to_csv(sync_request.json())
if __name__ == '__main__':
"""Replace with your app_id and valid access_token to start your testing."""
_app_id = "YOUR_APP_ID"
_access_token = "USER_ACCESS_TOKEN"
"""Uncomment corresponding function for testing."""
# run_sync_request(_app_id, _access_token)
run_async_request_for_result_1(_app_id, _access_token)
# run_async_request_for_result_2(_app_id, _access_token)
================================================
FILE: samples/python/ReportingAPISamples/adnw_exception.py
================================================
class ValidationError(Exception):
def __init__(self, message, errors=None):
super().__init__(message)
self.errors = errors
self.message = message
class HttpResponseError(Exception):
def __init__(self, message, errors=None):
super().__init__(message)
self.errors = errors
self.message = message
class InvalidQueryIdError(Exception):
def __init__(self, message, errors=None):
super().__init__(message)
self.errors = errors
self.message = message
================================================
FILE: samples/python/ReportingAPISamples/adnw_params.py
================================================
import enum
import string
# Params Key
METRICS = 'metrics'
BREAKDOWNS = 'breakdowns'
FILTERS = 'filters'
VALUES = 'values'
ORDERING_COLUMN = 'ordering_column'
ORDERING_TYPE = 'ordering_type'
LIMIT = 'limit'
AGGREGATION_PERIOD = 'aggregation_period'
Date_SINCE = 'since'
Date_UNTIL = 'until'
# Required Parameters for Sync Request without query ids
class Metric(enum.Enum):
ADNW_REVENUE = 'fb_ad_network_revenue'
ADNW_REQUEST = 'fb_ad_network_request'
ADNW_CMP = 'fb_ad_network_cpm'
ADNW_CLICK = 'fb_ad_network_click'
ADNW_IMPRESSION = 'fb_ad_network_imp'
ADNW_FILLED_REQUEST = 'fb_ad_network_filled_request'
ADNW_FILL_RATE = 'fb_ad_network_fill_rate'
ADNW_CTR = 'fb_ad_network_ctr'
ADNW_SHOW_RATE = 'fb_ad_network_show_rate'
ADNW_VIDEO_GUARANTEE_REVENUE = 'fb_ad_network_video_guarantee_revenue'
ADNW_VIDEO_VIEW = 'fb_ad_network_video_view'
ADNW_VIDEO_VIEW_RATE = 'fb_ad_network_video_view_rate'
ADNW_VIDEO_MRC = 'fb_ad_network_video_mrc'
ADNW_VIDEO_MRC_RATE = 'fb_ad_network_video_mrc_rate'
ADNW_BIDDING_REQUEST = 'fb_ad_network_bidding_request'
ADNW_BIDDING_RESPONSE = 'fb_ad_network_bidding_response'
# Optional Parameters
class Breakdown(enum.Enum):
COUNTRY = 'country'
DELIVERY_METHOD = 'delivery_method'
PLATFORM = 'platform'
APP = 'app'
PROPERTY = 'property'
PLACEMENT = 'placement'
DEAL = 'deal'
class FilterOperator(enum.Enum):
IN = 'in'
class Filter:
def __init__(self, condition: Breakdown, operator: FilterOperator, filters: [string]):
self.condition = condition
self.operator = operator
self.filters = filters
def raw_value(self):
return {'field': self.condition.value,
'operator': self.operator.value,
'values': self.filters}
def __hash__(self):
return self.condition.__hash__()
def __eq__(self, other):
return self.condition == other.condition
class OrderingColumn(enum.Enum):
TIME = 'time'
VALUE = 'value'
class OrderingType(enum.Enum):
ASCENDING = 'ascending'
DESCENDING = 'descending'
class AggregationPeriod(enum.Enum):
DAY = 'day'
TOTAL = 'total'
================================================
FILE: samples/python/ReportingAPISamples/adnw_requests.py
================================================
import datetime
import requests
import json
import adnw_utils
from adnw_params import *
# Base URL
BASE_URL = 'https://graph.facebook.com'
API_VERSION = 'v10.0'
ADNW_REQUEST_API = '/adnetworkanalytics'
ADNW_REQUEST_API_BY_QUERY_IDS = '/adnetworkanalytics_results'
ACCESS_TOKEN_KEY = 'access_token'
QUERY_IDS = 'query_ids'
MAX_ROW_LIMIT_ASYNC = 10000
MAX_ROW_LIMIT_SYNC = 1000
now = datetime.datetime.now()
date_format = "%Y-%m-%d"
class ADNWRequestBuilder(object):
def __init__(self, app_id: string, access_token: string):
self.url = BASE_URL + '/' + API_VERSION + '/' + app_id
self.access_token = access_token
self.metrics = set()
self.breakdowns = set()
self.date_since = now.date() + datetime.timedelta(days=-6)
self.date_until = now.date()
self.filters = set()
self.ordering_column = OrderingColumn.TIME
self.ordering_type = OrderingType.ASCENDING
self.limit = MAX_ROW_LIMIT_SYNC
self.aggregation_period = AggregationPeriod.DAY
self.query_ids = set()
def add_metrics(self, metrics: [Metric]):
self.metrics.add(metrics)
def add_metric(self, metric: Metric):
self.metrics.add(metric)
def add_breakdowns(self, breakdowns: [Breakdown]):
self.breakdowns.add(breakdowns)
def add_breakdown(self, breakdown: Breakdown):
self.breakdowns.add(breakdown)
def set_date_range(self, date_since: datetime.date, date_until: datetime.date):
self.date_since = date_since
self.date_until = date_until
def add_filters(self, filters: [Filter]):
self.filters.add(filters)
def add_filter(self, _filter: Filter):
self.filters.add(_filter)
def set_ordering_type(self, ordering_type: OrderingType):
self.ordering_type = ordering_type
def set_ordering_column(self, ordering_column: OrderingColumn):
self.ordering_column = ordering_column
def set_aggregation_period(self, aggregation_period: AggregationPeriod):
self.aggregation_period = aggregation_period
def set_limit(self, limit: int):
self.limit = limit
def set_query_ids(self, query_ids: [string]):
self.query_ids = query_ids
""" Build sync request with provided params."""
def build_sync_request(self):
sync_url = self.url + ADNW_REQUEST_API + '/'
self.validate_params()
return requests.get(sync_url, self.get_params())
""" Build sync request with query ids and access token.
Any other param will be ignored.
"""
def build_sync_request_with_query_ids(self):
sync_url = self.url + ADNW_REQUEST_API_BY_QUERY_IDS + '/'
print("You are using query ids to get results."
" The fields except for query ids and access token will be ignored.")
self.validate_params(is_using_query_ids=True)
params = {
ACCESS_TOKEN_KEY: self.access_token,
QUERY_IDS: json.dumps(self.query_ids)
}
return requests.get(sync_url, params)
""" Build async request to fetch query id."""
def build_async_request(self):
async_url = self.url + ADNW_REQUEST_API + '/'
self.validate_params(is_sync_request=False)
return requests.post(async_url, json=self.get_params())
def get_params(self):
metrics_list = list(map(adnw_utils.raw_value, self.metrics))
breakdowns_list = list(map(adnw_utils.raw_value, self.breakdowns))
filters_list = list(map(adnw_utils.raw_statement, self.filters))
return {
ACCESS_TOKEN_KEY: self.access_token,
METRICS: json.dumps(metrics_list),
BREAKDOWNS: json.dumps(breakdowns_list),
Date_SINCE: self.date_since.strftime(date_format),
Date_UNTIL: self.date_until.strftime(date_format),
FILTERS: json.dumps(filters_list),
ORDERING_COLUMN: self.ordering_column.value,
ORDERING_TYPE: self.ordering_type.value,
LIMIT: self.limit,
AGGREGATION_PERIOD: self.aggregation_period.value
}
def validate_params(self, is_sync_request: bool = True, is_using_query_ids: bool = False):
if not is_using_query_ids and len(self.metrics) == 0:
raise Exception("The parameter metrics is required.")
diff = (self.date_until - self.date_since).days
if diff >= 7 or diff < 0:
print("date since: " + str(self.date_since))
print("date since: " + str(self.date_until))
if diff >= 7:
raise Exception("The time range needs to be at most 7 days.")
if diff < 0:
raise Exception("The time range is invalid.")
if is_sync_request:
if len(self.metrics) > 1:
raise Exception("The parameter metrics cannot be more than 1 with Sync Request.")
if len(self.breakdowns) > 2:
raise Exception("The parameter breakdowns cannot be more than 2 with Sync Request.")
if self.limit > 1000:
raise Exception("The parameter limit cannot be more than 1000 with Sync Request.")
else:
if self.limit > 10000:
raise Exception("The parameter limit cannot be more than 10000 with Async Request.")
if is_using_query_ids:
if len(self.query_ids) <= 0:
raise Exception("The query ids are not valid in the request.")
================================================
FILE: samples/python/ReportingAPISamples/adnw_response.py
================================================
import json
import requests
import adnw_utils
import adnw_exception
class ADNWResponse(object):
__instance = None
@staticmethod
def get_instance():
if ADNWResponse.__instance is None:
ADNWResponse()
return ADNWResponse.__instance
def __init__(self):
if ADNWResponse.__instance:
raise Exception("ADNWResponse class is a singleton!")
else:
ADNWResponse.__instance = self
""" Check error message if status_code is not 200.
Validate response (make sure the status in Json is "complete")
from sync request with query ids if status_code is 200.
"""
def validate_response(self, _request: requests.request):
_json = _request.json()
if _request.status_code != 200:
_error = _json["error"]
_message = _error["message"]
raise adnw_exception.HttpResponseError(_message)
else:
try:
_data = _json["data"]
if adnw_utils.is_list_empty(_data):
raise adnw_exception.InvalidQueryIdError("query id is invalid.")
else:
for each in _data:
if each["status"] != "complete":
raise adnw_exception.ValidationError("Report is not ready in Backend, please retry later.")
except KeyError:
return
def get_query_id(self, _json: json):
try:
query_id = _json["query_id"]
except KeyError:
raise adnw_exception.InvalidQueryIdError("Unable to get valid query id.")
return query_id
================================================
FILE: samples/python/ReportingAPISamples/adnw_utils.py
================================================
from adnw_params import *
import datetime
import json
import csv
import shutil
import os.path
flat_item = {}
REPORTS_DIR = 'csv_reports'
def raw_value(enum_val: enum.Enum):
return enum_val.value
def raw_statement(_filter: Filter):
return _filter.raw_value()
def validate(date_text: string):
try:
datetime.datetime.strptime(date_text, '%Y-%m-%d')
except ValueError:
raise ValueError("Invalid data format, should be YYYY-MM-DD")
""" Flatten nested Json object."""
def flatten_item(value, key=None):
global flat_item
if type(value) is list:
for item in value:
flatten_item(item)
elif type(value) is dict:
(sub_key, sub_value) = add_separated_key_value_if_needed(value)
if not (sub_key or sub_value):
for (sub_key, sub_value) in value.items():
flatten_item(sub_value, sub_key)
else:
flat_item[sub_key] = sub_value
elif type(key) is str:
flat_item[key] = value
""" Flatten nested Json and save to csv file"""
def write_to_csv(_json: json):
if os.path.exists(REPORTS_DIR):
shutil.rmtree(REPORTS_DIR)
if not _json:
print("Failed to writing results to csv, json results: \n" + str(_json))
return
flat_datas = list()
global flat_item
data_array = _json["data"]
for data in data_array:
flat_items = list()
for item in data["results"]:
flat_item = {}
flatten_item(item)
flat_items.append(flat_item)
flat_datas.append(flat_items)
if is_list_empty(flat_datas) or is_list_empty(flat_datas[0]):
print("Failed to writing results to csv, json results: \n" + str(_json))
return
if not os.path.exists(REPORTS_DIR):
os.makedirs(REPORTS_DIR)
i = 0
for flat_items in flat_datas:
if is_list_empty(flat_items):
continue
csv_output = csv.DictWriter(open(REPORTS_DIR + "/report_" + str(i) + ".csv", "w+"), flat_items[0].keys(), quoting=csv.QUOTE_ALL)
csv_output.writeheader()
for flat_item in flat_items:
csv_output.writerow(flat_item)
i += 1
print("json response: " + str(_json))
print("Finish writing results to csv, check 'csv_reports/report.csv' in root directory.")
def add_separated_key_value_if_needed(node: dict):
key = None
value = None
for (sub_key, sub_value) in node.items():
if sub_key == 'key':
key = sub_value
elif sub_key == 'value':
value = sub_value
else:
break
return key, value
def is_list_empty(_list: list):
return _list is None or len(_list) == 0