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.
Related
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 =]
My project has linked with like 30 different libraries. Very few of them support Carthage.
Do I need to make a branch and make them support Carthage one by one?
Is there any better way to do so?
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. ;-)
There is no problem in having both Carthage and Cocoapods running on the same project. You can try a hybrid approach and replace the libraries step by step.
You can check this post on it. There, I make my build time 9 times faster by replacing Cocoapods with Carthage, but I discuss how some libraries were hard or impossible to replace.
Is there a best way to use Alamofire and AlamofireImage together in the same project?
I use Alamofire in most projects I make and I really like the "new" AlamofireImage framework, which uses Alamofire itself as a submodule.
If I use both of the frameworks in my project however as siblings, then I end up with multiple versions of Alamofire, duplicate schemes, etc. I'd like to use them as siblings for a couple of reasons.
AlamofireImage isn't always running the latest version of Alamofire.
After asking some questions to the guys making Carthage, they suggested this over using nested frameworks. https://github.com/Carthage/Carthage/issues/816
Is there any best practices anyone can suggest here? I keep running though issues with this and ending up with a million schemes for Alamofire is starting to drive me a bit crazy. Let alone the issues I kept running into when trying to use Carthage.
Small Note: At I'm using submodules in Git over Carthage atm, as I was not able to use Carthage due to the errors I was getting with nested frameworks (and I'd prefer not to use CocoaPods as I feel it can get way too complex, way too quickly).
Thanks for any help or suggestions anyone can give.
I recently had the same difficulty in my iOS project. The solution is to reference the Alamofire framework which is INSIDE the AlamofireImage repo.
Here is the step-by-step guideline to make this work
git Set-up
XCode should be closed.
Cd into thee project directory
Add AlamofireImage as a git submodule to your repo (git add submodule AlamofireImageLink)
Now, there are two options for ensuring that the submodules are correctly initialized
Re-clone the project repo using the "--recursive" flag on when cloning to ensure submodules are correctly downloaded
cd into AlamofireImage and run git init and git update. cd into AlamofireImage/Alamofire and run git init and git update.
XCode Set-Up
Re-open the project in XCode
Add AlamofireImage and AlamofireiOS as embedded / linked binaries in the project build settings.
AlamofireiOS will be referenced as INSIDE Alamofire
Ensure the AlamofireImage and AlamofireiOS build settings are set to the target deployment of the project (iOS 9.1 probably)
Ensure that both have references set to "Relative to Group" in the right sidebar
May need to remove the red Alamofire framework reference in the navigator.
Feel free to look at my set-up for guidance:
https://github.com/Matt--King/HearthStoneFlashbacks
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.
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).