Facebook 的 Audience Network 跟 Admob 有何区别,有竞争力的薪酬如何

如何在 iOS App 中整合 Facebook 广告
不久前有人问我如何在项目中集成 Facebook 的广告。因为之前没用过,以为一定很难,所以事先查阅了大量文档。在通读完文档之后,发现其实并不是很难,仅仅几分钟我就能够搞定我的第一个 Facebook 广告 App!
Facebook 广告是一种将广告集成到你的 app 中的方法,使你可以通过广告的点击量来获得收入。这个方法(集成广告)并不复杂,在Facebook SDK(一个 Facebook 推出的 SDK 框架)中,有一个框架是和广告相关的,那就是
框架。 你只需在 app 中使用这个框架就行了。
Facebook 为不同的平台提供了不同的广告类型,但对于移动设备来说只有 3 种类型:Native, Interstitial, 和 Banners。下面简单介绍一下这 3 种类型:
Native 广告能放置在 app 的任何地方,它们能被重新定制,从外观上看它们与视图上的其它 UI 毫无区别。这些视图可以来自于手动创建的 view (通过自定义控件展现广告内容),也可以来自于 Audience Network 框架中的模板──但它们的某些属性可以被定制。有一点特别的地方是,如果要在 table view 中显示这些广告,你只有两种办法:要么使用自定义 view(也就是自定义 cell)显示广告,然后手动处理所有相关的 table view 回调,要么使用 Audience Network 框架(诚挚感谢)提供的类,然后(几乎)不用你处理 table view 的回调。唯一的缺点是用这种方式你无法自定义广告的外观,当然在某些情况下这也不是什么问题。 Interstitial(插页式)广告是全屏广告,如你所料,它们一旦显示就会将 app 整个遮住。因此,这类广告的外观根本不需要任何定制。 Banner(横幅)广告是小幅面广告,经常显示在屏幕的顶部或底部,它们除高度外都不能被定制。
我们会在本文中介绍这 3 种广告,此外还会演示如何在 Facebook Developers portal 中进行必要的设置。也就是说,我会指引你配置 app 的广告显示能力以及其它(广告内容、布局信息等等)。给你一个永远正确的老忠告:看文檔去(即&去读该死的手册&)。
你也许会问&既然将 Facebook 广告集成到 app 中很容易,那还写什么教程?&。主要是出于两个目的:第一,网上基本没有能让人一目了然的教程,我觉得有必要写一个让人立马就明白怎样在 app 中集成广告的快捷指南,以节省大家的时间。第二,Facebook 文档中的所有示例程序代码都是 Objective-C 的,对于只会 Swift 的新人来说,将 O-C 的示例程序代码翻译成 Swift 会是一个不小的挑战。
最后,需要说明的是,后面演示的示例项目(你可以下载它)都是用 Xcode 7.3.1 和 Swift 2.2 编写的。这两者都目前有效的正式版本,请不要在 Swift 3.0 中打开和运行它。
关于示例 app
能让我们学习和研究的文章,毫无例外都会要求你亲自动手。本教程也不例外,它也会有一个 demo app。为了将注意力集中在将 Facebook 广告集成到 app 中,这个 app 被设计得很简单。你可以从下载开始项目,通过它我们会一步一步完成最终的 app。
这个 app 是一个 tab bar app,包含了 4 个 tab,每个 tab 显示一种广告类型:
第一个 tab 包含的 view controller 是SingleAdsViewController,这是 native 类型的广告。注意,我们不仅会演示自定义 view 的 native 广告,还会演示&模板化&的 native 广告,我们通过覆盖它的属性(而不是自定义 view)来进行定制。 第二个 tab 包含的 view controller 是 TableViewAdsViewController。它使用了 table view 来显示广告,只不过这次我们会使用到 Audience Network 框架提供的工具。如果你下载并运行开始项目,你会在 table view 中看到一些示范数据。我们的目的是在那些显示示范数据的行之间插入广告。 第三个 tab 包含的 view controller 叫做 FullScreenAdsViewController。当我们点击按钮时它会显示一个全屏广告。 最后一个 view controller 是 BannerAdsViewController 。你猜得不错,它会显示横幅广告。
下面的截图显示了我们的最终效果:
Native 广告──使用自定义 view:
在 table view 中显示 Native 广告:
接下来我们提到的内容在大部分情况下都适用。如果你想对某些方面进行更细致的调整,你应当仔细官方文档──这会让你对这个主题有更深刻的理解!
首先我们要介绍的是 Facebook Developers portal,因为我们必须在这里进行一些操作,并获取一些重要数据。简单说,你需要新建一个 Facebook app 并进行一些配置,最终获得几个 ID,要在你的 app 中显示广告,你必须用到这些 ID。
让我们详细说明。首先,用任意登录你的 Facebook 账号(你肯定有的吧?)。进入
并点击绿色的 Start Now 按钮。你会看到弹出一个窗口,在这个窗口中你需要:
输入 app 的名字。 选择目标平台为 iOS。 在输入 app 名字时,点击 Link to Facebook。这会创建一条新记录,并添加在 Facebook Developer portal 的 My Apps 中。这一步至关重要,千万不要遗漏。
然后,form 中会多出两栏:一栏要你填入一个 email 地址作为你的联系邮箱,第二栏要你选择一个和该 app 相符的类型。
填完这些信息后,点击 Sign Up 按钮。通过安全检查后进入下一步。如果没有任何错误,你将看到一个设置界面,即 Audience Network 产品的 Placements 设置。这是一个关键的地方,这里会创建 placement ID,这个 ID 将用于在 app 中显示广告。一个 placement 表示一个广告在 app 中的位置,Facebook 通过创建这些 placement 来搜集用户的点击,并用于对广告的显示提供建议和优化。
向下滚动页面,你会看到已经有一个 placement 自动创建了。在我们的 demo app 中,需要 4 个 placement ID,因此还需要创建其它的。你只需要点击 Create Ad Placement 按钮,然后在新弹出窗口中输入信息。
demo 中的第一个广告是一个 native 广告,我们会用一个按钮来加载和显示这个广告。这个新 placement 的详细配置如下:
配置完成后,请点击 Save 按钮,新建的 placement 会在设置页面列出。第二个广告实际上是在第二个 tab 的 view controller 的 table view 中显示的一系列 native 广告,因此第二个 placement 的详细设置如下:
第三个广告是一个全屏广告。
我把第四个广告的 placement ID 的配置留给你练习。对于这个 placement,你可以在自动添加的基础上加以编辑,也可以创建一个新的。记住,横幅广告也可以在某个按钮被点击时显示。
注意,每个新的 placement 添加到设置页面后,都会被分配给一个 Placement ID 值,我们将在后面用到这个 ID。
另外,如果你点击 Get Code 按钮,你会立即看到关于使用这个广告和 placement ID 的示例程序代码。遗憾的是:它们是 Objective-C 的,因此你需要自行转换成 Swift 的。不用担心,这会在后续步骤进行讲解。
继续后面的内容之前,有一件事情是你必须知道的。根据文档描述,只允许以两种方式在 app 中运行 测试广告:
在仿真器中运行 app。 如果通过 Xcode 调试真机上的 app,则需要遵循如下步骤(摘自 Facebook 官方文檔):
要在设备上开启测试广告功能,要在加载广告之前加入一行程序代码: [FBAdSettings addTestDevice:@&HASHED ID&]; 。这个 hashed ID 会在第一次在设备上请求加载广告时打印到控制台中。
换句话说,当你在设备上运行 app 时,会分配一个 hashed ID 给指定设备(通过控制台中输出)。你通过这个 ID 表示你想测试这台设备上的广告。
除此之外,你的 app 从 Facebook 请求到的将是真正的广告,在 Facebook 审查团队审查 app 之前你不会看到广告。审查会在你将 app 发布到公网(比如 App Store 或者某个企业商店)之后开始,因为这时审查团队才能够下载你的 app。如果 app 通过审查,你的 app 就会播放真正的广告,否则广告不会显示。
因此,需要你将 app 的 URL 输入到文本框,以便审查团队下载 app,这个文本框会显示在 Facebook Developers portal 的 Placement 设置页顶端(你可能已经看到它了)。在这个地方输入 app 的下载地址(如果你已经有这个 URL 的话), 然后等候评审(几天)。然后不时来 portal 看一下 app 的 Alerts 区域,评审结果会在这里显示。
App 的设置
做完 Facebook 的设置之后,下载开始项目,我们还需要在项目中进行一些设置。首先是加入 Facebook Audience Network 框架,有两种加入方式:
使用 Cocoapods 下载 Facebook iOS SDK 并手动将框架加入到项目中
在的 Set Up the SDK 一节,两种方式都进行了介绍。对我来说,我宁可自己下载 SDK,然后将 Facebook Audience Network 框架直接拖进Xcode中。
当你以两种方式中的任何一种将框架加到项目中以后,你必须添加另外三个依赖框架。在项目导航器中,点击项目的名称,然后在 General
窗口中找到 Linked Frameworks and Libraries 一节。点击 + (加号) 按钮三遍,依次添加这三个框架:
StoreKit CoreMotion AdSupport
如我所说,Facebook SDK 是使用 Objective-C 编写的,因此我们要使用一个 bridging header 文件去导入这个库,这样才能在 Swift 代码中使用它。这个过程非常简单,操作步骤如下:
在 Xcode 中,点击菜单 File & New & File&。 在文件模板窗口,选择 iOS 下面的 Source。 选择 header file 模板。 将文件命名为 AdsTutorial-Bridging-Header.h 并保存。
然后你会在项目导航器中看到新创建的这个文件,选中它,将下列内容粘贴进文件中:
接下来,再次在专案导航器中选中项目名称,点击 Build Settings tab,确保显示的是 All 设置,然后在右边搜索栏中搜索 Bridging Header 字符串。双击搜索结果的内容区域(即 Objective-C Bridging Header 文字的右边),输入或者粘贴进如下内容:
AdsTutorial/AdsTutorial-Bridging-Header.h
回车,设置完毕。项目的设置就到这里结束了,接下来开始实现。
显示 Native 广告
我也说过了,native 广告的外观可以被完全定制化,甚至可以和 app 中的其他 UI 变得一模一样。有两种方法可以做到这点。第一种方法是手动创建所有的 view 和 subview 然后显示广告内容。第二种方法是使用标准模板,然后覆盖某些属性(比如颜色和字体),这种方法不需要手动创建 view。我们两种方法都会介绍,这一节先介绍第一种方法。无论是哪种方法,我们在 app 不会显示其它无关的内容,以使问题简化。
当你在 Interface Builder(即点击 Main.storyboard 文件),你会看到一颗按钮,我们会用它来加载广告;以及一个 view(上面有几个 subview ),我们将用它显示我们请求到的广告的内容。这些控件都已经和 SingleAdsViewController 类中的 IBOutlet 属性建好了连接。让我们一一列数一下:
viewAdContainer: 一个容器,包含了用于显示广告内容的其他 subview。在 app 一启动时,这个 view 是隐藏的,因为广告还没有加载进来。 lblAdTitle: 一个 label,用于显示广告标题。 lblAdBody: 一个 label,用于显示广告的主体文字。 imgAdIcon: 一个 image view,用于显示广告图标。 btnAdAction: 一个 call-to-action 按钮,当它被点击时,会打开广告详情(全屏方式)。另外,容器 view 也可以触发全屏广告的显示。我两者都会使用。 lblSocialContext: 一个 label,用于显示类似于 &Available on the App Store& 的消息。
在请求广告时,需要注意一件事情,广告的基本字段总是有值的(比如 title 和 icon),但其它字段则有可能为空(nil),为了避免意外闪退,你必须对这种情况进行处理。正如稍后你会看到的。
现在,开始进入编码。首先,在所有 IBOutlet 属性声明之后添加两个属性:
var nativeAd: FBNativeAd!
var coverMediaView: FBMediaView!
nativeAd 对象代表 app 中的 native 广告,在我们的实现过程中我们会使用得非常多。你可以在
找到 FBNativeAd 类的所有细节。coverMediaView 是一种特殊的 view( UIView 对象),能够显示广告中包含的各种媒体、图片或视频。它只能由程序员手动创建,无法在 Single Ads View Controller 场景(Interface Builder)中以可视化控件的方式使用它。 如果你想进一步了解 FBMediaView,可以阅读 。
首先用到的是 nativeAd 对象,用它来尝试下载一个广告(也就是请求一个广告)。这个动作会在 Load Ad 按钮被点击时发生,因此我们需要在 loadNativeAd(_:) IBAction 方法中编写程序代码。这个方法在这个按钮被点击时触发。这是该方法的实现:
@IBAction func loadNativeAd(sender: AnyObject) {
nativeAd = FBNativeAd(placementID: &PLACEMENT_ID&)
nativeAd.delegate = self
nativeAd.loadAd()
通常,我们先使用第一行程序代码去实例化 nativeAd 对象。在运行 app 之前,你应当将 &PLACEMENT_ID& 字符串替换成你自己的 Placement ID,这个 ID 是你先前所创建的。你可以从 Audience Network 设置页面中复制该 native 广告的 placement ID,并将它粘贴到这里。然后,将 nativeAd 的委托设置为 self,以便我们下一步进行处理。最后,调用 loadAd() 方法请求并获取一个广告。
另外,你可以进一步指定 nativeAd 的 缓存选项。这样 Audience Network Framework 会事先缓存广告中使用的图片和视频。例如,当你想让视频在被加载之后立即播放,你可以在加载广告之前设置缓存选项为:
nativeAd.mediaCachePolicy = FBNativeAdsCachePolicy.Video
默认不使用预缓存机制。要查看所有可用的缓存选项列表,请阅读 。
接下来我们应当采用
协议。先前我们已经将 SingleAdsViewController 类设置为 nativeAd 的委托属性,但我们还没有让我们的类采用这个协议。找到类的第一行,将其修改为:
class SingleAdsViewController: UIViewController, FBNativeAdDelegate {
FBNativeAdDelegate 协议中包含的方法很少。但是,其中有两个方法是必须实现是,因为它们是唯一可以让我们知道广告加载是否成功或失败的方法,剩下的方法都是可选的,实现不实现随便你了。这两个方法分别实现如下:
func nativeAdDidLoad(nativeAd: FBNativeAd) {
handleLoadedNativeAdUsingCustomViews()
func nativeAd(nativeAd: FBNativeAd, didFailWithError error: NSError) {
print(error)
你可以在这里实现更好的错误处理,这里我只是简单打印错误而已。主要是 nativeAdDidLoad(_:) 委托方法,正如其名,它可以让我们指定当广告加载成功后的处理。在此我必须说明一点,我们将在下一部分(也就是视图模板的使用)也会使用相同的委托方法,当然在广告加载后的处理是截然不同的。因此,我会根据不同情况调用不同的自定义方法进行处理,在本文中这会让事情变得简单。
在 handleLoadedNativeAdUsingCustomViews() 方法,我们会将广告数据赋给不同的 view,并确保数据有确定的值。我们先来看一下实现的第一步,后续还会在此基础上不断添加。为便于理解,程序代码中添加了批注:
func handleLoadedNativeAdUsingCustomViews() {
// 设置广告标题
lblAdTitle.text = nativeAd.title
// 设置广告文本(如果有的话).
if let body = nativeAd.body {
lblAdBody.text = body
// 设置 call-to-action 按钮的标题
btnAdAction.setTitle(nativeAd.callToAction, forState: UIControlState.Normal)
// 加载并显示广告图片
nativeAd.icon?.loadImageAsyncWithBlock({ (iconImage) in
if let image = iconImage {
self.imgAdIcon.image = image
// 创建一个顶层的媒体 view,将 nativeAd 赋给它(它会根据广告内容显示图片或视频)
let yPoint = lblAdBody.frame.origin.y + lblAdBody.frame.size.height + 8.0
let coverMediaViewFrame = CGRectMake(lblAdBody.frame.origin.x, yPoint, lblAdBody.frame.size.width, lblSocialContext.frame.origin.y - yPoint - 8.0)
let coverMediaView = FBMediaView(frame: coverMediaViewFrame)
coverMediaView.clipsToBounds = true
coverMediaView.nativeAd = nativeAd
viewAdContainer.addSubview(coverMediaView)
// 设置 social context 标题 (如果有的话)
if let socialContext = nativeAd.socialContext {
lblSocialContext.text = socialContext
有三个地方需要注意:
我们并不知道广告的 body 和 social context 属性是否有值,因此我们需要检查它们是否为空。如果你想万无一失,甚至连基本属性你都应该进行必要的检查。 广告的 icon 是以异步方式进行加载的。loadImageAsyncWithBlock(...) 负责异步加载,我们需要做的仅仅是在我们对 imgAdIcon 的 image view 进行赋值之前确保已经获得图片。 coverMediaView 被初始化,并手动添加到 container view (即 viewAdContainer)中。注意 clipsToBounds 的使用,这是必须的。如果你不这样做,很可能广告媒体会超出 container view 的框架(宽度)。
此外,我们还要提供一个
view,用户可以用它设置与广告有关的隐私选项。其实也很简单,Audience Network 框架提供了一个 :
func handleLoadedNativeAdUsingCustomViews() {
// 添加 AdChoices view
let adChoicesView = FBAdChoicesView(nativeAd: nativeAd)
viewAdContainer.addSubview(adChoicesView)
adChoicesView.updateFrameFromSuperview()
我们调用了 updateFrameFromSuperview() 方法,以调整 AdChoice View 的 frame,除此之外什么也没干。当然,因为它是一个 view 对象,你要手动修改它的 frame 也是可以的。
一个广告应该在用户点击它的时候能够进行响应,并在全屏模式下展示广告。准确点讲,如果用户点击了整个广告画面,或者点击了 call-to-action 按钮,广告应该能够与用户交互。使用哪种交互方式取决于你,但我会两种方法都尝试一下。要让整个 view 可点击,需要在上述方法中加入下面几行:
func handleLoadedNativeAdUsingCustomViews() {
// 使整个广告的 container view 能够被点击。
nativeAd.registerViewForInteraction(viewAdContainer, withViewController: self)
如果你只想让 call-to-action 按钮能够被点击,则可以将上述语句替换为下一句:
func handleLoadedNativeAdUsingCustomViews() {
// 使用 call-to-action 按钮和用户交互。
nativeAd.registerViewForInteraction(viewAdContainer, withViewController: self, withClickableViews: [btnAdAction])
上述调用的最后一个参数是一个 view 数组,意味着你除了 action 按钮外,你还可以设置更多的控件与用户交互。出于演示的目的,我们只在数组中放入了一个按钮。
做完上面的一切,我们就只剩下一件事情要做了:让 container view 变成可见的,而之前它一直是隐藏的:
func handleLoadedNativeAdUsingCustomViews() {
// 让 native 广告的 container view 可见
viewAdContainer.hidden = false
现在你终于可以运行 app 了,并点击第一个 tab 的 view controller 中的 Load Ad 按钮。 如果你前面的步骤完全正确,你应该能够看到第一个测试广告显示出来(我建议你使用仿真器来进行测试):
FBNativeAdDelegate 协议还有一些可选方法可用。在 Xcode 中输入 &nativeAd&(不带双引号),你可以阅读官方文档中关于这些方法的说明。例如,下面这个方法可用于处理广告的点击(不管是整个 view 还是 call-to-action 按钮):
func nativeAdDidClick(nativeAd: FBNativeAd) {
print(&Did tap on the ad&)
在本节结束之前,还需要做一件事情。找到 loadNativeAd(_:) IBAction 方法,修改为:
@IBAction func loadNativeAd(sender: AnyObject) {
if coverMediaView != nil {
coverMediaView.removeFromSuperview()
coverMediaView = nil
if nativeAd != nil {
nativeAd.unregisterView()
nativeAd = FBNativeAd(placementID: &PLACEMENT_ID&)
nativeAd.delegate = self
nativeAd.loadAd()
想必你也看到了,在加载广告之前我们又做了两件事情:首先将 coverMediaView 从 superview 上移除(如果它不为空),并将它置为空。你应该记得这个对象是每次广告被加载后都会重新创建的。其次,如果 nativeAd 对象已经初始化,并且不为空,我们会在加载新的广告前将它(不管是 container view,还是是 call-to-action)从交互中注销。这是必须的,因为接下来在广告加载后,对应的 view 会根据你的命令再次进行注册。
关于 native 广告的更多资料,请看
Native 广告模板
现在我们已经了解如何在自定义 view 中使用 native 广告了,接下来我们来试试如何使用 Audience Network 内置的 native 广告模板。这种方式不像前者一样,需要手工创建 view 并将广告属性赋值给它们。它只需要你指定广告 view 的 frame(这个 view 会自动创建),然后进行一些设置,比如显示内容的颜色、字体等。
在SingleAdsViewController 类中,我们将创建一个新方法,名叫 code&handleLoadedNativeAdUsingTemplate(),我们会改变 nativeAdDidLoad(_:) 委托方法,当广告加载后,调用新方法而不是 handleLoadedNativeAdUsingCustomViews() 方法。 在最简单的情况下,新方法将包含如下语句:
func handleLoadedNativeAdUsingTemplate() {
let nativeAdView = FBNativeAdView(nativeAd: nativeAd, withType: FBNativeAdViewType.GenericHeight300)
nativeAdView.frame = CGRectMake(20.0, 100.0, UIScreen.mainScreen().bounds.size.width - 40.0, 300.0)
self.view.addSubview(nativeAdView)
nativeAd.registerViewForInteraction(nativeAdView, withViewController: self)
在这里我们见到了一个新类 。类如其名,这个类负责创建一个 view,用于显示 native 广告的内容。程序代码很简单,创建一个 FBNativeAdView 对象,设置它的 frame,然后将它加到你想放置它的 view 中。最后一句将新创建的 nativeAdView 注册到 native ad 对象,以便用户点击广告时它能够进行响应。
要想让这个方法生效,我们需要将 nativeAdDidLoad(_:) 方法修改为:
func nativeAdDidLoad(nativeAd: FBNativeAd) {
// handleLoadedNativeAdUsingCustomViews()
handleLoadedNativeAdUsingTemplate()
现在,运行 app 并点击 Load Ad 按钮。你将看到如下所示的画面:
FBNativeAdView 有 4 种可以预先指定的高度。你可以在初始化时通过 withType 参数进行指定。这 4 个 FBNativeAdViewType 枚举值分别是:
GenericHeight100 GenericHeight120 GenericHeight300 GenericHeight400
显然,在修改 frame 时,高度必须和这个值一致。例如,如果你指定了 native 广告 view 为 GenericHeight120 类型,则在设置 frame 时,必须将高设置为 120.0 pt。
在使用 FBNativeAdView 时,你可以设置某些属性,你可以参考
类的文檔。简单说,它们是:
Height Width Background Color Title Color Title Font Description Color Description Font Button Color Button Title Color Button Title Font Button Border Color
上述属性必须在 native 广告 view 初始化之前指定,否则不会生效。下面来看个例子。在handleLoadedNativeAdUsingTemplate() 方法中,我们可以在 native 广告 view 初始化之前设置这些属性:
func handleLoadedNativeAdUsingTemplate() {
let attributes = FBNativeAdViewAttributes()
attributes.buttonColor = UIColor.magentaColor()
attributes.buttonTitleColor = UIColor.yellowColor()
attributes.backgroundColor = UIColor.purpleColor()
attributes.titleFont = UIFont(name: &Noteworthy&, size: 20.0)
attributes.titleColor = UIColor.whiteColor()
attributes.buttonTitleFont = UIFont(name: &Futura&, size: 12.0)
attributes.descriptionColor = UIColor.whiteColor()
你可以设置更多的属性,或者随意修改上面的这些属性值。无疑,配置方式的 native 广告 view 使用起来更加简单。现在,前面所用的初始化方法无法满足我们了,因为我们还有一个 attributes 对象要传递。 我们需要调用 nativeAdView 的另一个初始化方法:
FBNativeAdView(nativeAd: nativeAd, withType: FBNativeAdViewType.GenericHeight300, withAttributes: attributes)
这个方法增加了一个可空的参数 withAttributes,它是一个 FBNativeAdViewAttributes 对象。通过这个参数,我们可以在 native ad view 实例化之后应用我们自定义设置。
下面是修改之后的完整方法实现:
func handleLoadedNativeAdUsingTemplate() {
let attributes = FBNativeAdViewAttributes()
attributes.buttonColor = UIColor.magentaColor()
attributes.buttonTitleColor = UIColor.yellowColor()
attributes.backgroundColor = UIColor.purpleColor()
attributes.titleFont = UIFont(name: &Noteworthy&, size: 20.0)
attributes.titleColor = UIColor.whiteColor()
attributes.buttonTitleFont = UIFont(name: &Futura&, size: 12.0)
attributes.descriptionColor = UIColor.whiteColor()
// let nativeAdView = FBNativeAdView(nativeAd: nativeAd, withType: FBNativeAdViewType.GenericHeight300)
let nativeAdView = FBNativeAdView(nativeAd: nativeAd, withType: FBNativeAdViewType.GenericHeight300, withAttributes: attributes)
nativeAdView.frame = CGRectMake(20.0, 100.0, UIScreen.mainScreen().bounds.size.width - 40.0, 300.0)
self.view.addSubview(nativeAdView)
nativeAd.registerViewForInteraction(nativeAdView, withViewController: self)
再次运行 app,效果如图:
关于 native 广告模板的更多内容,请参考 。
在 table view 中显示 native 广告
本地广告可以很容易就集成到 table view 中,因为 Audience Network Framework 提供了专门做这件事的附加工具。当然,你可以创建自定义 native view 然后将它们添加到 table view 的 cell 中,但这种方式很傻。当同时使用广告和 table view 时,我们可以使用两个新类:FBNativeAdsManager 和 FBNativeAdTableViewCellProvider (见
和 )。第一个类负责下载 一组广告
并为 app 管理它们。这个类的一个特点是会 克隆 已经下载的广告,因此它们可以反复在一张很长 table view 里显示(不仅仅如此)。第二个类提供一种机制,用于自动将 native 广告集成到 table view 中,例如它拥有创建 cell 或者计算行高的方法。这些方法和 table view 内置的委托方法和数据源方法配合使用。除了第二个类的方法以外,我们还可以使用
类中的方法,这个类随 FBNativeAdTableViewCellProvider 类一起提供。
后面我们会看到它们是如何使用的,在此之前先打开 TableViewAdsViewController.swift 文件,声明 3 个属性:
let adRowStep = 4
var adsManager: FBNativeAdsManager!
var adsCellProvider: FBNativeAdTableViewCellProvider!
adRowStep 表示广告在 table view 上显示的频次,在我们的例子里,广告将每隔 3 个单元格出现一次(每 4 行 cell 中会有一个 cell 用于显示广告)。另外两个属性是前面讨论的两个新类的实例。
然后实现一个新方法。在这个方法中,我们初始化 adsManager 对象,加载一堆广告以便在 table view 中显示:
func configureAdManagerAndLoadAds() {
if adsManager == nil {
adsManager = FBNativeAdsManager(placementID: &PLACEMENT_ID&, forNumAdsRequested: 5)
adsManager.delegate = self
adsManager.loadAds()
初始化方法需要两个参数:第一个参数是我们在 Facebook Developer portal 中生成的 placement ID,我们将它复制粘贴到这里。第二个参数告诉 adsManager 要下载多少个广告,最大不能超过 10。当然,如果 adsManager 已经初始化,就不需要再次初始化了,所以我们检查了它是否为空。在调用 loadAds() 方法下载广告之前,我们设置 TableViewAdsViewController 类作为 adsManager 的委托。因为只有通过委托方法,我们才能在后面实现这些方法时知道广告是否下载成功,这也是我们接下来要进行的工作。
光实现这个方法当然不行,我们必须调用它。找到 viewWillAppear(_:) 方法,在最后一行加上:
override func viewWillAppear(animated: Bool) {
configureAdManagerAndLoadAds()
现在需要采用两个协议。第一个是 * FBNativeAdsManagerDelegate* 协议,它让我们知道广告是否下载成功或者有错误发生,第二个是 FBNativeAdDelegate 协议(我们在前面已经使用过它了),它允许我们控制发生在广告上的动作。找到类的第一行,声明使用这两个协议:
class TableViewAdsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, FBNativeAdDelegate, FBNativeAdsManagerDelegate {
首先是 FBNativeAdsManagerDelegate 协议方法。第一个方法会在广告下载成功后调用,在这里我们需要实例化 adsCellProvider 对象并刷新 table view,这样广告将夹在其他内容中一起显示:
func nativeAdsLoaded() {
adsCellProvider = FBNativeAdTableViewCellProvider(manager: adsManager, forType: FBNativeAdViewType.GenericHeight120)
adsCellProvider.delegate = self
if tblAdsDemo != nil {
tblAdsDemo.reloadData()
初始化时我们需要提供两个参数。第一个参数是我们早先用到过的 adsManager 对象,第二个参数是 native 广告 view 的类型 (FBNativeAdViewType) ,这个类型我们在模板广告 view 一节中已经见过了。通过这个类型,我们可以设置广告要显示的高度,根据前面所述,高度值分别是 4 者之一:100, 120, 300 和 400 pt。你可以分别尝试以找出最适合你的值。除此之外,我们还要将我们的类设置为 adsCellProvider 的委托,这样当广告上有事件发生时,我们可以通过 em&FBNativeAdDelegate 协议方法获得通知。当然,这是可选的动作,你完全可以不做。
不要忘记,广告有可能下载失败,因此我们必须处理这种情况。为了简单起见,我们这样实现它(另一个协议方法):
func nativeAdsFailedToLoadWithError(error: NSError) {
print(error)
我们会实现下面的 FBNativeAdDelegate 协议方法,备注:仅仅是演示。在这个方法里,我们会&捕捉&到广告上的点击事件,然后打印被点击的广告的标题:
func nativeAdDidClick(nativeAd: FBNativeAd) {
print(&Ad tapped: \(nativeAd.title)&)
你还可以实现其它协议方法,只需要输入 nativeAd,Xcode 会自动提示这些方法。当然,你也可以阅读协议文文件中关于 Showing Native Ads 的部分。
实现完委托方法之后,为了将广告集成到 table view 中,我们还需要使用 FBNativeAdTableViewCellProvider 和 FBNativeAdTableViewAdProvider 类提供的机制。首先,我们需要调整的地方是 table view 要显示的 cell 行数:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -& Int {
if adsCellProvider != nil {
return Int(adsCellProvider.adjustCount(UInt(self.sampleData.count), forStride: UInt(adRowStep)))
return sampleData.count
我再次建议你去阅读 FBNativeAdTableViewCellProvider 和 FBNativeAdTableViewAdProvider 类文档。如果你没有看过这些文档,那么你可以认为上述程序代码 调整了 tableview 的行数,将广告条数也加进了返回结果中。
然后,我们需要根据行的索引创建并加入广告 cell。我们没有必要进行手动检查,相反,你会看到我们只是简单调用了另一个方法进行检查,然后再调用另一个方法来创建和返回广告 cell。
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -& UITableViewCell {
if adsCellProvider != nil && adsCellProvider.isAdCellAtIndexPath(indexPath, forStride: UInt(adRowStep)) {
return adsCellProvider.tableView(tableView, cellForRowAtIndexPath: indexPath)
let cell = tableView.dequeueReusableCellWithIdentifier(&idCellSample&, forIndexPath: indexPath) as! SampleCell
cell.lblTitle.text = sampleData[indexPath.row - Int(indexPath.row / adRowStep)]
return cell
想必你也看到了,这些来自于 Audience Network 框架的新方法全都使用 Uint(unsigned int)值作为参数,因此需要在 UInt 和 Int 之间进行强制类型转换。剩下来的就简单了,判断某一行是否是广告 cell,然后用 FBNativeAdTableViewCellProvider 类为我们准备相应的 cell。这里有一个地方需要注意,就是 else 语句中数组的索引。注意之前的语句是:
sampleData[indexPath.row]
& 原来用 indexPath.row 来检索数组,现在则变成了:
sampleData[indexPath.row - Int(indexPath.row / adRowStep)]
这样,我们将避免 app 发生闪退,因为有可能滚到某些行的时候,行的索引就已经大过 sampleData 数组的长度了。可以假设一下这种情况会发生什么,例如会发生 indexPath.row 为 20 行(刚好等于数组的长度)的情况,因为其中还有 6 行广告被插入了 table view 中。所以我们要在这里调整数组的索引,这是必须的。
最终,我们要给每一行一个正确的高度:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -& CGFloat {
if adsCellProvider != nil && adsCellProvider.isAdCellAtIndexPath(indexPath, forStride: UInt(adRowStep)) {
return adsCellProvider.tableView(tableView, heightForRowAtIndexPath: indexPath)
return 60.0
运行 app,切换到第二个 tab。稍等片刻,广告将在 table view 的其它内容之间交叉显示。
全屏广告(即 interstitial 广告),和我们将在下一节看到的横幅广告,则相对要简单得多。我们只需要下载广告,然后直接在 View controller 中呈现即可。要实现这个目的,我们将用到新的协议 。该协议提供了让我们知道广告加载成功和出现错误的方法,以及广告被点击或关闭的方法。首先,我们将从协议的声明开始。打开 FullScreenAdsViewController.swift 文件,将类的第一行修改为:
class FullScreenAdsViewController: UIViewController, FBInterstitialAdDelegate {
属性,用于表示一个全屏广告。
var fullScreenAd: FBInterstitialAd!
如果你曾经运行过开始项目,你会发现有一个用于显示全屏广告的按钮。我已经为这个按钮创建了一个 IBAction 方法,你只需要将方法中的代码补全即可。这个过程你应该很熟悉了。
@IBAction func showFullScreenAd(sender: AnyObject) {
fullScreenAd = FBInterstitialAd(placementID: &PLACEMENT_ID&)
fullScreenAd.delegate = self
fullScreenAd.loadAd()
btnShowAd.enabled = false
对于 fullScreenAd 对象的初始化,我们只需要一个参数,即我们所创建的全屏广告的 placement ID。因此请确保你已经有这个 ID 并将之粘贴到第一行代码中。剩下的事情就简单了。注意,当按钮被点击后,我们 disable 掉了按钮, 以免重复发送广告请求。
然后是委托方法。首先处理广告加载成功的情况,在这时我们只需要显示广告:
func interstitialAdDidLoad(interstitialAd: FBInterstitialAd) {
interstitialAd.showAdFromRootViewController(self)
btnShowAd.enabled = true
注意,我们又 enable 了按钮控件。
然后是加载出错的情况:
func interstitialAd(interstitialAd: FBInterstitialAd, didFailWithError error: NSError) {
print(error)
btnShowAd.enabled = true
一般,我们只需要打印错误信息并 enable 掉按钮就可以了,但这种简单处理的方式不推荐在真实 app 中采用。
出于演示的目的,我们又实现了两个委托方法(当然也没有做什么有意义的处理):
func interstitialAdDidClick(interstitialAd: FBInterstitialAd) {
print(&Did tap on ad&)
func interstitialAdDidClose(interstitialAd: FBInterstitialAd) {
print(&Did close ad&)
这就不需要多说了吧。
运行 app,切到第三个 tab。点击按钮,稍等片刻,全屏广告就会显示在屏幕上。
关于全屏广告的更多内容,请参考
如果你想在 app 中使用横幅广告,你可以使用
协议。类似全屏广告,我们只需要初始化一个 FBAdView 对象并下载一个广告,然后在 view controller 中显示它即可。初始化时略有不同,我们稍后会讨论。
首先打开 BannerAdsViewController.swift 文件声明一个属性:
var bannerAdView: FBAdView!
然后修改类的第一行,让它采用 FBAdViewDelegate 协议:
class BannerAdsViewController: UIViewController, FBAdViewDelegate {
在 loadBannerAd(_:) IBAction 方法中,我们必须初始化 bannerAdView 对象,然后加载广告。然后,我们还需要制定横幅广告的 frame。
@IBAction func loadBannerAd(sender: AnyObject) {
bannerAdView = FBAdView(placementID: &PLACEMENT_ID&, adSize: kFBAdSizeHeight50Banner, rootViewController: self)
bannerAdView.frame = CGRectMake(0.0, 20.0, UIScreen.mainScreen().bounds.size.width, 50.0)
bannerAdView.delegate = self
bannerAdView.hidden = true
self.view.addSubview(bannerAdView)
bannerAdView.loadAd()
初始化方法需要 3 个参数:广告的 placement ID(在这里请复制﹣粘贴你自己的 ID),广告的大小 size,显示广告的 view controller。列有你可以使用的 size 值。具体使用哪个值,应该取决于 app 的实际需要,或者和其他 UI 相协调。注意,在我们将横幅广告添加进 view 之前,我们先将它设置为隐藏,而当广告下载成功后我们才会将它设置为显示。
接下来实现委托方法。首先是加载成功方法。在这里,我们需要让横幅广告显示出来:
func adViewDidLoad(adView: FBAdView) {
bannerAdView.hidden = false
然后是其他委托方法:
func adView(adView: FBAdView, didFailWithError error: NSError) {
print(error)
func adViewDidClick(adView: FBAdView) {
print(&Did tap on ad view&)
这样就可以在 app 中显示一个横幅广告。运行 app,切到最后一个 tab 进行测试。
更多内容,请参考 。
一旦你决定在 app 中集成 Facebook 广告,所有选项你都可以使用。我们前面讨论过的所有内容没有任何深奥的地方。本文尽量覆盖大部分内容,但仍然建议你通读一遍官方文档,那里会有本文遗漏的一些细节。对于每个开发者来说,都应该了解如何通过 Audience Network 框架集成 Facebook 广告,这样可增加一种从 app 自身以外获得收入途径。无论如何,我希望本文能够激发你的兴趣,并从中学到新的东西。本文到此结束,祝你玩的开心!
完整的 Xcode 专案,请从 。

我要回帖

更多关于 内向性格的竞争力 的文章

 

随机推荐