Cocoapods: Cannot get ObjC and Swift to interop (module map support for static libs)

Created on 19 Jul 2019  Â·  17Comments  Â·  Source: CocoaPods/CocoaPods

Report

I want to call some C/ObjC functions from within Swift, and I don't want to expose these functions to consumers of my cocoapod. When I try to use a bridging header, Xcode tells me "error: using bridging headers with framework targets is unsupported". When I try to use a custom module map, cocoapods tells me that it won't work for static libraries, and I'm not sure if it works that way anyways. What should I do?

What did you do?

Run pod install, with a brand new .xcodeproj that depends on this library and see that there's a build error

What did you expect to happen?

It builds

What happened instead?

It does not build

CocoaPods Environment

Stack

   CocoaPods : 1.7.3
        Ruby : ruby 2.6.0p0 (2018-12-25 revision 66547) [universal.x86_64-darwin19]
    RubyGems : 3.0.1
        Host : Mac OS X 10.15 (19A471t)
       Xcode : 11.0 (11M336w)
         Git : git version 2.21.0
Ruby lib dir : /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib
Repositories : artsy - https://github.com/artsy/Specs.git @ bdd1edc21cd8e834919636d4ace59e4bf362f2fc
               master - https://github.com/CocoaPods/Specs.git @ 3ec921a1a1f1cd8a1304d33bfdee5947e201c75f

Installation Source

Executable Path: /usr/local/bin/pod

Plugins

cocoapods-deintegrate : 1.0.4
cocoapods-plugins     : 1.0.0
cocoapods-search      : 1.0.0
cocoapods-stats       : 1.1.0
cocoapods-trunk       : 1.3.1
cocoapods-try         : 1.1.0

Podfile

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'ZippyRun' do
  # Comment the next line if you don't want to use dynamic frameworks
  # use_frameworks!
  pod 'ZippyJSON', :git => 'https://github.com/michaeleisel/zippyjson'


  # Pods for ZippyRun

  target 'ZippyRunTests' do
    inherit! :search_paths
    # Pods for testing
  end

end

Project that demonstrates the issue

https://github.com/michaeleisel/ZippyRun/ , run pod install and then observe that in ZippyJSONDecoder.swift, it can't find lots of functions that are in ZippyJSONPrivate.h

moderate enhancement

Most helpful comment

use_frameworks! :linkage => :static introduced in 1.9.0 might be a workaround

All 17 comments

Cannot run pod install in your sample:

[!] No podspec found for `ZippyJSON` in `../ZippyJSON`

Need a correct sample.

I also tried:

pod 'ZippyJSON', :git => 'https://github.com/michaeleisel/zippyjson'

While pod install worked I am seeing a 'simdjson.h' file not found error.

Oops, it builds now, you can build for the simulator at least (I made a bunch of private headers public, skirting the issue). But I think it will help to ignore sample projects like this one and to consider the different options:

  • Have a bridging header with the private headers in it, except that this doesn't work because Apple doesn't allow bridging headers in static libs and dylibs
  • Use a module map that declares a private module, except Cocoapods doesn't allow you to set the module_map option for static libraries, and this needs to be available as a static library. I suppose I could just change the Xcode build settings for module maps myself, but this feels like circumventing Cocoapods and makes me nervous.

These options are discussed further in https://jsorge.net/2019/01/23/mixed-language-framework

Generally specifying a private module map could be a good enhancement but yes support for module maps for static libraries is not there yet.

Am I understanding that you were able to get things working? Trying to see if there is an action to be taken here.

I am not able to get things working, because although it builds for me, I don’t want to expose all those private functions to consumers. To reiterate, my goal is to have a Swift file that calls private C/ObjC functions and not expose those functions to the consumer.

If this can be accomplished by a private module map then this could be the enhancement.

Yes, I think that’s the best solution. +1 for that enhancement, I’ll find a workaround in the meantime

@michaeleisel thanks! If we mirror the module_map DSL we can have a private_module_map DSL added so it should actually be fairly easy.

Not tagging this for 1.8.0 yet as we do not know if we will make it there.

That is not the blocker, although that could make things nicer. The blocker is that module_map is not supported for static libs. So unless this private option was supported for static libs, I would still be unable to use it

then it is even a "bigger" enhancement to add module map support for static libs.

Yes

I wasn’t sure if there was a workaround so I opened the issue, but it sounds like there’s not, so yes this is just an enhancement request then

use_frameworks! :linkage => :static introduced in 1.9.0 might be a workaround

Paulb777. I had to create a Github account just so I could thank you.
use_frameworks! :linkage => :static does indeed solve the actual problem.

use_frameworks! :linkage => :static introduced in 1.9.0 might be a workaround

It actually did worked. I was working around on this issue from cocoa pods 1.8.0 alternatively using "use_modular_headers!" but the issue of module map missing was persistent for "BoringSSL-GRPC" finally Thanks Paul you saved the day.!!

Thanks for this. Also, since SwiftPM doesn’t allow mixed-language packages, people who want to support both will have to create separate projects anyways

@michaeleisel I am having same issue as your, but in my case I can make objective-c module public.

Did you find workaround for your problem?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

luhui picture luhui  Â·  3Comments

spencerkohan picture spencerkohan  Â·  3Comments

k06a picture k06a  Â·  3Comments

pallaviMN picture pallaviMN  Â·  3Comments

Mingmingmew picture Mingmingmew  Â·  3Comments