Use CocoaPods in a secondary Xcode project - ios

I have an Xcode workspace that has two projects. The main project uses the second project as a static library. The main project is working fine with CocoaPods. In both projects I need to include AFNetworking. How can I set this up correctly?
PS: I am using unit test in the static library project so including AFNetworking headers wont be enough.

Since you are already using cocoapods, I thinks the best way is to become your secondary project a pod itself, a private one if you can not free the code. That way you can define in the podspec all the dependencies you need, like AFNetworking and when you use that in the main project all the dependencies will be managed for you.
Also that way unit testing and reusing should become even easier.

Related

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

Sharing classes between Xcode projects

A while ago I developed an iOS application using Xcode that and created a bunch of classes that work together to communicate with a RESTful API. Now I'm creating a second app, totally separate but communicates with the same API. I want to reuse these classes, what is the best way to approach this? Should I be do the via some Version control system? Or should I use an Xcode workspace?
Thanks in advance for any help.
I prefer to create separate Git repository for selected files, and embed this repository as submodule in both projects (old and new one)
In similar situation I done it using XCode Workspace and Static Library.
I added the common classes to a Static Library project and added that to the XCode Workspace.
In my second project I added that Static Library Project.
I have two options there:
Adding that Static Library project to the new project workspace
Adding the static library (.a) project to the new project
I chose the first option because, I can add the other common files to that Static Library and also modify the existing files if needed.
As Midhun and yourself mentioned, the best way to do it us by making a workspace and adding your projects to that.
Your shared code can go into a new project that's basically empty and dragged/linked from there into any projects in your workspace.
Changes made to that code from any project will also update the shared code base, which I think is what your ultimate goal was.

iOS Framework build: what is the best practice to link with third-party libraries?

I'm build a Framework for iOS and my framework has AFNetworking as dependency.
So what is the best practice to include AFNetworing? Reading other posts (specially this question here) i came up with three options:
Copy all the .h.m files from AFNetworing in to my project and compile my framework with it. But according to this, it will possible cause a situation where some third part developer using my Framework are already using AFNetworking and will get a compile-time error that some class is declared twice.
Use CocoaPods and link AFNetworking to my Framework. This is causing this error: -lPods is not an object file (not allowed in a library).
Build something like the Aeris SDK where the third part developer using my Framework will be responsibly to add AFNetworking to their project.
I think that option 3 is the best but i don't know how to do that. How can i dev my framework calling AFNetworking classes/methods but do not include on the final framework product?
Thanks!
That's a very bad practice to use third party library in you library.
Ideally you should avoid doing that.
But if you really need it, you can define and add prefixes to class names.
Refer this article Avoiding dependency collisions in iOS static library managed by CocoaPods
Ok. I decided to go with the option 3.
A just added all the header files from any third-party lib to the my framework project (you can also add the .m files but not include them on the static library target).
And a i also documented everything, so developers using my framework will know what are the dependencies and how to include/install them on their own projects (including third-party lib versions, CocoaPods support, etc).
I decided not to go with option 1 because that will cause some situations where a project will have two copies of the same lib compiled on the final app. Even if a change the namespace for the libs on my framework code (to prevent "duplicated symbols" errors) that will still cause some other possible problems like an APP with larger size, possible bugs related to two or more instances of the same lib running together, etc...

How to reuse Swift code in other projects?

I wrote a class in Swift. I want to use this code in two separate iOS app projects that I wrote. Both the shared code and the apps are written in Swift. What is the best way of doing that?
I tried to create both a framework and a library in Swift and then add it as a sub-project to my app. In both cases I could not make the app see the module. I tried to add the shared module to "Target Dependencies" and "Link Binary With Libraries" of the main app's target. No luck - the app still can not see the classes of the shared module.
Using Xcode6 Beta6 at the moment.
Solution
As Konstantin Koval and Heliem pointed out, all I needed is to use public in my class and method declarations, in the shared module. Now all works, both if I use workspace and if I add the module as a subproject.
Update
I just found an excellent easy solution for reusing code between projects in Swift. It is called Carthage (https://github.com/Carthage/Carthage). This is not a plug as I am not affiliated with it in any way, I just really like it. It works in iOS 8+.
Create a new project (iOS Cocoa Touch Framework) for your reusable code
Move your classes to that Framework project
Mark your methods and classes, that should be visible to others as public
Create Workspace.
You can create a workspace on step 1. When you create new Framework project, Xcode will ask you if you want to create new workspace and add that project to workspace. This is the best approach
Add both your project and Framework to the workspace
Select you project target -> General tab. Add Framework and Libraries (add your library here)
When you want to use code from your Library in swift file, import it using import 'LibTargetName'
You can take a more programatic approach by using SWM (Swift Modules): https://github.com/jankuca/swm
It is very similar to npm (node.js package manager) or bower (client-side module manager); you declare your dependencies in a swiftmodule.json file like below. It does not have a central module registry like the two mentioned JS solutions, it only accepts git URLs.
{
"name": "ProjectName",
"dependencies": {
"Dependency": "git://github.com/…/….git"
}
}
…run swm install and have the Dependency module (compiled into a *.swiftmodule binary) ready for import in the .modules/ directory.
import Dependency
And if you prefer to skip Xcode for app development, you can also build your whole app using swm build (more info in the project's readme).
The project is still in early stages but it makes itself useful a lot for me at least. It provides the most clean (and clear) way of creating importable modules.
Here is a video which is very straightforward: http://eonil-observatory.tumblr.com/post/117205738262/a-proper-way-to-add-a-subproject-to-another-xcode
The video is for OS X instead of iOS. But you will get it and figure out the process for iOS.
Let's assume that AppA needs to reused code from SharedProject.
The following process works for me in Xcode 7 Beta:
Create SharedProject. Project type must be Framework instead of Application. You write common code in this project and mark the code as public.
Open AppA in Xcode, open the folder which contains SharedProject in Finder. Drag the .xcodeproj file of SharedProject from Finder and drop it into the root folder of AppA in Xcode Project Navigator.
AppA --> Build Phases --> Link Binary with Libraries. Add SharedProject.
import SharedProject and reuse code from SharedProject!
Edit:
Nowadays I suggest you use Carthage. It's better than the home made solution above.

Resources