Romain Romain - 4 months ago 51
iOS Question

Building a Cocoapod with Swift and dependency on Objective-C framework

I know there are already a few questions on this theme here on SO, but very few have accepted answers, and I don't think I have found the exact same problem as mine.

I'm building a Swift pod, and in my code I rely on the Google Maps iOS SDK, which is bundled as a

.framework
file. The project builds OK in Xcode, however I have troubles publishing the lib to Cocoapods.

I managed to have a
Podspec
file that almost validates using the
pod lib lint
command. However, now that I've added the
Google-Maps-iOS-SDK
pod as a dependency in the
Podspec
file, it fails with the following message:


$ pod lib lint

[!] The 'Pods' target has transitive dependencies that include static
binaries:
(/private/var/folders/n2/qyjfpk6n7zz_mngtwswlmsy00000gn/T/CocoaPods/Lint/Pods/Google-Maps-iOS-SDK/GoogleMaps.framework)

$


Is this expected? Why can't I add the Google Maps iOS SDK as a pod reference in my own Swift-based pod?

Here's the
Podspec
:

Pod::Spec.new do |s|
s.name = '(name)'
s.version = '1.0.0'
s.summary = '(summary)'
s.platforms = { :ios => '8.0', :osx => '10.10' }
s.ios.deployment_target = '8.0'
s.osx.deployment_target = '10.10'
s.license = { :type => 'BSD', :file => 'LICENSE' }
s.source_files = 'Sources/*.{h,swift}', '*.framework'
s.source = { :git => "https://github.com/(Github repo).git", :tag => "1.0.0" }
s.requires_arc = true
s.frameworks = "Foundation", "CoreLocation"
s.author = { 'Romain L' => '(email)' }
s.dependency 'Google-Maps-iOS-SDK'
end


If I don't include the Google Maps iOS SDK as a dependency, then
pod lib lint
fails in the Bridging Header, and complains it cannot find
<GoogleMaps/GoogleMaps.h>
(file not found).

I'm stuck, and I don't know if it's a bug from Cocoapods 0.36 (still in Beta) or if I'm doing something wrong.

Thanks for your help!

Answer

I finally found another thread on SO dealing with similar problems: Linker errors in a Swift project with Google Maps for iOS added via CocoaPods.

It appears that the errors were due to a combination of bad Podspec file (on the Google Maps iOS SDK side), and bugs in Cocoapods 0.36 Beta.

It's actually possible to workaround the issues by using @fz.'s revised Podspec file for Google Maps: http://stackoverflow.com/a/28471830/145997. Another article that also was of great interest to understand how the vendored_frameworks setting works in Podspec is: http://codereaper.com/blog/2014/creating-a-pod-with-crashreporter/.

So, to correctly import the Google Maps iOS SDK in a Pod project, first use the following Podfile:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
# altered version of Google's Podspec
pod 'Google-Maps-iOS-SDK', :podspec => "https://raw.githubusercontent.com/Reflejo/GoogleMapsPodspec/master/Google-Maps-iOS-SDK.podspec.json"
use_frameworks! # don't forget this!

I'm now able to reference Google Maps classes from my Swift code simply by doing import GoogleMaps. And, to distribute the Pod, my final Podspec now resembles the following:

Pod::Spec.new do |s|
    s.name                  = 'MyPod'
    s.version               = '1.0.0'

    s.homepage              = "https://github.com/..."
    s.summary               = '(pod summary)'
    #s.screenshot            = ""

    s.author                = { 'Romain L' => '(email)' }
    s.license               = { :type => 'BSD', :file => 'LICENSE' }
    s.social_media_url      = "https://twitter.com/_RomainL"
    s.platforms             = { :ios => '8.0' }
    s.ios.deployment_target = '8.0'

    s.source_files          = 'MyCode/*.{h,swift}'
    s.module_name           = 'MyPod'
    s.source                = { :git => "https://github.com/....git", :tag => "1.0.0" }
    s.requires_arc          = true
    s.libraries             = "c++", "icucore", "z" # required for GoogleMaps.framework
    s.frameworks            = "AVFoundation", "CoreData", "CoreLocation", "CoreText", "Foundation", "GLKit", "ImageIO", "OpenGLES", "QuartzCore", "SystemConfiguration", "GoogleMaps" # required for GoogleMaps.framework
    s.vendored_frameworks   = "Dependencies/GoogleMaps.framework" # Put the Google-provided framework in that subfolder of your Pod project
    #s.dependency              'Google-Maps-iOS-SDK' # Careful! this will cause errors if enabled!
end

I am now able to start a new iOS app in Xcode and use the following Podfile to link against my own pod, itself referencing the Google Maps iOS SDK:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
pod 'MyPod'
use_frameworks! # do not forget this!

Not that easy, but feasible after all! Hoping Google will soon patch its Podspec file for Swift developments, though.