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:
- Add the .xcodeproj to your workspace
- 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 ) - Go to
General
tab of the target you want to run, add the framework underLinked Frameworks and Libraries
(it is going to take the one added from the .xcoproj) - (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?
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.Yes.
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
Inter-App Data Migration (Migrating Data to New App Version)
Convert String to Date in Swift
Protocol Doesn't Conform to Itself
What Is an Optional Value in Swift
Firestore: How to Get Random Documents in a Collection
Swift 3 Incorrect String Interpolation With Implicitly Unwrapped Optionals
Any Way to Replace Characters on Swift String
How to Deal With @Objc Inference Deprecation With #Selector() in Swift 4
Is Swift Pass by Value or Pass by Reference
How Does One Generate a Random Number in Swift
Difference Between 'Let' and 'Var' in Swift
Nsdate() or Date() Shows the Wrong Time
Swift @Escaping and Completion Handler
Difference Between Flatmap and Compactmap in Swift