MoPub Mo' Problems

Part I: Setting up MoPub with Swift & CocoaPods

Posted by Grego on December 31, 2015

As you may have noticed, the MoPub Documentation is rather weak when it comes to implementing MoPub ads on iOS using Swift. I seemingly ran into more trouble when trying to integrate using CocoaPods.

Here I’ll show a quick demo of how to get set up and started with MoPub, Swift and CocoaPods.

Create Project and Add the Pod

  1. Create a new project, then close it. We’re about to create the Podfile and open the workspace.
  2. Add Pod, install, open workspace:
echo "pod 'mopub-ios-sdk'" >> Podfile
pod install
open MoProblems.xcworkspace

Add a Bridging Header

In order for us to work with the Objective-C code written by the nice MoPub people, we’ll have to add a Bridging Header to the project before we can use that code.

  1. Add a New File to your project. Select Header File. Bridging headers are typically in the format of AppModuleName-Bridging-Header.h but if you don’t want to follow that format, don’t.
  2. Take note of where your Header file lives, in my case I placed it under the MoProblems/ subdirectory of my project:

     .
     ├── MoProblems
     │   ├── MoProblems
     │   │   ├── AppDelegate.swift
     │   │   ├── Assets.xcassets
     │   │   ├── Base.lproj
     │   │   ├── Info.plist
     │   │   ├── MoProblems-Bridging-Header.h
     │   │   └── ViewController.swift
     │   ├── MoProblems.xcodeproj
    

Set Up Bridging Header

Since we added the bridging header manually, we have to set it up manually in order for the compiler to pay any attention to it.

  1. Click on your Project in the Navigation Window (⌘1)
  2. Go to Build Settings and search for Bridging Header.
  3. Set the Objective-C Bridging Header option to the relative path to your header. So for me that’s MoProblems/MoProblems-Bridging-Header.h

Importing the bridging header

Now we need to import MoPub’s Bridging Header in our own bridging header. This may seem whacky, but I’ve experienced problems when trying to use their header directly, and having our own adds a bit of flexibility so I see it only as a benefit.

Now the import is a little tricky. You can place it inside the header guard, or remove the guard all together, since the Objective-C #import statement should cover you for duplicate imports—but that’s really not the tricky part.

Method A - No Frameworks

If your Cocoapods is not set to build frameworks (the use_frameworks! line does not appear in your Podfile), add the following #import statement in AppModuleName-Bridging-Header.h:

   #import "MoPub-Bridging-Header.h"

It’s slightly uglier since it pulls all of the MoPub stuff into your namespace, but from my current experience it will make the ads load better.

Method B - Using Frameworks

If your CocoaPods is set to build frameworks (the use_frameworks!) option does appear in your Podfile, add the following #import statement in AppModuleName-Bridging-Header.h:

   #import <mopub_ios_sdk/MoPub-Bridging-Header.h>

Implementing MoPub (MPInterstitialAdController)

In this example, I’ll show how to implement a simple MPInterstitialAdController:

import UIKit
//import ios_mopub_sdk   //uncomment this line if you `use_frameworks!`

class ViewController: UIViewController {

  var adController: MPInterstitialAdController?
  let INTERSTITIAL_AD_ID = "YOUR_INTERSTITIAL_AD_ID_HERE"

  override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    adController = MPInterstitialAdController(forAdUnitId: INTERSTITIAL_AD_ID)
    adController?.delegate = self
    adController?.loadAd()
  }

  override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
  }

}

// MARK: - MPInterstitialAdControllerDelegate
extension ViewController : MPInterstitialAdControllerDelegate {
  func interstitialDidLoadAd(interstitial: MPInterstitialAdController!) {
    print("Yay! Ad loaded!")
    interstitial.showFromViewController(self)
  }

  func interstitialDidFailToLoadAd(interstitial: MPInterstitialAdController!) {
    print("Ad failed to load!")
  }
}

Uncomment the appropriate line if you opted for Method B, or the compiler will complain about the following:

Use of undeclared type 'MPInterstitialAdController'
Use of unresolved identifier 'MPInterstitialAdController'

That’s about it for now.

MRAID Issues

As it stands right now I still have problems with my implementation. While this code compiles and works somewhat, the MoPub code seems to have an issue either about being compiled as a framework, or getting namespaced. I’m not too sure. The MRAID ads in my current project won’t load at all when MoPub is compiled as a framework, but work rather well when compiled as a static library (.a).

To elaborate these are the issues I encounter when building as a Framework:

MOPUB: Looking for custom event class named MPMRAIDInterstitialCustomEvent.
MOPUB: Loading MoPub MRAID interstitial
MOPUB: MoPub MRAID interstitial did fail
MOPUB: Interstitial ad view is fetching ad network type: clear
MOPUB: No ads found for ad unit: <my_ad_unit_id>

At present there is no way to use_frameworks! for a specific pod but I’ve voiced my issues there already as well.

I’ve contacted MoPub and I’m currently waiting for them to return from their company winter vacation in the Bahamas, seeing as they’re out of office until January 4, 2016.

The only other solution might be to create a separate MoPub project to include and forget about letting CocoaPods manage MoPub all together. This way the code stays out of my project and I can still compile a static library.