07/09/2018, 15:32

Swift: cách tích hợp iAd và Admob vào cùng một app

Tích hợp iAd vào một app IOS hiện tại đã đơn giản hơn rất nhiều. Theo document của Apple thì chúng ta chỉ cần thêm 1 dòng vào viewDidLoad trong ViewController. override func viewDidLoad() { super.viewDidLoad() self.canDisplayBannerAds = true // here } Như vậy nếu có nhiều ...

Tích hợp iAd vào một app IOS hiện tại đã đơn giản hơn rất nhiều. Theo document của Apple thì chúng ta chỉ cần thêm 1 dòng vào viewDidLoad trong ViewController.

override func viewDidLoad() {
    super.viewDidLoad()
    self.canDisplayBannerAds = true // here
}

Như vậy nếu có nhiều ViewController thì trong mỗi ViewController đó cũng chỉ thêm 1 dòng như trên. Tuy nhiên mọi việc không đơn giản như vậy.

Apple Technical Note TN2286 có đoạn

If your application has multiple tabs or views displaying an iAd banner, you should share a single instance of ADBannerView across each view.

Using a shared banner allows maximum efficiency in retrieving ad inventory for your app. The longest wait for iAd inventory is when the ADBannerView is instantiated. After that, ad inventory refreshes on a periodic basis. If you delete and recreate the ADBannerView every time the view switches, your wait for inventory is reset and induces a delay in waiting for another ad to become available.

Đại khái là "phải implement share single instance nếu không thì ad sẽ tự động refresh rất nhanh".

WTH ??

Ở bên trên ta đã thêm mỗi ViewController một dòng và với cách làm như vậy thì ngờ rằng ta đã tạo ra n instance khác nhau và trái với technical note ở trên.

Câu trả lời cho thắc mắc trên là ... tui hổng biết T_T Bạn nào có biết thì chỉ giáo nhé. Chỉ thấy trong video WWDC thì Apple khuyến khích cách làm trên nên có thể là nó không vi phạm technical note, nhưng hoàn toàn không có một tài liệu chính thức nào cho biết điều này.

iAd nghe nói có tỉ lệ click trên impression cao, tuy vậy fill rate thấp và mới chỉ available ở một số quốc gia (xem ở đây). Có nghĩa là thời gian bỏ không không hiển thị ad là cao và với những nước như VN thì còn chẳng bao giờ hiện ad.

Ngược lại Admob của Google thì fill rate lên đến 99%, độ phủ lại cao, tuy vậy tỉ lệ click trên impression rất thấp.

Phương pháp tối ưu lợi nhuận sẽ là, hiển thị iAd và khi iAd không có gì thì ẩn iAd đi hiển thị Admob. Đến khi iAd có "hàng" thì lại ẩn Admob đi để hiện iAd.

Để thực hiện cách làm bên trên thì hiển nhiên không thể dùng phương pháp nhanh gọn của Apple được rồi, trước hết ta sẽ tạo single share instance cho iAd dựa theo hướng dẫn trong Technical note

  • Create an ADBannerView instance belonging to your app delegate soon after your application launches, for example, in -application:didFinishLaunchingWithOptions: of your app delegate.
  • Use your application delegate as the banner's delegate. Have your application delegate tell the current view controller

Bước 1 : AppDelegate.swift

Trước hết là import iAd, tạo một biến appDelegate để sau dùng trong ViewController và cho AppDelegate extend protocol ADBannerViewDelegate

import iAd
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate

class AppDelegate: UIResponder, UIApplicationDelegate, ADBannerViewDelegate {

Sau đó khởi tạo ad banner bên trong class

var iAdBannerAdView: ADBannerView! = ADBannerView()

Tiếp theo, khởi tạo ad trong hàm chứa didFinishLaunchingWithOptions

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    iAdBannerAdView.delegate = self
    iAdBannerAdView.hidden = true

    return true
}

Xong phần khởi tạo! Giờ cần implement phần xử lý khi banner load được ad và khi banner không nhận được ad

func bannerViewDidLoadAd(banner: ADBannerView!) {
    iAdBannerAdView.hidden = false
}
func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
    iAdBannerAdView.hidden = true
    // Try Admob here
}

