Best way to integrate a complex Xcode project into another - ios

I would like to integrate an existing Xcode project A into another project B so the second one could reuse some features.
Project A :
quite complex, manage authenfication + session, a lot of dependencies betweens classes (notably UIViewController)
relies on a dozen of Cocoapods dependencies
the project lives on its own : it's a sale channel/ticket shop that is already deployed on the store as it
constant evolution
Project B :
Project customer side that would love to integrate some parts of the sale channel
Complexity might be very variable (using Cocoapods or not, etc)
Basically we can either deliver and package the e-commerce shop for one of our customer if he does not already have an iOS application, or we have to integrate it in their existing one.
Expectation :
ideally we could pursue the evolution and iteration on the core Project A without having a lot of work to make it available for integration (it would be more cost efficient for us to work on a single project than on the core one and separate SDK/Library made from scratch)
we want to make it easy to integrate for the customer on its own
The approach we have been thinking to are :
build a .a library file. But it does not seem really practical considering the size of the project
dropping the .xcodeproj from A into B (à la ZXing), but it was a pain because of Cocoapods dependencies
Simply adding all the classes from A into B (with a proper packaging into folders first), manage Cocoapods for B (add dependencies from A if Cocopoads already used or set it up), and make all imports easier by editing .pch accordingly.
What would be your suggestion ?

Since you are already using cocoapods I would try to do a private pod(s) with the shared characteristics. That way you can easily track versions across projects and use the same tool to manage all the dependencies.
This approach also would make easier for the customer to integrate as he will see the shared code from the pod as long he has access to the repository but not the complete main project.

Related

Why we have to use dependency manager?

I am developing an app for IOS,and I have to use some framework.
as you know Cocoa pods and Carthage are dependancy manager for iOS and mac OS
my question is "why we have to use dependancy manager?, instead of using dependancy manager just clone that project[was written by other programmer and can be used as framework] and drag and drop to your project ??"
Thanks for your answers
Few things that you need to think about is:
Updating your dependencies when new versions came out.
Updating dependencies for multiple platforms.
Interdependent frameworks and different framework versions for dependant frameworks.
Basically, time that you will spend on maintaining dependancies for your project will grow as your project grows. Dependancy managers allow you to avoid all this unnecessary and boring work.
There are a lot of other reasons to use DM instead of just importing frameworks. More about you can find here. And here.
At some point you might want to use 3rd party code to get extra features or something, you can copy the source code but how you will update it in the future? keep coping it again!!
Also some of your 3rd party code might depend on other 3rd part code, and if you copied it twice, you will get duplicate symbols.
Dependency managers handle all this for you.
My advice is to use Carthage or submodules, but do not use CocoPods, anything that touches the project file is not a good practice with Apple.
Why Libraries are Your Friend
While you aren’t strictly required to use third-party libraries or
frameworks, they can definitely save you a lot of time and let you
focus on polishing your app instead of typing out countless lines of
code that you simply don’t need to write.
You can use third-party frameworks and libraries without a dependency
manager too, and you can get hands-on tutorials about them right here
on this site. For example, there’s our Alamofire tutorial, and our
SwiftyJSON tutorial.
Without a dependency manager, you simply add each library’s code to
your project manually. However, this approach has several
disadvantages:
Updating a library to a new version can be difficult, especially if several libraries must be updated together because one depends on
another.
Including a library in your project makes it tempting to make local changes to the code, making it harder to update to a newer version
later.
Determining the current versions of libraries used in your app can be hard to do, especially if you don’t proactively keep track of them.
Finding new libraries can be difficult without a central location to see all the available libraries.
CocoaPods helps you overcome all of these issues and more. It fetches library code, resolves dependencies between libraries, helps
you search for and discover new libraries, and even sets up the right
environment to build your project with minimum hassle.
Courtesy
https://www.raywenderlich.com/97014/use-cocoapods-with-swift

Create Framework / Library / Module of Swift Objects in Xcode

