Thursday, May 07, 2015

Cocoapods use_frameworks! Means A Bridging Header Not Required for Objective-C Pods in Swift

TL;DR Use standard "Import Framework" in Swift instead of the Obj-C bridging header for Obj-C Cocoapods with use_frameworks! in your Pods file
Versions: OS X  10.10.3 Xcode 6.3.1 iOS SDK 8.3  Cocoapods 0.36.1

This just wasn't obvious at all. I've been using Swift & Cocoapods < 0.36 since Xcode 6 shipped. While versions < 0.36 did not work with a Swift framework like Alamofire, you could use Objective-C pods and let them get compiled as a static library as long as you used the Objective-C bridging header to import the header(s).

With Cocoapods 0.36 and above, you can have Swift frameworks as Pods. To make that work, you have to put the use_frameworks! keyword in your Pods file. My brain misunderstood Use frameworks instead of static libraries for Pods because it automatically inserted for Swift before the Pods in that sentence. 

Took me a couple hours this morning to work out all my Pods might be framworks. I'm not the first person to figure it out, just a few days ago, Johannes Luderschmidt published a blog post with the solution which put on the right path. All Pods using use_frameworks! are frameworks, not just the Swift pods. A problem like this is where experience with Xcode can really work against you. You start tweaking Header Search Paths,  Framework Search Paths, User Header Search Paths, and the Always Search User Paths (docs: disabling it is strongly recommended) settings in desperation because that's usually where these problems lie. Especially when the first compiler error in your project after putting use_frameworks! in your Pod file is that the header for come Objective-C pod can’t be found.

But that’s totally down the wrong rabbit hole. I’m using the Obj-C MBProgressHUD Pod. What you need to do is:

  1. Remove the #imports from your bridging header
  2. Add Import MBProgressHUD into every Swift file that needs the class.
  3. Fix the enums

You're now using bona fide frameworks, so your enums have moved in flight! You might have a line of Swift that was fine with the bridging header like this:

progressHUD.mode = MBProgressHUDModeIndeterminate

That now has to become this:

progressHUD.mode = MBProgressHUDMode.Indeterminate

Not to big a deal, but the pile of errors might lead you astray that you have a bigger problem than you do if you’re using a lot of Obj-C enums.