Cocoapods and Carthage

set up a carthage/cocoapod project to distribute multiple dependencies

Should SmallerModule be a part of the Core project or should they be separate Xcode projects

I guess it depends by the granularity of what you need to be exposed. SmallerModule might be separated or merged inside Core, remember that once you expose it, it's quite complicate coming back, eg: you might generate dependencies to other projects.

Secondly, if it is a separate project, how does SmallerModule have access to the interfaces in Core?

If you split the projects, SmallerModule will easily have the access to the interfaces of the Core dynamic framework, the thing you must do first is generate such framework.

Do I need to include it as a dependency in SmallerModule

eg: if you use Carthage as dependency manager, you should create a Cartfile inside the project SmallerModule containing this line:

github "MyOrg/Core"

then on SmallerModule “Build Phases” settings tab, click the “+” icon and choose “New Run Script Phase”, add the following contents to the script area below the shell:

/usr/local/bin/carthage copy-frameworks

Add the paths to the frameworks you want to use under “Input Files”, e.g.:

$(SRCROOT)/Carthage/Build/iOS/Core.framework

Add the paths to the copied frameworks to the “Output Files”, e.g.:

$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/Core.framework

then after resolving the dependency:

carthage update

You will find Core.framework inside the folder ./Carthage/build/iOS/ so you may drag and drop such framework inside your SmallerModule to be able to compile it.

wouldn't Core be duplicated if someone tried to pull in both Core and SmallerModule since Core is a dependency for SmallerModule

Since you'll be using a dependency manager (eg: Carthage), it won't be a problem. All the dependencies will be resolved (if they link the same version eg: tag x.y.z) by the dependency manager itself during the resolution process (carthage update).

Note that if SuperSmallerModule has to bind your SmallerModule, then assuming everything is fine, must create a Cartfile with:

github "MyOrg/SmallerModule"

and follow the same process, also explained here.

Using Carthage and CocoaPods in the same project

The main issue you will run into is that CocoaPods and Carthage are not aware of each other. This means that if a dependency managed by CocoaPods and a dependency by Carthage share a common dependency, conflicts may arise.

Carthage requires that you manually add frameworks to a project which means that you can probably get away with not linking any shared dependency and relying on the framework added by CocoaPods, but you won't get dependency version resolution across the two dependency managers and it won't be clear how it all works.

With that said, there aren't any inherent reasons why you can't use both, and if the library you want to include has few or no dependencies, it's probably still preferable to use Carthage rather than including the library as a submodule or even copying the source in.

My recommendation, if possible, is to include your other dependencies via Carthage, or to create a podspec for the library so that you can use Carthage or CocoaPods exclusively.

Combine Cocoapods and Carthage

You can definitely make your framework available with both CocoaPods and Carthage. This is the path that I would recommend to allow your users to use whatever solution they prefer. Also note that setting a framework up to work with Carthage also makes it much easier for users who want to use your library without either of these solutions.

On a high level, for CocoaPods you'll want to create a podspec that lists your dependencies there. This way CocoaPods will manage downloading and configuring them along with resolving them against other user dependencies. See more here.

For Carthage you'll want to configure your project with framework targets for the platforms you support and add your dependencies in your Cartfile. More on that here

What's the equivalent of development pods under Carthage?

I believe Carthage doesn't have something similar to "development pods" yet.

But you could simulate "development pods" just following these steps:

Steps:

  1. Add the .xcodeproj to your workspace
  2. Remove all the dependencies you have in your project of the framework you added in step 1. (probably you may need to remove it from Build Phases -> Run Script -> Input Files too )
  3. Go to General tab of the target you want to run, add the framework under Linked Frameworks and Libraries (it is going to take the one added from the .xcoproj)
  4. (optional) you may need to run carthage bootstrap in the framework's repo you want to add locally.

That's it.

After that you will be able to run your project and update framework's code in the same workspace.

Do we need to create iOS Universal Frameworks for CocoaPods and Carthage?

  1. If you distribute your source code with CocoaPods or Carthage, these systems will make your source code compiling either into .framework or into static library on the consumer side while the consumer’s project builds. Consumers will have access to your source code.

  2. Yes.

  3. If your framework is intended to be used in Mac Catalyst apps - then XCFramework is the only choice. Otherwise, you can still ship fat framework - old, but gold.

UPDATE:

With AppleSilicon, XCFramework becomes the only format in which you should ship your prebuilt framework, because even iOS simulator now should support both x86_64 and arm64 architectures.

How to move from CocoaPods to Carthage?

The carthage idea is based on frameworks. So if your dependencies do not support them, carthage is unable to build them for you. Simple as that.

But: You can use carthage also to manage dependencies only by using the param "--no-build". Then carthage will only fetch the dependencies into your Carthage/Checkouts folder.

There are some drawbacks:

  • depending on the project you have to add the projects of each dependency to your own project, if the projects only contain a sample app you have to add the code itself
  • if the projects have dependencies itself carthage is only able to find them if there is a cartfile in the projects, as an alternative you may add the dependent projects to your own cartfile to avoid forking them but then you have to update the versions for yourself
  • developers see the code itself while work but they should handle them as read-only
  • ...

It's possible to use carthage like that, but I wouldn't recommend it. If you need more informations about this solution read here.

Note: If you fork the projects and make them support carthage the community might be grateful. ;-)



Related Topics



Leave a reply



Submit