I am a (very) novice iOS/Swift programmer with a basic question about moving reusable software objects to their own ... something.
I am developing three iPhone apps that present information from three distinct data sets. Those data sets contain unique information but are structurally similar. As such, the apps share some Swift classes that are identical, specifically the classes that model the data. As I continually refactor the code, I find that when I tweak a class in one app's project, I have to remember to go to the other two projects and make the same tweaks to the same classes for those apps. It's getting to be a big headache.
What I would like to do is have one class definition in its own ... something that I can share, link, import, or attach to/from each app's project. From my online research, I suspect that the ... something is a library? or maybe it's a framework? or a module? I have found all three terms are used, but I am not sure how they relate to each other.
Given that all of the software I am writing is in Swift, does Xcode support what I am trying to do? Thank you!
It seems you have the issue of needing the same Swift class in multiple projects. You could build a Framework (aka Module) for this class then copy it in to each project. This is probably the formally correct approach but it is a bit of overkill for just a single class.
Instead, you could just make the file in the Navigator panel a reference in each project to the one actual file.
You could also make a Workspace and then put each project into the workspace and just have the file at the top level (but this may introduce some build complexity).

How to share and keep dynamic libaries up to date?

So I watched the whole video ("Building modern frameworks") here and I still have some questions. The last 11 minutes is the actual demo if you want to watch it, but to sum up he creates a framework and then stops. He does not show how to share it or place it in other projects.
1.) In order to use the frameworks in other projects I have to import both the simulator framework and the device framework to work? Is that correct?
2.) Can I copy the actual framework out of the build folder to use in other projects?
3.) Is it possible to keep the framework up to date among different projects? Like change method A in the first project and the change is also visible in the second project?
4.) The guy from here has also an option for keeping pieces of code in sync with different projects. In short: He makes a project (framework) places all the code in it who should be the same in other projects. He then copies the framework in other projects and does not copy the framework in there, but just links it. Is this a good method? Will this be accepted by Apple?

Multiple frameworks and common library

