14

I would like to create a dynamic framework and distribute it. It needs to work when running on simulator, an iPhone device, and be able to submit to the App Store.

I am aware of lipo thanks to this guide. It shows how we can combine the simulator architectures with the iphone architectures into a single dynamic framework that can be distributed without distributing the source code. It allows me to use the framework for both simulator and iPhone device. However, it fails when I try to send it to the App Store because of the simulator build.

Carthage provides an interesting solution. It creates a framework that works for both simulator and iPhone. But when it is time to send it to the App Store we need to run a script to rip out the simulator slices.

However, the creators of DoubleClick for Publishers (DFP) have found a way to create a framework that works on both simulator and device; Passes the App Store submission; And doesn't require any script to rip out the simulator slices (AFAIK). All I really have to do is drag the GoogleMobileAds.framework file into Linked Frameworks and Libraries. It is a little surprising that I don't need to add it to Embedded Binaries like most dynamic frameworks)

I created a sample project that uses DFP that demonstrates this.

// clone repository
git clone --recursive https://github.com/wh1pch81n/DoubleClickGoogleExample.git

// Move to correct branch
git submodule foreach 'git checkout master'
git submodule foreach 'git pull origin master' 

Now you can choose the Simulation_mate scheme and run the app. The app will show a single advertisement banner at the bottom to show that the ad is actually working.

The dependency graph looks like this.

Simulation_mate.app
   -> Mate.framework
      -> DFP.framework
         -> GoogleMobileAds.framework

Again, I can run Simulation_mate on simulator, iPhone, and can submit it to the App Store.

My question is how in the world did they create GoogleMobileAds.framework like this? What steps need to be followed to create a framework like this?

7
  • Smells like a static library framework. Can you file the binary file inside the framework to test? Afaik, Google only creates static frameworks in order to support iOS 7. Commented Jan 22, 2017 at 23:30
  • Have you consider to create a Pod instead? you can distribute the Pod and cocoapods manage the configuration to compile the framework for the appropriate architecture, works for simulator and device and no problems when you submit to the app store. Commented Jan 24, 2017 at 17:21
  • I can't use cocoa pods or Carthage or any 3rd party dependency management tool Commented Jan 24, 2017 at 18:12
  • CocoaPods is never the solution this day and age. It's an archaic relic of the past. Commented Jan 25, 2017 at 17:06
  • Please be aware that lipo can smash binaries together but the Mach-O header does not have an entry for "platform". There is special magic to detect Simulator binaries on macOS and vice-versa but otherwise merging a tvOS slice with an iOS slice will leave you with a mess. If this is something you would like to see supported please file radars to request it; your votes do count. Commented Jan 27, 2017 at 5:35

1 Answer 1

8
+150

As suspected, the GoogleMobileAds.framework is a static framework, rather than a dynamic framework.

> file GoogleMobileAds
GoogleMobileAds: Mach-O universal binary with 5 architectures: [arm_v7: current ar archive] [arm_v7s] [i386] [x86_64] [arm64]
GoogleMobileAds (for architecture armv7):   current ar archive
GoogleMobileAds (for architecture armv7s):  current ar archive
GoogleMobileAds (for architecture i386):    current ar archive random library
GoogleMobileAds (for architecture x86_64):  current ar archive random library
GoogleMobileAds (for architecture arm64):   current ar archive

Whereas, running file on a dynamic framework, you get a different result:

> file AppKit 
AppKit: Mach-O universal binary with 2 architectures: [i386: Mach-O dynamically linked shared library i386] [x86_64]
AppKit (for architecture i386): Mach-O dynamically linked shared library i386
AppKit (for architecture x86_64):   Mach-O 64-bit dynamically linked shared library x86_64

Unfortunately, the problem you describe is a known limitation of the App Store distribution system. In theory, the correct way to distribute your dynamic framework should be to distribute the full fat binary with all architectures, and let either the build system throw out the the unneeded architectures when building, or let the App Store distribution system do that when slicing the app for specific devices ("slicing"). If I had to guess, the App Store distribution fails with such frameworks due to iOS 8 and below support, since those systems do not support slicing from the App Store.

The reason Google creates static libraries is in order to support iOS 7. A silly reason at this day and age, it has created many issues for developers, since Google also insists on using CocoaPods. Static frameworks, while superficially seem like a silver bullet at first ("no scripts for lipoing out archs; no embedding"), are actually not that great. For instance, if you'd like to include non-compiled resources, a static framework will not do the trick (dynamic frameworks are bundles, while static frameworks are not).

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for the detailed response. I did not suspect GoogleMobileAds.framework was secretly a static library, since I thought static libraries had the ".a" extension.
This is one of those things, like KVOing a UIScrollView, that seems to mostly work (and so most everyone does it) but it is not actually supported. If you're distributing your own library, consider staying in the realm of officially supported methods (e.g. distribute platform-specific binaries) and save your library users a future headache!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.