Combine Cocoapods and Carthage - ios

I'm creating a Swift framework that is dependent on several other third party frameworks. Both these other frameworks support Carthage and Cocoapods.
Is there any way I can make my own framework support installing using both Carhage and Cocoapods? Or is just not achievable and should I just pick one?

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

Combining both is actually not difficult. With my framework I have started with CocoaPods template containing Example and Pod directories. In the example project I created a new Cocoa Touch Framework target, made sure this target is Shared (in Product - Schemes - Managed Schemes) and dragged content of my Pod/Classes directory to the project (with unchecked Copy items if needed and added Target Membership only to this newly created framework).
This should be enough, Carthage should find this shared scheme and use it. Just keep in mind you have to commit changes and create a new git tag before using your framework from Carthage.

Related

How to add a reference (instead of copy) of a custom iOS framework in a project

I try to add a custom made framework in a project of me but as a reference.
The reason for this is that I want making changes in the framework and see them in the project without need of delete old framework - copy new one.
But something i am missing since i got the below error
No such module
The way I add the framework as a reference is to "untick" the "copy if needed" when I drag and drop it.
I am adding the framework inside the "frameworks" folder of the project.
Any help would be appreciated, thanks!
You should be linking external libraries in the menu by going to the Target’s “Build Phases” and add the library with “link binary with libraries”. This should fix your problem.
An alternative suggestion is to use CocoaPods, which are very widely used in iOS development. If you aren't familiar with Cocoapods, its sort of like web development's npm. You turn your custom framework into a Pod and add a Podfile to your iOS app. The Podfile is just a list of external dependencies. If you push a change to your custom framework, all you have to do is run
pod update
in your command line it will automatically handle the update. This would solve your problem and also keeps your project neat and organized so you don't have to juggle drag and dropping new libraries. CocoaPods also can handle a lot of the other major external libraries you may be using. See the following very easy to follow tutorials:
creating a pod,
getting started with cocoapods

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.

How to install projects without cocoa pods?

I have seen various libraries on GitHub that look useful, but only list CocoaPods as an install method. I'm not sure I want to be dependent on CocoaPods, because I'm wary of Apple breaking it in some future OS X/Xcode update. Is there a way to get these libraries into my Xcode project without using CocoaPods?
Role of CocoaPods is to automate and simplify the process, but you don't need to use CocoaPods if you don't want to.
In case of "manual installation", usually it would be:
download the project from GitHub
add the files to Xcode
import headers
But there is no universal recipe for every project, it may slightly differ from case to case, but usually it boils down to previously mentioned.
The best way if you don't want to use CocoaPods is to read the project documentation, and study examples if there are any.
Of course there is. Basically you need to download the library project, drag the project into your own project, do some library dependency setup and you're done.
For details, check out https://github.com/Alamofire/Alamofire for manually adding a Swift library. And https://github.com/jverkoey/ObjQREncoder for manually adding a Objective-C library to your project.
The only way to install things without Cocoapods is to just drag the source code of other projects into your class. For example, most Github projects can be installed via Cocoapods, or you can just drag the relevant source code into your projects. You don't need to drag in all of the project resources, all you need is usually class files

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).

handling dependencies for iOS Framework project

I've created iOS Framework project using this method: https://github.com/jverkoey/iOS-Framework
Works pretty neat but I'm a little confused on how to include libraries/frameworks that are needed by my framework to work and, in particular, how to do it so that in case 3rd party client app that uses my framework can include these libs as well without conflicts.
Let's say my framework code needs these two things:
FacebookSDK.framework
libFlurry.a
The first one is an iOS Framework. When I add it to "Link Binary With Libraries" phase in my Framework and try compile the client project that uses my framework the linker complains about missing symbols - I need to add FacebookSDK to the client project which is great: there is no possibility of conflicts if client apps wants to use Facebook.
However when I do the same with Flurry static library I get duplicate symbols error when compiling client project. Which confuses me a bit, because isn't FacebookSDK.framework just a packaged static library?
ukaszs-iMac:FacebookSDK.framework lukasz$ file Versions/A/FacebookSDK
Versions/A/FacebookSDK: Mach-O universal binary with 3 architectures
Versions/A/FacebookSDK (for architecture i386): current ar archive random library
Versions/A/FacebookSDK (for architecture armv7): current ar archive random library
Versions/A/FacebookSDK (for architecture cputype (12) cpusubtype (11)): current ar archive random library
So my questions are:
why a library embedded in framework (like Facebook) is not linked to my Framework project product, whereas library included as .a file is?
how to include .a file in my framework so that it does not produce duplicate symbols error when client app using my framework also needs this particular static library?
For the use case you are describing, you should be linking to these external libraries from your application, NOT your own framework. It can be one or the other, but it can't be both.
If you decide that these dependancies belong as the responsibility of the application, you would remove them from "Link Binary With Libraries" and any other explicit linking configuration, and just project your framework project with the path to these frameworks and libraries so it can find the symbols (but not link against them) at compile time (i.e. the path to the libraries should be included LIBRARY_SEARCH_PATHS).
Use cocoapods , it's easy (http://cocoapods.org/)
Your application developers will have to include the podfile and download the dependencies.
While developing your SDK use a reference application/demo app on top of the SDK to simulate this.
You shouldn't link anything when building your framework but just create a *.a binary with your framework's objects.
Also you should not include code from other libraries in your framework as client applications may be adding the same libraries directly or requiring different versions of them, thus creating conflicts.
Off course you can reference *.h header files from other libraries in your framework in order to compile your objects.
As a result the installation steps for your framework should detail other required frameworks/libraries needed, their supported versions, how to add resource files (if any), etc. Just some of the many reasons why you may want to consider Creating a CocoaPods' podspec instead.
You should use CocoaPods. Your dependency on Facebook can be done by linking against the CocoaPod.
If you want to include that particular version of Facebook in your pod, you can put it in your repo and use the vendored_frameworks property to refer to it.
Similarly if you wanted to vendor libFlurry.a, you could do so using s.vendored_libraries.
For system libraries, you don't need to vendor them, e.g. libZ.a.
I strongly recommend creating your CocoaPod using pod lib create YourPodName. They've recently changed the mechanism for how this works and it's really nice.
You can create an Example project that shows how to use your code in context of an app.
Then one of the other neat things I just learned about, someone can do pod try YourPodName and it will automatically download, integrate and run the Xcode project.
CocoaPods is worth the trouble.
I am building my framework project using CocoaPods.
The framework uses some 3rd libs from CocoaPods.
Podfile specifies to install dependency on target of the framework.
When I build the framework, it includes all libs in the binary.
If I add use_frameworks! in Podfile, when the framework is built, it will not include 3rd party libs.
Use CocoaPods dependancy manager. Here's a good guide,
7 miniute video tutorial
Mostly if you install third party frameworks you can install with cocoapods (which is really nice, I would definitely do that) or they offer you to download the framework and include it in your Project.
If you decide to download the library and include it there is normally a list of frameworks you need in the "Getting started" guide.
Means: Offer them to install using cocoapods and to download your library but do not include anything else, give them a list what they need.

Resources