Using iOS 8, Xcode 6.
Let's say I have 2 dynamic frameworks, frameworkA and frameworkB and they are both dependent on libC. In addition, I have an app that uses both frameworkA and frameworkB. My original thought was to make frameworkA and frameworkB umbrella frameworks and libC a subframework. However, Apple advises against umbrella framework and this post describes why umbrella framework is a bad idea due to potential linker conflict issue.
My second option is to use cocoapods (still new to this so a bit fuzzy on details) to use libC as a pod which then gets compiled into frameworkA and frameworkB. However, it occurred to me that both frameworks still has its own copy of the libC. Since the app uses both frameworks, will this result in a linker conflict issue as well? Is there a better way to solve this problem?
UPDATE
#Rob The projects I work on do require complex dependency management but I kept the problem domain simple in the question to try to better understand how and if using cocoapods can help solve the linker conflict issue with umbrella frameworks. I work with a team of developers who write libraries and can depend on each other's base libraries that provide versioned common APIs. We are required to package and deliver as few libraries as possible to a different organization that is building an app with our libraries and one of their key requirement is that we deliver a dynamic framework.
The best way to solve most problems is to put all the code in a project and compile it. When you have specialized problems that make that problematic, then you should look at other solutions, such as static libraries, and finally frameworks.
Static libraries can make sense if you have a code base that has pieces which require different build requirements. If all the pieces have the same build settings, then just "add files" them into your project from a "common" directory and build your project. Static libraries can be attractive if your build times are very significant and some pieces never change and you want to be able to "clean" without rebuilding those parts. But wait until you start having that problem before you go making complicated multi-package projects.
If you sell closed-source libraries, then frameworks are very attractive. You should strongly avoid adding third-party dependencies for the reasons you note. If you must, the best way is to help your customers package all the pieces as frameworks and have them link everything at the end. But that adds a lot of annoyance; so make sure you really need that third-party piece.
You might also consider frameworks if you have a very large piece of reusable code that has its own lifecycle separate from the main products. But again, keep it simple. Avoid third party stuff inside of it, and if you must have third party stuff, then have the consumers link it at the end.
(This isn't a new solution, BTW. When you use curl, if you want SSL, you need to also download and build OpenSSL and link them together yourself. Curl doesn't come with OpenSSL built in.)
But in the vast majority of cases, this is all overkill. Don't jump to frameworks. Don't jump to libraries. Just put all the code in the project and compile it. 90% of your problems will evaporate. iOS projects in particular just aren't that big usually. What problem is a framework solving?
If you have a lot of code that your organization uses repeatedly in lots of products, then I have heard many teams have good luck using internal CocoaPods to manage that. But that's just to simplify checking the code out. It still all goes into a project and you compile it together into one binary; no frameworks needed. Dynamic frameworks are a nice feature in for certain kinds of problems that were really painful before. But, for most situations, they're just complexity looking for a problem.
(If you have one of those specialized problems, edit your question and I'm happy to discuss further how you might approach it.)
EDIT: (You fall into that "specialized problem," so let's talk about it. I did, too, for many years inside of a large multi-team Mac and iOS dev environment. And we tried just about every different solution, including Frameworks. They're only new on iOS.)
Within an org like you describe, I would strongly recommend packaging each dependency as its own framework (AFNetworking, JSONKit, etc) and each of your pieces as a framework, and then have the app devs link all of them together at the end. In this way, it is identical to other dynamic libraries (libcurl, openssl, etc.) which require the app dev to link everything together.
In no case should dynamic frameworks include other frameworks that could otherwise be required (i.e. frameworks should never package "third party" stuff). That will explode. You cannot make that not explode. You'll either have bloat, build conflicts, or runtime conflicts. It's like merge conflicts. There's a point at which a developer has to make a choice. App-level linking is making that choice.
Making components over-dependent on other components is the source of decades of trouble, from Windows DLL Hell to iOS apps with competing crash handlers. All the best component systems look like Legos, where the end user assembles small pieces that have minimal dependencies. As much as possible, make your internal frameworks rely on nothing but Cocoa. This has some tangible design influences:
Avoid directly requiring logging or analytic engines. Provide a delegate interface that can be adapted to the engines of the caller.
Avoid trivial categories (methods that save just a few lines of code). Just write the code directly.
Avoid adding framework dependencies that aren't buying you a lot. Don't add AFNetworking just to save a few lines of code over NSURLConnection. Of course if you're heavily relying on the features of another framework, that's different. But as a framework developer your threshold should be quite high before requiring another framework.
Strongly avoid being clever in the build or version control. I've seen too many cases where people want to make everything "automatic" for the app-level developer, and so make the system really complicated. Just say "you need to link this and import this and put this in your app delegate startup." Don't create complicated build and version control systems to save 2 minutes on the first build or two lines of initialization logic. These things blow up and waste hours to work around. Don't get clever with +load magic. Just make it clear and consistent.
And of course, good luck. Supporting other devs is always an interesting challenge.

iOS / XCode separate layers in targets

I am fairly new to iOS and XCode and come from .Net background. So in Visual Studio I would usually separate the layers of my application (say WebApp layer, business logic layer, data access layer etc.) into separate project so I can have control over what each project depends on etc.
So my question is if there is something similar in XCode? I tried using the static library template for a target and it seems to be working but I am wondering if there are any drawbacks for this approach? All the examples I find on the Internet just show a folder structure in the app target for the layers is this the preferred way of doing it and why?
I am also using Swift if that makes any difference but I still do have dependencies on 3rd party libraries developed in Objective-C
New in Xcode 6 / iOS 8, you can make a framework, thus dividing your code into multiple targets. This is a nice easy way to separate reusable functionality. It also has the advantage of privacy; in Swift, each framework is a module, and one module that imports another module can see only those members of the imported module that are declared public.
In general, however, I would suggest that you not worry about this; just keep your classes organized conceptually using the MVC architecture that Cocoa encourages, and physically organize them within your project using "groups" (the fake folders that appear in Xcode's project navigator). The reason is that very little of your code is going to prove to be reusable anyway, so it's really just a matter of making editing / developing / maintaining this project as easy as possible.

Resources