Managing multiple Xcode projects that share code with git - ios

There are already several SO questions that address this issue, but I haven't found one that completes addresses my situation.
I have projects X, Y, and Z, that all share a common framework C. The projects and the framework all use Cocoapods. I would ideally have three separate Xcode projects that all include the common framework C. So I would have, X+C, Y+C, and Z+C. Then, when I push X+C, I want it to push the changes of X to repository X, and the changes of C to repository C. I would also like to be able to pull changes from C into X, Y, or Z. I would like to work on framework from within project X, Y, or Z, and debug the framework from each of the projects X, Y, or Z.
Is this currently possible? I know there is the concept of submodules, but it doesn't sound very robust (likely to fail with branches).

Yes it's possible with pods. You can create private framework C.
If you define path for your C framework in podfile for your projects then the framework will be generated as development pods and you can debug and edit it.
Example part of podfile
'C', :path => './C/Source')
You can use relative path. Also you can define framework in this same git repository or add submodule for your git repository project

Related

How to manage transitive dependency for local Xcode projects

I have two Objective C dynamic frameworks X and Y and another Objective C app Z.
All these frameworks and apps have been created by me locally. Framework X is the very base framework used by framework Y and the app Z. So the dependency graph is something like the following:
Y ---> X
Z ---> X
Z ---> Y (---> X)
I want all my targets to be debuggable and to pick the platform tools based on run destination (device/simulator). So I have added dependencies as sub-projects to the main projects and have linked them with the dependent projects to generate implicit dependencies by Xcode.
The set up 1 and 2 works great independently. But I am struggling with the set up 3 which is creating duplicate build rules for the target X due to transitive dependency on it (target Y and Z both depends on it) and subsequently failing the build process.
Anyone has any idea on how to deal with this situation? Thanks in advance!
It seem that in Objective-C, We can't link a dynamic framework to another dynamic framework, or to a command line tool. It's always raise an exception, when running in production
Dyld Error Message:
Library not loaded: #rpath/XFrameworks.framework/Versions/A/XFrameworks
For your situation, What I think might solve your problem
X (Core features) can be built in static library
Y can be built in type of dynamic framework
will link with X library
or link with others (I mean some another code base)
Z (your application) will link with Y framework
Actually there is a way through which I could finally solve the issue of transitive dependency in Xcode. I have to use Workspace (.xcworkspace) rather than a Xcode project (.xcodeproj).
To get it done use the following steps:
Close all related and open Xcode projects.
Create a new Workspace in the root directory from File > New >
Workspace. Open the workspace by double clicking onto it and
drag/drop the required projects to the workspace.
Add the independent framework (X in my question) output to both of
the dependent project targets (Y and Z) by adding it under the
Framework and Libraries section. Embed the dynamic library only to
the top level application (Z) and do not embed it to the
intermediate dependent target library (Y).
Add the intermediate framework (Y) to the root level app under
Framework and Libraries section and embed it to the root app bundle.
This setup works like a charm for me without ever creating duplicate build rules and it spontaneously picked up the dependency as well.
Obviously, you can not do this if your independent framework is a static library and in that case it will be linked to both the dependent targets causing duplicate symbols issue during linking.

Hundreds of targets, same code base in xcode configuration