Bước 2 ViewController.swift

Vậy là chúng ta đã có một instance của iAd trong appDelegate, bảo đảm thỏa mãn yêu cầu của Technical Note. Giờ chỉ cần gọi ra trong mỗi ViewController.

override func viewWillAppear(animated: Bool) {
    appDelegate.iAdBannerAdView.center = CGPoint(
        x: view.frame.midX, 
        y:  view.frame.height - appDelegate.iAdBannerAdView.frame.height / 2)
    view.addSubview(appDelegate.iAdBannerAdView)
}

Chú ý là nên dùng viewWillAppear chứ không phải viewDidLoad nhé.

Tích hợp Admob có vài bước cần chuẩn bị, đầu tiên (tất nhiên là) lập tài khoản, download SDK về và kéo thả vào project ... Những bước này đã có hướng dẫn cụ thể của Google Khi làm theo cái này bạn chỉ cần làm đến phần build SDK như sau nhé.

  • Download SDK: link
  • Add vào project
  • Chọn file
  • Thêm thư viện cần thiết vào project
    • AdSupport
    • AudioToolbox
    • AVFoundation
    • CoreGraphics
    • CoreMedia
    • CoreTelephony
    • EventKit
    • EventKitUI
    • MessageUI
    • StoreKit
    • SystemConfiguration

Bước 1: AppDelegate.swift

Giống như iAd, cần import và extend thêm protocol GADBannerViewDelegate

import GoogleMobileAds
class AppDelegate: UIResponder, UIApplicationDelegate, ADBannerViewDelegate, GADBannerViewDelegate {

Sau đó tạo adbanner

var adMobBannerAdView: GADBannerView! = GADBannerView(adSize: kGADAdSizeSmartBannerPortrait)

Kế là khởi tạo y chang iAd trong class, chỉ khác là ở trạng thái khởi tạo thì để delegate là nil

adMobBannerAdView.delegate = nil // attension!
adMobBannerAdView.hidden = true

Giờ đến đoạn quan trọng nhất, trong hàm đã viết lúc nãy cho iAd thì ta sẽ khởi tạo AdMob

func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
    iAdBannerAdView.hidden = true

    // Try AdMob
    adMobBannerAdView.delegate = self
    adMobBannerAdView.adUnitID = adMobBannerAdID
    let request = GADRequest()
    request.testDevices = [ kGADSimulatorID ]; // Simulator
    adMobBannerAdView.loadRequest(request)
}

func adViewDidReceiveAd(bannerView: GADBannerView!) {
    adMobBannerAdView.hidden = false
}

Bước 2: ViewController

Giờ đến ViewController. Với đoạn lúc nãy sẽ cần thêm như sau

override func viewWillAppear(animated: Bool) {
    // iAd
    appDelegate.iAdBannerAdView.center = CGPoint(
        x: view.frame.midX, 
        y:  view.frame.height - appDelegate.iAdBannerAdView.frame.height / 2)
    view.addSubview(appDelegate.iAdBannerAdView)

    // AdMob
    appDelegate.adMobBannerAdView.rootViewController = self
    appDelegate.adMobBannerAdView.center = CGPoint(
        x: view.frame.midX,
        y: view.frame.height - appDelegate.adMobBannerAdView.frame.height / 2)
    view.addSubview(appDelegate.adMobBannerAdView)
}

Thế là xong, giờ chúng ta có một ad banner đa năng mà

  • Khi iAd có ad thì ưu tiên load trước.
  • Khi iAd không có ad thì load AdMob lên thay thế.
  • Khi iAd có lại ad thì lại ẩn adMob đi để ưu tiên lên trước.

Chúc các bạn may mắn!

0