Possible to use SPM packages from Cocoapods' "Pods" project?

Scenario: I am developing two frameworks, FLEX and Reflex. FLEX has no dependencies and Reflex depends on FLEX and Echo, a swift package. Both FLEX and Reflex support either SPM or Cocoapods. Echo only supports SPM and it also depends on swift-atomics. FLEX is purely Objc and Reflex is Swift.

In an example app, I added FLEX and Reflex as pod dependencies. After opening the generated workspace, I added Echo as a Swift package to the Pods project, to the Reflex target. I have tried this all with and without the use_frameworks! option in the Podfile.

Everything builds up until it reaches import Echo in Reflex. No such module 'Echo' it tells me. Which is strange, because I can import CEcho just fine, where CEcho is one of the targets declared by Echo

What do I need to do to get this to work? I've tried everything I can think of, but I'm really just guessing here; package management and build systems aren't my strong-suit.

You best bet is to keep the SPM and CocoaPods dependency chains separate, so you'll need to make Echo and swift-atomics visible to CocoaPods if you want your overall framework to be compatible. I'd suggest you focus on getting your SPM case working first, then moving on to CocoaPods. Unfortunately, swift-atomics doesn't support CocoaPods, so you'll need your own Podspec for it.

The reason I'm not using them all from SPM is because it's a huge pain to develop them from within SPM. Local packages aren't editable so you have to edit them in separate windows and then "update" the packages in a separate project.

But Xcode doesn't properly re-fetch package dependencies, even when you clear the cache; it just re-fetches the same commit, even if the chosen branch is on a new commit. The only way to make it download the new commit is to remove the dependencies, quit Xcode, clear derived data, and add them back. Gotta do this any time you want to test some changes in an app. It's a truly awful experience.

If I can't get SPM+Cocoapods working together, I'll have throw them all into a project by hand :persevere: Which I don't want to do. (That, or make podspecs for them both, which is even more work) There's no reason why this shouldn't work!

Finally got "show in log" to work (it wasn't working before) and I'm seeing one invocation of -fmodule-map-file for every module except Echo, for some reason. This explains why I'm able to import CEcho, but not Echo itself. I don't know how to fix this, though.

cc @Alejandro and @NeoNacho :(

You can put the packages in a workspace to make them editable and work alongside them (see a post I wrote here)

That's news to me! Cool! However, I can't run Xcode 13 so I can't use the fancy new app targets… :(

I need to be able to edit and run them together in an app. Cocoapods supports this use case perfectly

It's also possible to edit local dependencies (and cache of remote dependencies, I think) without putting them in the workspace if the root project is a SwiftPM project:

You definitely cannot edit any dependencies at all in the "Package Dependencies" section. I'm not able to, anyway. Either way, it doesn't matter since even local dependencies are always copied and never simply referenced as they probably should be. :/

hmm it appears that local dependencies are simply referenced for me:

My change (appended extra "!"s) to the dependency in the "Package Dependencies" section

is reflected in the dependency package itself:

If you right click on the package and "show in finder", does it take you somewhere in DerivedData?

It takes me directly to where the dependency package is located, not in DerivedData.

Interesting… I guess if it behaves differently when it's a swift package instead of an Xcode project? Good to know. Unfortunately that doesn't help me since this is an Xcode project :/

File -> Packages -> Update to latest package versions should do the trick.

1 Like

I know it's been a while but I just ran into this again and I wanted to say how incredibly misleading the labels are. The "reset cache" and "update to latest" buttons seem like they're backwards almost. What does invalidating the package cache even do if it doesn't re-fetch whatever branch or version you specified? :P