ネイティブ広告

ネイティブ広告はアプリのコンテンツにシームレスに調和することによって、ユーザーにより良い印象や体験を提供できます。アプリのデザインに最も合うレイアウトを選択し、カスタマイズすることができます。ニュース、ユーティリティー、コミュニケーション系のアプリにとっては理想的な広告フォーマットです。

以下の手順に従い、ネイティブ広告での収益化を開始してください。

ネイティブ広告の設定

アプリを追加してから、 ネイティブコンテンツを選択して広告タイプ ネイティブ向けのプレースメントを作成します。

以下のオプションから適切なレイアウトを選択します。

ネイティブプレースメントをいったん作成したら、プレースメントIDが手に入ります。

ネイティブ広告の作成

  1. ヘッダーをインポートして、ViewController.swiftファイルでネイティブインスタンスを宣言します。ViewControllerヘッダーファイルは次のようになります。
    import UIKit
    import InMobiSDK
    class ViewController: UIViewController, IMNativeDelegate {
        var nativeContent: String?
        var native: IMNative?
    }
    		
  2. ネイティブ広告オプジェクトのインスタンスを作成します。ViewController.swiftファイルは次のようになります。
    override func viewDidLoad() {
            super.viewDidLoad()
            native = IMNative.init(placementId: 13020009)
            native?.delegate = self
            native?.load()
    }
    		
  3. UIViewControllerdeinitメソッドでは、デリゲートをnil に設定します。バナーをリリースする際はデリゲートをnil に設定する必要があります。
    deinit {
           	 // perform the deinitialization
            	native?.delegate = nil
        	}
    		
  4. 広告ステータスのコールバックについては、IMNativeのデリゲートプロパティを実装します。以下のコールバックがサポートされます。
         /**
         * Notifies the delegate that the native ad has finished loading
         */
        public func nativeDidFinishLoading(_ native: IMNative!) {
            NSLog("[ViewController %@]", #function)
        }
        /**
         * Notifies the delegate that the native ad has failed to load with error.
         */
        public func native(_ native: IMNative!, didFailToLoadWithError error: IMRequestStatus!) {
            NSLog("[ViewController %@]", #function)
            NSLog("Native ad failed to load with error %@", error)
        }
        /**
         * Notifies the delegate that the native ad would be presenting a full screen content.
         */
        public func nativeWillPresentScreen(_ native: IMNative!) {
            NSLog("[ViewController %@]", #function)
        }
        /**
         * Notifies the delegate that the native ad has presented a full screen content.
         */
        public func nativeDidPresentScreen(_ native: IMNative!) {
            NSLog("[ViewController %@]", #function)
        }
        /**
         * Notifies the delegate that the native ad would be dismissing the presented full screen content.
         */
        public func nativeWillDismissScreen(_ native: IMNative!) {
            NSLog("[ViewController %@]", #function)
        }
        /**
         * Notifies the delegate that the native ad has dismissed the presented full screen content.
         */
        public func nativeDidDismissScreen(_ native: IMNative!) {
            NSLog("[ViewController %@]", #function)
        }
        /**
         * Notifies the delegate that the user will be taken outside the application context.
         */
        public func userWillLeaveApplication(from native: IMNative!) {
            NSLog("[ViewController %@]", #function)
        }
        /**
         * Notifies the delegate that the nativeStrands ad impression has been tracked
         */
        public func nativeAdImpressed(_ native: IMNative!){
            NSLog("[ViewController %@]", #function)
        }
    		
  5. ネイティブ広告のレンダリングとインプレションの計測

    nativeAdDidFinishLoadingのコールバックを取得すると、ネイティブ広告を正常に受信したことになります。nativeAd?.adContentオブジェクトは、新規または既存の UIView で表示できるネイティブ広告コンテンツを提供します。ネイティブ広告コンテンツには、InMobiポータルで選択したフォーマットに応じた一連のアセットが含まれます。

    たとえば、ニュースのビューであれば、コンテンツには以下のアセットが利用できます。

    • タイトル - 広告のタイトル、文字列
    • コンテンツ - 広告の内容、文字列
    • ランディング URL - 広告のクリック時に表示される URL
    • アイコン - アイコンの詳細。つまり、URL、JSON 表記による高さ、幅

    次のように、これらのアセットはビューに合わせて様々なコンポーネントで使用できます。

    if (native?.adContent != nil)  {
             do{
                    let data = native?.adContent.data(using: .utf8)
    /* Convert the native JSON content to NSDictionary.*/
                    let jsonDict = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! NSDictionary
                    let nativeJsonDict = NSMutableDictionary(dictionary: jsonDict)
                    // The native JSON is parsed and can be used.
                    // To differentiate the native JSON dictionary from other data
                    nativeJsonDict.setObject(true, forKey: "isAd" as NSCopying)
    /* Examples of fetching the image and title are listed below*/
    	/*Fetch the image url from the dictionary in the following way.*/
    	let icon = dict?.object(forKey: "icon_xhdpi") as? NSDictionary
    let url = icon?.object(forKey: "url")
    /*Fetch the tile from the dictionary*/
    	let title = dict?.object(forKey: "title") as? String
                    if (items.count > 0) {
                        items.insert(nativeJsonDict, at: 1)
                    }
                 } catch {
                    print("Error Caught")
                }
            }
    		

    これらの値を使って必要なビューを合成します。たとえば、テーブルビューを作成する場合、広告がそのビューのセルであれば、 tableView:cellForRowAtIndexPath:メソッドでビューをレンダリングします。例:

     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cellIdentifier: String = "someIdentifier"
            var cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)
            if (cell == nil) {
                cell = UITableViewCell(style: .value1, reuseIdentifier: cellIdentifier)
            }
            let row = indexPath.row
            let dict = items[row] as? NSDictionary
            let isAd = dict?.object(forKey:"isAd") as? Int
       // If this is the row where the ad should be displayed,
            if  (isAd != nil) {
                let titleLabel: UILabel = UILabel()
                let descriptionLabel: UILabel = UILabel()
                let imageView: UIImageView = UIImageView()
                titleLabel.text = dict?.object(forKey: "title") as? String
                descriptionLabel.text = dict?.object(forKey: "subtitle") as? String
                let icon = dict?.object(forKey: "icon_xhdpi") as? NSDictionary
                let urlString = icon?.object(forKey: "url") as? String
                if let url = URL.init(string: urlString!)
                {
                    let data = NSData(contentsOf:url)
                    if data != nil {
                        imageView.image = UIImage(data:data! as Data)
                    }
                }
                titleLabel.frame = CGRect(<FRAME_FOR_YOUR_LABEL>)
                descriptionLabel.frame = CGRect(<FRAME_FOR_YOUR_LABEL>)
                imageView.frame = CGRect(<FRAME_FOR_YOUR_IMAGE>)
    //Add subviews to the cell
                cell?.addSubview(titleLabel)
                cell?.addSubview(descriptionLabel)
                cell?.addSubview(imageView)
                //Bind the cell to the native ad as it has rendered the ad.
                IMNative.bindNative(native, to: cell)
            }
            else {
                // This is a content item
                // UnBind the cell as it might be a reused cell from a native ad.
                IMNative.unBindView(cell)
            }
            return cell!
    }
    		

    以下は、ネイティブ広告コンテンツにアクセスしてニュースフロー用にレンダリングする方法を示す一例です。別のフローでは、選択するビューに応じてコンテンツアセットが異なる可能性があります。

    広告コンテンツがレンダリングされたら、以下を呼び出してこれを通知します。

    bindNative(_ native: IMNative!, to view: UIView!)
    IMNative.bindNative(native, to: renderedUIViewInstance)
    		

    ここでは、 'renderedUIViewInstance'は表示されたネイティブ広告を示します。つまり、テーブルビューの場合、1 つのセルでネイティブ広告をレンダリングするのであれば、広告のレンダリング後にこのメソッドにセルを渡す必要があります。

    このセルが他のコンテンツまたは他のネイティブ広告インスタンスに再利用されている場合、 unBindView:(UIView*)viewメソッドとIMNative クラス メソッドを呼び出します。広告がまだ読み込まれていない場合、両方のメソッドは失敗します。

  6. クリックの計測およびランディングページ遷移の処理

    reportAdClick:(NSDictionary*)を呼び出すことによりネイティブ広告のインスタンスへクリックを通知します。

    ディクショナリのパラメータには、パブリッシャーがネイティブ インスタンスに提供したい追加の情報を含めることができます。

    クリックを通知して自らのコーディングでランディングページを開く処理を行うには、次を呼び出します。 nativeAd?.reportAdClick(paramsDictionary)

    • 広告コンテンツにランディングページ情報が含まれている場合は、reportAdClick メソッドを呼び出した後にネイティブ広告のランディングページへの遷移処理を実装する必要があります。
    • ランディングページのURLは、ネイティブ広告コンテンツ内の「landing_url」キーの値として提供されます。また、ランディングページ URL は通常、外部ブラウザで開かれます。
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
        {
            print(items[indexPath.row])
            let dict = items[indexPath.row] as? NSDictionary        
            if (dict?.object(forKey:"isAd") as? Int) != nil {
                let landingUrl = dict?.value(forKey: "landingURL") as? String
                native?.reportAdClick(nil)
                if(landingUrl != nil) {
                    let landingPageURL = URL.init(string:landingUrl!)
                    UIApplication.shared.open(landingPageURL!)
                }
            }
            tableView.deselectRow(at: indexPath, animated: true)
        }
    		

    クリックを通知し、InMobi のSDKにランディングページへの遷移を任せるには、以下をを呼び出します。 ;[nativeAd reportAdClickAndOpenLandingURL:paramsDictionary];

    native?.reportAdClickAndOpenLandingURL(paramsDictionary) 
       func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
        {
            print(items[indexPath.row])
            let dict = items[indexPath.row] as? NSDictionary
            if (dict?.object(forKey:"isAd") as? Int) != nil {
                native?.reportAdClickAndOpenLandingURL(nil)
            }
            tableView.deselectRow(at: indexPath, animated: true)
        }
    		

取得CreativeID

時には、広告品質のチェックをすべて逃れた不正な広告主様が、無関係で不快なものや混乱するものをユーザーに表示することで、アプリのユーザーエクスペリエンスを損なうことになります。 このような状況への対応策として、広告インスタンスのcreativeIDを取得し、InMobiの連絡先に暗号化されたクcreativeIDでレポートし直します。

mNativeAd.creativeId // mNativeAdはサンプルインスタンスです。

インテグレーションのテスト

  1. InMobiポータルでテストモードを設定します。

    [ツール] - [診断]に進み、テストモードを グローバルオンセレクティブオンのどちらかに切り替えます。

    アプリに対する広告インテグレーションが初めての場合 テストモードグローバルオンに設定します。
    特定のテスト用端末にのみテスト用広告を配信したい場合 -

    アプリに対して既にSDKを実装済みで、特定の更新部分などのテストをテスト用の端末に限定して実施する必要がある場合。
    テストモードセレクティブオンに設定します。

    デバイスセクションでテスト端末を登録します。

    1. デバイスIDボックスに、デバイスIDを入力します。
    2. デバイス名ボックスで、任意の名前を設定します。
    3. [デバイスを追加]をクリックしてテスト端末を追加登録します。

    すでに登録済みのデバイスがある場合は、その端末を選択し、テストモードを有効に設定できます。

    注意: テスト完了後、本番稼働する前にテストモードをオフにしなければなりません。そうしないと、お客様のアプリは収益化できません。

    これで、テスト広告を取得するための準備が整いました。

    デバイスIDの取得

    ここでのデバイスIDは、基本的にIDFAまたはIFA (広告の識別子)を指します。デバイスIDを取得するための、最も簡単なアプローチは、SDKのログレベルを“debug”に設定することです。デバッグログを有効にするには、以下を AppDelegate.swiftファイル内の didFinishLaunchingWithOptionsメソッドに追加することです。

    func application(_ application: UIApplication, didFinishLaunchingWithOptions 
    launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
            //Initialize InMobi SDK with your account ID
            IMSdk.initWithAccountID("Insert InMobi account ID here")
            IMSdk.setLogLevel(.debug)
            // Do your stuff.
            return true
        }
    		

    デバッグモードでは、デバイスIDは以下としてXCode開発者コンソールに出力されます。 “Publisher device ID is <device-id>”

    お客様はこのデバイスIDを デバイスIDボックスに入力できます。

  2. [診断]タブ上でテストモード時の広告ユニット別のレポート値を確認できます。実装が正しく行われたか確認するのに役立ちます。

  3. また、ネイティブ広告の読み込みに成功すると、コンソール内に以下のInMobi SDKのログも出力されるはずです。

    [InMobi] InMobi SDK initialized with account id: <your account id here>

    [InMobi] Fetching native ad for placement id: <your placement id here>

    [InMobi] Publisher device id is <device id here>

    [InMobi] Native ad successfully fetched for placement id: <your placement id here>

  4. これで、InMobiテスト広告もアプリケーション上で表示できます。
  5. 広告の作成前にSDKが正しく初期化されない場合は、通常以下のログが表示されます。

    ** ERROR ** [InMobi] ___ Please initialize the SDK before creating a <ad format> ad.

    ** ERROR ** [InMobi] ___ Account id cannot be null or empty. Please provide a valid Account id.

    [InMobi]Invalid account id passed to init. Please provide a valid account id.

キーとなるログの一覧を以下に記します。

SDK初期化

シナリオ ログ レベル ログ
NULLまたは空白のアカウントIDを渡した場合。 Error Account id cannot be null or empty. Please provide a valid Account id.
有効なアカウントIDを渡した場合。 Debug InMobi SDK initialized with account id: <account id>
無効なアカウントIDを渡した場合。 Error Invalid account id passed to init. Please provide a valid account id.
より新しいバージョンのSDKが入手可能な場合。 Debug A newer version (ver. 6.0.0) of the InMobi SDK is available! You are currently on an older version (ver. 5.3.1). Download the latest InMobi SDK from http://www.inmobi.com/products/sdk/#downloads

広告のライフサイクルで出力される主なログ

シナリオ ログ レベル ログ
ネットワークが使用できない状況で広告がリクエストされた場合。 Error Network not reachable currently. Please try again.
広告が読み込み中または利用可能な状態のときに広告がリクエストされた場合。 Error An ad load is already in progress. Please wait for the load to complete before requesting for another ad (Placement id : <placement id> ).
ユーザーが広告を閲覧中に広告がリクエストされた場合。 Error An ad is currently being viewed by the user. Please wait for the user to close the ad before requesting for another ad (Placement id : <placement id> ).
デバイスID Debug Publisher device id is <Device Id>

ネイティブ広告インテグレーション時のログ

シナリオ ログ レベル ログ
SDKが初期化されていない場合。 Error Please initialize the SDK before creating a native ad
無効なプレースメントIDでインタースティシャルを作成した場合。 Error Please provide a valid placement id to create a native ad
ネイティブ広告の読み込みが開始された場合。 Debug Fetching an native ad for placement id: <placement id>
広告が正常に取得された場合。 Debug Native ad successfully fetched for placement id: <placement id>
広告の取得に失敗した場合。 Error Failed to fetch native ad for placement id: <Placement id> with error:<Status code / message>
ネイティブ広告をビューにバインドした場合。 Debug Binding Native ad to view: <view info> for placement id: <placement id>
ビューからネイティブ広告のバインドが解除された場合。 Debug Unbinding Native ad from view : <view info> for placement id: <placement id>
コンテキストコードの読み込みを開始した場合。 Debug Started loading Native ad markup in the webview for placement id: <placement id>
コンテキストコードの読み込みが完了した場合。 Debug Successfully loaded Native ad markup in webview for placement id: <placement id>
広告表示のインプレッションを計測した場合。 Debug Viewable impression was recorded for Native ad with placement id: <placement id>
Null ビューで prepareToTrackImpressionsメソッドが呼ばれた場合。 Error Please pass a non-null view object to bindNative
既にアタッチされているビューで prepareToTrackImpressionsメソッドが呼ばれた場合。 Error Failed to attach view
広告がまだサーバから戻されていない状態で prepareToTrackImpressionsメソッドが呼ばれた場合。 Error Please wait for the ad to finish loading before making a call to prepareToTrackImpressions
無効な広告ステータスでの reportAdClick
Null ビューもしくは無効なビューで reportAdClick メソッドが呼ばれた場合。
Error reportAdClick call made in wrong state

高度な設定

インプレッションおよびクリックのカスタム計測

インプレッションおよびクリックのカスタム計測を実装するには、 IMCustomNativeクラスを使用します。

import InMobiSDK
	
  • トラッカーのスクリプトを使用してインプレッションを通知するには、次のメソッドを使用します。

    renderedUIViewInstanceにトラッカーのスクリプトをパラメーターとして渡します。

    open class func bindNative(_ native: IMNative!, to view: UIView!, withImpressionTrackerScript impressio	nTracker: String!)
    		
  • トラッカーの URL を使用してインプレッションを通知するには、次のメソッドを使用します。

    renderedUIViewInstanceにトラッカーのURLをパラメーターとして渡します。

    open class func bindNative(_ native: IMNative!, to view: UIView!, withImpressionTrackerURL impressionTrackerURL: URL!)
    		
  • 自らのコーディングでランディングページへの遷移処理を実装する場合には、以下の様に実装します。
    • トラッカーのスクリプトを使用してクリックを通知するには、次のメソッドを使用します。

      クリックのパラメータとトラッカーのスクリプトをパラメーターとして渡します。

      open func reportAdClick(_ extras: [AnyHashable : Any]!, withCustomClickTrackerScript clickTracker: String!)
      			
    • トラッカーの URL を使用してクリックを通知するには、次のメソッドを使用します。

      クリックのパラメータとトラッカーのURLをパラメーターとして渡します。

      open func reportAdClick(_ extras: [AnyHashable : Any]!, withCustomClickTrackerURL clickTrackerURL: URL!)
      			
  • ランディングページへの遷移処理を自らのコーディングで実装せずに、InMobi SDKに任せる場合には以下のメソッドを使用します。
    • トラッカーのスクリプトを使用してクリックを通知するには、次のメソッドを使用します。

      クリックのパラメータとトラッカーのスクリプトをパラメーターとして渡します。

      open func reportAdClickAndOpenLandingURL(_ extras: [AnyHashable : Any]!, withCustomClickTrackerScript clickTracker: String!)
      			
    • トラッカーの URL を使用してクリックを通知するには、次のメソッドを使用します。

      クリックのパラメータとトラッカーのURLをパラメーターとして渡します。

      open func reportAdClickAndOpenLandingURL(_ extras: [AnyHashable : Any]!, withCustomClickTrackerURL clickTrackerURL: URL!)
      			

viewcontrollerクラスは次のようになるはずです。

override func viewDidLoad() {
        super.viewDidLoad()
        customNative = IMCustomNative.init(placementId: "Insert native Placement ID Here")
        customNative?.delegate = self
        customNative?.load()
}
//Track impressions using custom script
IMCustomNative.bindNative(customNative, to: UIRenderedView, withImpressionTrackerScript: "custom script here")
IMCustomNative.bindNative(customNative, to: UIRenderedView, withImpressionTrackerURL: "custom impression tracking URL here")
customNative?.reportAdClick("clicks params", withCustomClickTrackerScript: "custom script here")
customNative?.reportAdClick("clicks params", withCustomClickTrackerURL: “custom click tracking URL here”)
customNative?.reportAdClickAndOpenLandingURL("clicks params", withCustomClickTrackerScript: "custom script here")
customNative?.reportAdClickAndOpenLandingURL("clicks params",  withCustomClickTrackerURL: “custom impression tracking URL here”)