How to make framework in CocoaPods that has multiple targets?
Asked Answered
C

2

18

I write a framework and I like to divide framework to small separate submodules (targets). Apple provides a cool description for thing I want to achieve with CocoaPods:

Targets are the basic building blocks of a package. A target can define a module or a test suite. Targets can depend on other targets in this package, and on products in packages which this package depends on.

I could easily do it with Swift Package Manager:

    targets: [
        .target(name: "Network"),
        .target(name: "Service", dependencies: ["Network"])
    ],

I could use import Network in a Service target and it's cool because they are separate modules, logic is clear.

How to achieve it in CocoaPods and Carthage (I write a framework, not the final application)?

What I've tried:

Subspec

I tried to use subspecs:

  s.subspec 'Service' do |ss|
    ss.dependency 'MyFramework/Network'
    ss.source_files = 'Sources/Service/**/*.swift'
  end

  s.subspec 'Network' do |ss|
    ss.source_files = 'Sources/Network/**/*.swift'
  end

It doesn't work as I want because CocoaPods just merges all files into one framework (just divides it to separate folders), so:

  1. I receive namespace collisions.
  2. Fatal error when I try to import Network inside Service because there is no Network target after pod install. So I can't use one that framework with Swift Package Manager. CocoaPods just merges everything to one target MyFramework as I mentioned before.

Separate repos/pods

It's the solution but it's very hard to maintain multiple separate git repositories and make separate commit and pushes. I want to keep everything in a one repo.

Crispation answered 24/10, 2019 at 11:52 Comment(2)
Any reason why you don't want to bundle them separately? So, you could have a Pod for Network and then you would declare a separate Service Pod, which itself would use Network as a Pod? :)Horst
@Crispation did you found any solution ? I am also facing similar situationCosmopolitan
T
2

I'm pretty sure that CocoaPods doesn't have the ability to create separate targets for one podspec.

As you mention above you can create separate podspecs, but in one repository like RxSwift. Then while you are developing you can use some Example project which includes all your podspecs. You don't need to manage different repositories.

Also, you can try to create a module map with different modules, e.g.:

framework module Something {
    framework module Core { ... }
    framework module Toolbox { ... }
    ...
}

And then assign it in podspec, e.g.:

Pod::Spec.new do |s|
  s.module_map = "#{s.name}/#{s.name}.modulemap"
...

But I'm not sure about that. I've tried only the first way as in RxSwift repository.

Trudeau answered 8/12, 2020 at 16:57 Comment(0)
S
0

Use the below approach in the pod file, to specify different pods for each target. You can also create multiple def and add different pods in each one in which can be used separately.

In the provided example I have 2 shared pods and 2 targets

  • target1_name is the of one target

  • target2_name is the name of another target

  • shared_pods list of pods

  • shared_pods_2 list of another pods

    use_frameworks!    
    
    def shared_pods
     # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
    
     pod 'RealmSwift'
     pod 'Alamofire'
     pod 'ReachabilitySwift'
     pod 'SDWebImage'       
    end
    
    def shared_pods_2
     pod 'Fabric'
     pod 'Crashlytics'
     pod 'CryptoSwift'
    end
    
    target 'target1_name' do
     shared_pods
    end
    
    target 'target2_name' do
     shared_pods_2
    end
    
Streetman answered 10/12, 2020 at 11:1 Comment(1)
Thanks for your answer but this is a Podfile, for using pods, whereas the question is about a podspec, for creating a podMirella

© 2022 - 2024 — McMap. All rights reserved.