Import a CocoaPods Library from a SPM Package - ios

I have a project that is fully built using SPM. There's one specific library that I want to use that only provides support to CocoaPods. I thought about sending a PR adding support to SPM to that library, but the library also depends on other libraries that also don't provide support to SPM.
In this scenario, there's something that can be done to stick with an SPM project structure and also be able to access the Cocoapods dependency?

Related

Migrating from carthage to swift package manager

I have a project that has multiple external dependencies as well as in house ones such as analytics, api, interfaces, that are all integrated with Carthage. I wanted to gradually migrate all of them to SPM starting with the analytics module.
I've restructured my analytics module to a package and integrated it to main my project using SPM (all worked well!). I did the same for all the other modules that also depend on analytics and removed the references from cartfile, .resolved and .private files.
The issue that I'm facing now is that I'm not sure how to remove the integration done by carthage. Even removing the reference from all cartfiles and from framework and libraries, when I run carthage bootstrap it looks like it still fetches that module and adds the framework to my Carthage folder, which I don't want to.
It's the first time I'm using Carthage, so I'm not sure if I might be missing some step when removing just one dependency. If anyone with more experience could help I'd really really appreciate it =]

Creating iOS compiled SDK in swift which has third party dependency (using CocoaPods)

I've a SDK in Swift 5.1 which our customer would like to distribute (sell) as a compiled SDK instead of giving its sources.
Unfortunately this SDK depends on some third party libraries, integrated using CocoaPods (Alamofire, RealmSwift, ReachabilitySwift, etc...). I know you should avoid having third party dependencies in your frameworks/libraries, but unfortunately we started working on this project after another agency started it. This SDK is actually a cocoapod's Pod, but it's not a compiled pod.
What is the best approach in order to distribute this SDK as a compiled SDK (in order to avoid giving source files to the final consumers who'll buy it) ?
As far as i've understood, if you compile your sdk with third party dependency, you must be sure the app that will use the same libraries with the same public apis as the one used by the compiled sdk, otherwise the app will crash at runtime. The only way to do so, as far as I understand, is to specify a very strict version of each third party dependency in the compiled sdk podspec. For example, Alamofire, '~> 4.2.0'. But I don't like this approach because this way the app can't use a newer version of Alamofire (or the other dependencies), only because the compiled sdk has been compiled with that version.
I'm creating an XCFramework, then a podspec with that XCFramework vendored as vendored_framework (using CocoaPods 1.9.0-beta2 which is the only one that currently supports XCFrameworks as vendored_framework).
I tried many different approaches, like trying to build the compiled sdk as static libraries and linking it's third party dependencies as static libraries too, but in this case when using it in the app, along with the same dependencies (e.g. Alamofire), i see in the console some "Class X is implemented in both Y and Z. Which one to use is undefined" (where Y and Z are the sdk and the app).
Have you any suggestion? How would you do that ?
Thank you!
When you say For example, Alamofire, '~> 4.2.0'. But I don't like this approach because this way the app can't use a newer version of Alamofire (or the other dependencies), only because the compiled sdk has been compiled with that version. I don't think you understood the concept of compiled SDK... When you package the SDK it will be static, so it doesn't matter the possibility of newer third-party dependencies, to update the SDK you need to release a new version to the customer, so you can upload when necessary... The customer isn't able to update the SDK by himself, not at all.
(should be a comment but too big for it)

How to use dynamic framework inside the pod?

I have a free framework (FW). It distributes via cocoapods. In this framework i use another framework. It compiled as dynamic framework (DFW).
So in my FW i need to write import DFW and after this can use it. Also the DFW is linked in Embedded Binaries and Linked Frameworks and Libraries in my project target.
After that i push my FW to cocoapods and after installing it tells Cannot find such a module near the import DFW statement.
The question is - how to properly distribute cocoapod with embedded dynamic frameworks in it?
There is no way to use dynamic frameworks in cocoapods, because it brings in a versioning issues. Instead of this use s.dependency in the podspec file. You can read this also.

Cocoa Touch Framework Swift with embed libraries

I am working on a suite of applications that contain common modules.
 
I want to store the common modules in a Cocoa Touch Framework.
This framework may also contain the libraries and Alamofire and SwiftyJSON because they are widely used in the modules.
 
Currently, despite the many tutorials, articles, etc. read on the internet, I cannot get a stable solution.
Is it possible to integrate the frameworks Alamofire and SwiftyJSON within the framework custom or is it better to integrate them in the different projects consuming the framework (they will also need individually) ?
 
Is it possible to generate a framework running on the simulator and on the phone (whatever methods: subproject or not, dynamic or static library, fat library) ?
You can absolutely do this. You currently have three options for setting this up for development and two options for deployment.
Development
Git Submodules
Git submodules are a great way to bring additional libraries into your project's repository to embed in your project. All you need to do is add the submodule, then drag the Xcode project of that library into your Xcode project so it's nested inside your project. Then you need to add the framework as a link target to your library.
Carthage
Carthage also supports git submodules through the --use-submodules flag. All you need to do is install carthage through homebrew, then create a Cartfile that adds Alamofire and SwiftyJSON using the following command.
carthage update --use-submodules
CocoaPods
CocoaPods is a dependency management system that allows you to easily pull in and deploy different versions of a given library. Since both Alamofire and SwiftyJSON support CocoaPods, you could create a Podfile, and run pod install to pull the pods into your library. I would not recommend this though as this is a pretty heavy weight approach. Instead, I would recommend using either Git Submodules or Carthage for development.
Deployment
Deployment is a MUCH different situation. Currently, there are two fairly robust deployment mechanisms for iOS and OSX that are in wide use in the OSS community (including Alamofire and Carthage).
Carthage
If you imported your git submodules using Carthage, then you may already be completely supporting Carthage deployments. It depends on whether you used a Cartfile.private file to pull in your dependencies. Given what you're trying to do, I doubt that you would use a private Cartfile and would instead use the public one. This means that you should be good to go right out of the box. Awesome!
CocoaPods
CocoaPods is much different than Carthage and has some big advantages over Carthage, at a cost. You need to create a podspec file and push that into a public or private spec repo. Then anyone can pull your pod into their project using a Podfile.
Summary
As you can see, there are MANY options here. I would highly recommend using Carthage to pull in your git submodules, then supporting both Carthage and CocoaPods for deployment. I know that's a lot of effort though, so you may want to focus on one or the other. Sorry for the massive amount of links and information, but you question leads me to believe that you would greatly benefit from all these various sources.
Hopefully that helps get you on your way to becoming a dependency development and deployment ninja.

iOS dependency management and packaging

I'm completely new to iOS development and coming from an Android background. I was starting to look at what alternatives are out there for dependency management in iOS and found out that CocoaPods seems to be the most prevalent option.
After reading a lot of links about this topic I'm kinda at a loss and wondering what is the usual way dependencies are handled in iOS.
I have two questions:
1) What would the equivalent of using gradle to generate library (.aar) projects be in iOS? If there's any equivalent option. From what I've seen one can wrap static libraries and headers into frameworks and these can be used in other apps, is this the standard way to do it?
2) If (1) is correct, does CocoaPods offer a mechanism to add frameworks as dependencies?
I don't have a Android background but from what I understand of .aar files CocoaPods does something very similar. CocoaPods uses .podspec files (described here) to generate static libraries (and soon dynamic frameworks which are new in iOS 8) that are then linked into your project.
A podspec can define source files, assets, libraries, or frameworks that a source vendors for linking into your application. So yes it does support adding frameworks as dependencies, although until iOS 8 frameworks were not supported at all on iOS.
As far as the 'standard' way to do it, I think that's based on opinion. There are a few general ways to include dependencies you can choose from.
Drag files, frameworks, and whatever else you need into your project manually. Updating these is more difficult and that also means you have to configure your .xcodeproj depending on what features that library needs (such as ARC)
Drag a provided .xcodeproj into your project, and link the relevant target from the given project. This can be nice if the library provides a project that can build a framework or static library, in this case you'd pull in that library but their project would handle custom compiler flags.
Do either of the above while including them as git submodules. Assuming nothing massive changes in the project this helps a lot with updating your dependencies.
Use CocoaPods. CocoaPods will handle all the custom linking and updates based on semantic versioning (usually).
Use Carthage. Carthage is an in- between CocoaPods and the .xcodeproj solution. It will download code based on semantic versions defined by git tags, then you drag the generated frameworks into your project.
All of these options have pros and cons and the decision normally comes down to how you feel about the control you have over the inclusion of the library, and how automated you want it to be.
I do not have android nor iOS background however I've been developing a CI tool for both platforms and here are the answers
As You mentioned this a framework and pods (libraries) from cocoapods are distributed that way. For instance, have a look at Apphance. When spec is clicked it's visible that this library will be accessible as a Apphance-Production.framework.
You add pods to Podfile and download them with pod install command. This command will made classes from Apphance accessible from the code. Some people do commit downloaded pods, other not (it's like adding jars or aars to source control).

Resources