We are at 400+ targets in xcode. It still works fine but there has to be a better way to set this up by keeping the same code base but not having all those targets which could slow down xcode.
Android Studio lets you update the appname, which loads that folder from disk so only that project is loaded to run and program against. In XCode that is not the case, all targets are available.
It's been years but is there a better way now, with hundreds of targets that doesnt involve Git or Branching? The questions in regards to this are old and only for a few projects, we are talking hundreds here.
Your question lacks enough context to make a specific recommendation but in general...
Use Frameworks
If you can, combine sensible things into a single (or multiple) framework target. Frameworks can be more than fancy wrappers around a dynamic library, they can contain helper tools and such as well.
Use Workspaces
If there is a logical grouping to your existing targets you can separate them out into their own Xcode projects. Once you have them in their own projects you can create a workspace that references those individual projects. Even if the combined workspace loads in everything upfront (I don't think it does tho) you can still open and use the separate projects for a fast and fluid experience when working on the components.
Use static libraries
If you have a ton of targets such that one requires A, B, and C, but another needs B, C, D then you can actually put A, B, C, and D together in a static library and rely on the linker to strip out unused code from each individual target. This obviously does not reduce the number of targets you have, but you can make the static library its own project and include it in a common workspace. This will also speed up compilation as the files only need be compiled once.
Parameterize Targets or Use Schemes
If your targets are simply wrapping some external build tool/script with hardcoded parameters (I've actually seen this) you can actually pass a ton of existing variables from xcode to these external tools and eliminate "duplicate" targets. Similarly you can add new schemes if some of your targets are simply permutations of each other. A good example I've seen of this are people that have a separate target for "sanitized" (address sanitizer, etc) builds you can instead create a sanitization scheme instead of a target.
Use "Script" Build Phases
If some of your targets are doing something such as linting then you can instead employ a script build phase to call the linter instead of having a separate target to do it.
Offload Targets to an External build System
Xcode can have targets that simply call out to an external tool/script using the Script build phase (and using variable parameters as mentioned above). This can make sense to do if you already use another build system (make, cmake, etc) for another platform. Use Xcode only for the Mac/iOS specific targets and offload everything else to a cross platform build system.
If the build system outputs errors in a format Xcode understands it will even show file and line errors the same as native Xcode targets. I've seen people write thin wrappers around external tools to catch parse and reprint errors into such a format.

Link one framework with multiple sub projects in Xcode workspace

I have a workspace that contains multiple projects - Project A and Project B. In this case, Project B is a dependency of Project A. When Project A is built, project B is then added as a dynamic framework to Project A.
- Project A
- Framework 1
- Project B
- Framework 1
Both Project A and Project B rely on a framework (Framework 1). I add this framework to both projects by going Build Settings -> Framework Search Paths -> Add path to Framework 1. When I compile the project, I get Xcode warnings saying:
Class XXX is implemented in both PATH 1 and PATH 2. One of the two will be used. Which one is undefined.
What I really want to do is to tell Xcode to link the Framework with both sub projects but to understand that this is one common library that doesn't need to be duplicated. I have two questions:
Is this possible?
If it's not possible, will this warning cause any problems? For example, is it that Xcode will just use the source code from either Framework location or is it that Xcode could run parallel instances of the framework code which could cause issues with singletons being duplicated.

InterProject communication in XCode

My project architecture is, a workspace which has two projects(Project A & Project B). Project A has three more sub projects(Project X , Project Y, Project Z).
Workspace
Project A
Project x
Project y
Project z
Project B
Project B is more a kind of utility project. It needs to be re used in Project A, Project x,Project y, Project z and elsewhere it could be. I am starting to do a prototype. But face challenges in linking Project B in other projects. Every time i need to add the .a file manually into all other projects. Do we have any solution to dynamically link?
I tried this approach as well. I moved project B inside Project A below Project z. But i was not able to access the classes in Project x, y, z because all the projects are in the same level.
Any solution to dynamically link projects in the same level?
You need to add Project B as Target Dependency from Build Phases to other projects, that way Project B is built and added to other projects just as you'd like.

Two related iOS apps in one CocoaPods workspace?

I am working together with some friends on a iOS project.
We are using CocoaPods for integrating third-party code (Facebook-iOS-SDK, ..) and sync the whole Xcode workspace (including the Pods Project) with Git and bitbucket.
Everything works perfect and we are very happy with this setup.
The only problem is, that we have to build a second application and the two apps will share a lot of common code.
Does it make sense to just add a second target to the workspace or is it better to create a private pod?
Other possibilities? We want't to keep things as simple as possible...

Resources