I have an app, it's currently in the app store.
I have an idea for another app, that would share a lot of the same structure as my published app. They're both photo manipulation apps, so the codebase for importing, sharing, saving, rotating, etc. would all be shared between the two. The type of photo manipulation would be different, though.
My thinking is, when I update app #1, I want those changes in app #2, and vice versa.
What is the best way to achieve two apps from one codebase?
Strategies I've contemplated,
One project file, two targets. That way the codebase for both apps will always be up to date, though the project file/directory will be a little messy, to be sure.
Branch the app in git, frequently merge changes between the two branches for the classes used by both.
I'm open to other ideas, too.
I've found people discussing this, but mostly in relation to minor changes... i.e. one app with a few different brandings / data files. My two apps will be reasonably distinct, so I don't think those techniques necessarily apply.
Create a static library with your common photo manipulation or other shared functions, and rework the existing project to add the library as a dependency and use the library's headers folder in the User Header Search Path. Then you can essentially clone your old project and start modifying straight away with access to all of the shared library functions.
Two targets of the same project seems applicable to your situation, though. If you've got a large amount of overlap then you just basically need to write a second UI / workflow for that, right? If yes, using two targets makes a lot of sense.
I suggest split your existing app into TWO parts. Separate out all the common portions as a generic DLL/class library, and use the dll in both your existing and new project.
As the first project development progresses, use the latest version of the dll in your newer project, using appropriate deploy scripts. This way your new project can even be in a seperate codebase
I would suggest you take a look at using git submodules in both your apps. This have worked perfectly for us when sharing code in multiple apps. Basicly we use a structure where we in each Xcode project have a "Components/" folder where we keep submodules.
App A can have the submodules like this:
Components/SomeAmazingPhotoManipulationStuff
Components/MaybeSomeUsefullFoundationThingsYouUseOften
App B might only use:
Components/MaybeSomeUsefullFoundationThingsYouUseOften
The idea here is that you can update your submodule projects seperately and just go into each App where it is used and update submodule to the latest version of the component, successfully sharing stuff between apps without losing version control. It will also scale well to many projects.
And ofcourse you can branch your submodules and have App A use one branch and App B another, if you do some specific stuff or very experimental stuff in one app only or whatever scenario you might think of.
Ever since we started using git submodules like this we have not looked back or even considered any other solution.
Related
Lets say I have an iOS App for let's say, Football news, now I want to create an other version for Basketball news that will be based mostly on the Football App but with a freedom to create a different behaviour in some aspects of each app + adding more apps in the future for other news subjects.
An other condition is that they will have a separate CoreData model, assets, icon etc.
As I understand I have few options:
Manage the apps separately, place them in the same directory and point to the shared files in the first (Football app).
Create a different target for each app in the same project
Create a Workspace with one project that will hold the common code and a project for each project.
What are the pros / cons for each option and what are the best practices in this situation ?
Just to clarify - the apps I mention are an example, the App is not for news, and it must be a different app for each concept.
Thanks
I work in an enterprise environment, and we have a mobile app that's a product of the company I work for. We sell licenses of that software to our costumers, which are always huge companies. Our app doesn't go through the App Store.
Each of our clients have some sort of customization on the app, either by simply changing their logos or even adding some specific features for one of them. What I mean by this is: we have to deal everyday with a situation very close to what you are describing, and here's my two cents.
In advance: sorry if I'm too honest sometimes, I don't mean to offend anyone.
1. Manage the apps separately, place them in the same directory and point to the shared files in the first (Football app).
Well... That's a weird solution, but it sure could work. It might be hard to maintain locally and even harder when using SVN/Git (specially when working on a team).
I had some issues before related to symbolic links before, but I'm not sure if that's what you are referring to in this option. If you explain a little bit better, I can edit this and try to give you a better opinion.
2. Create a different target for each app in the same project
That's a better start, in my opinion.
We use this approach mostly to handle various possible backend servers. For example, one of our targets uses our development backend server, while another target uses the production server. This helps us ensure that we can use the development-targetted app without risking serious costs to our team (due to a mistakenly placed order, for instance).
In your case, you could for example configure preprocessor macros on the targets to enable/disable some target-specific feature that's called by code. You could also use different storyboards for each target.
The downside of this option is that the code will be messy, because every piece of code will be on the same project. This is the main reason why I'd go with option #3.
3. Create a Workspace with one project that will hold the common code and a project for each project.
Again, I'd go for this. To be honest, we're not using this at our company YET, but that's due to internal reasons. I'm trying to get this going for our projects as soon as possible.
I wouldn't call it easy to set up, but if done properly it can help you save some time because of maintenance reasons. You'll be able to reuse any code that's possible to reuse, and still be able to keep your target-specific images, classes and views to their own "container"(project).
This way you'll get a default project (the app itself), multiple targets for it, and a "framework" to keep the code for each one of the targets. In other words, you'll be able to share code between the multiple targets/apps, and at the same time you'll be able to separate what belongs to each one of them. No messy project :)
I'm not sure about how CoreData is compiled by Xcode, as we're not using it. But check out the answer I just did for another question. It's not Swift, but that shouldn't make much difference as almost all of the answer is about configuring the workspace to achieve this solution. Unfortunately I think it too big, that's the reason why I'm linking the answer instead of pasting it here.
If you need any help setting that up, let me know and I'll do my best to help you.
This may be overkill for you, but this solution is scalable. We had to build ~15 apps from one codebase
The problem we had to solve was branding. Application design and flow was basically the same, along with the structure of the data we received.
A lot of the heavy lifting was done by our CI server.
We had a core application with all of the UI and some common business logic. this was known as the White-app.
We then had a specific project (frameworks didn't exist then) for each of the different endpoints & data models and mappers into the White-app's view models. Those applications were private pods and managed by cocoa pods.
Our CI was configured in a way that it would compile all 'Branded' app's by copying, compiling, signing all the varying plist, assets, string files into each application along with each of the specific data models for each application. So when a end-to-end build was triggered, it would build all the different branded apps.
The advantage of this is the target layout within Xcode is not cluttered, we had a release, test and development target which applied to each application built. This meant our project was succinct with no risk of accidentally editing a branded apps build settings.
This solution will also provide you with an .xcworkspace (mostly utilised by cocoa pods) which contains reference to the the different model pod's
This solution because it is work to setup i.e when building in Xcode we created a special scheme which installed a pod and copied in all the correct assets (as CI would)
This is a question that many developers were thinking about many times, and they came up with different solutions specific to their needs. Here's my thoughts on this.
Putting the common parts, which you could see as the core, into something separate is a good thing. Besides supporting reusability, it often improves code quality by the clear separation and clean interfaces. From my experience, this makes testing also easier. How you package this is determined by what you put in there. A static library is a pretty good start for core business logic, but lacks support for Swift, and resources are painful to include. Frameworks are great, but raise the bar on the minimum iOS development target. Of course, if you're just using very few files, just adding the folder to your app projects might work as well - keeping the project structure up to date can be automated (the dropbox/djinni thing does this), but it's a non-trivial approach.
Then there are the actual products to build, which must include the core module, and the individual parts. This could be a project with several targets, or a workspace with several projects, or a mix of both. In the given context, I make my decision based on how close the apps relate. If one is just a minor change from the other, like changing a sports team, or configuring some features out as in light vs. pro, this would be different targets in the same project. On the other hand, I'd use different projects (maybe arranged within a common workspace) if the apps are clearly different, like a Facebook client and a Twitter client, a board game app for offline play and an online gaming app etc.
Of course, there are many more things to consider. For example, if you build your app for clients and ship the sources, separate projects are probably needed
.
It's better to create a framework that will contain the most shared code you need in all 3 options. Also, the first option is bad in any case. For better control it is better to have 2 or 3 option. The workspace is more preferable, imho, since it will not harm to other sub-projects if you, for example, will decide to use cocoapods. The workspace also allows you to have a different set of localizations in each project. Plus, only targets that related to a specific project will appear in targets list, which is better than a bunch of target in one pile (if you have, for example, a share extension in all products - it will be frustrating to find one you need). What you choose depends on your needs, but both second and third options are good enough.
I think that the best way to do that is something that encloses all the 3.
First I would create a configurable framework, that shares with all targets everything that they have in common, from UI (elements such as custom alerts etc) to business logic.
Then I will create different bundles or folders for each target checking the membership target (in these way you guarantee only to import the exact resources), then using preprocessor macro you can create a path builder specific to the right bundle or directory where your resources reside.
During the years I've collected some interesting links about best practice.
Here they are:
Use asset catalog with multiple targets
Use multiple tagets XCode 6
XCode groups vs Folders
Create libraries with resources
Create lite and pro version of an app
I know that in SWIFT they made some changes about preprocessor macros, so some article are still valid but little bit outdated.
We all face this kind of situation. But here are the things I do and maybe you can pick something here that can help you. (I hope).
have a project that contains the core features
have modular projects that can be used by other variants of the product
manage the project under version control or git flow that will help keep the main source / project under the main branch accessible through branches / features
create new branch / feature for the project variant if necessary or just enable / disable or use project modules needed for that variant (whatever is most appropriate on the current setup).
if the app has a web service that it connects to, provide a licensing stage where the mobile app will do it's first ever request to a common (to all variants or even all mobile apps) web service URL. This web service interprets the request and respond with the given information to what the app's settings will be (e.g. web service to connect to for the given license number, modules to be enabled, client's logo, etc).
the main projects and modules created can be converted to frameworks, libraries or even bundles for resources & assets depending on the level or frequency of changes done to these items. If these items are constantly changing or updated by others, then don't compress it; have a workspace with targets that link the whole project / module to the current project variant so that the changes to these modules reflect immediately (with consideration of version control of course).
Scenario. A team has 5 developers and all developers are working independantly on 4 different projects. iOS / OS X. A library has been created which encompasses multiple subclasses, categories and so on for reuse. Each member in this team needs to be able to use this library for each project. The library itself has it's own git repo. When someone makes a change to the library it is handled the same way a standard project is handled and a merge is completed.
Problem I see with this approach...
1. This doesn't seem like common practice for a proper Xcode / Git workflow and I feel a framework or similar would be a better tactic.
2. Although this is great for sharing I can also see this as an issue since one issue with the library will break all existing projects.
3. Adding classes to this library requires each project to be updated to include the new headers.
4. Directory structure can differ on each machine therefore a simple clone of a repo will not work as expected without folder modification.
What is the best way to handle your own library of classes in a Xcode / team environment of multiple users?
If you must have a single library for all this - you can go two ways:
Nobody changes the library, the library is as it is and everyone just pulls it down and then makes changes in their code to make-up for the shortcomings they find in the library.
Everyone changes the library, but the project has A master branch, a stage branch, and a branch for every single project associated with it. Devs change and update their respective project branch, and another person (perhaps one of the project devs maintains the flow from the multipe dev to the single stage to the single master branch). With this approach, it requires much more management but you can slowly improve the main library without potentially breaking other projects as everyone has their own specific know-to-work version of the library in a branch specific to their project, only re-syncing with the master when safe.
Suppose that I have similar apps that share a lot of code. Paid and free versions, whitelabeled apps for different client companies, that sort of thing. In general, the differences between apps would be relatively minor; some images would be different, some text would be different, some kind of flag values would be different--the shared code would check for those values and change behavior accordingly.
A nice bonus, but not essential, would be for each app to be able to add code to extend/override some of the shared code.
I have read of several different approaches--there may be more I haven't considered.
one .framework file used in many repositories
I don't know much about this, but I gather it would be like making a JAR in Java; compiling code to be used as-is by other programs. This might work well for a general-purpose library to be used by many different kinds of apps, but as far as I know it is not suitable for the above purpose (correct me if I am wrong).
one repository, one project, multiple targets
From what I understand, this is most popular for the "one app with paid and free versions" situation, where there is only a very tiny difference between the apps produced--they are essentially the same app.
However, I don't know how flexible this is in terms of changes between the different targets. I gather it's possible to set a different .plist file for each target, and that can result in different text, flags or (through some kind of awkward workaround) different images for the apps, and that is it, correct?
I also feel uncomfortable with using one repository for multiple projects, but when they are this closely related, perhaps it doesn't matter.
one repository, one workspace, multiple projects
Although this seems to be a cleaner division among the projects, I'm not sure if there's a good way to separate resources for the different projects. The most logical solution would be to have different folders for resources for different projects, and include them in the workspace with only one target each--but I can't seem to do that. Apart from that, there seems to be little difference between this and the previous option.
So, what is the right way to make shared code for multiple projects that only have a few differences from one another? Is it one of the above methods (and if so, how do you do it?) or is it something different?
I prefer to have separate projects and a separate folder for each project.
You then bring each shared unit into the project as you need it. Shared features (most features) go in the shared units.
If you want to upgrade one project with the latest Rest.h and Rest.m, you bring it into the project folder. Maybe on the next project, you're not ready to upgrade to the latest.
You will have duplicate files (one for each project), but it allows you to update, test, and finely control each project atomically.
One repository or not, it doesn't matter, since the projects will have different folders and the shared files will be duplicated (possibly different versions in each, with the trunk having the latest shared files).
On a side note, I hope these many similar apps don't all end up in the App Store.
The scenario is as follows. I am working at a company that started out with one iOS application. Now, the company is interested in creating a second iOS application, that shares much of the same code base. The original application was not written with the intention of being reusable, as it was not known at the time that a second similar application would be created. In future, there may be even more similar applications that build on the existing code base.
We are trying to determine the "best" option with respect to how we maintain the source code going forward. So some of the options we're contemplating include single repository with shared library, one repository for shared library and one repository that contains all of the iOS applications, one repository for shared library and one repository per iOS application, etc etc. There's also the question of whether to use git submodules or not if using multiple repositories etcetera.
Currently, the two applications + library are all in one git repository. One of the advantages of this is that a developer can checkout a commit of the single repository and expect the product to build, without having to worry about updating multiple repositories. Basically, the developer doesn't have to be concerned with multiple repositories needing to move in lockstep with one another or requiring some specific combination of repositories commits for a build to work. The developer also doesn't have to worry about cases where another developer may have remembered to commit one repository, but not the other.
Here are some more things I've considered:
Submodules
I've used submodules before, but am no expert. My understanding is that the "super" repository containing a submodule also stores a reference to a specific commit of the submodule. This partly deals with ensuring that multiple repositories (i.e. application + library) would move in lockstep, though I'm guessing there are still issues with needing to manually pull changes from the sub module. Also, issues with a submodule commit not being available to pull if a developer happens to forget to push its changes and it is referred to by the super repository.
One nice aspect of submodules is that it creates a stronger semantic separation between the library and the applications which happen to use the library. Whether this is useful in practice, I'm not sure.
Single repository
As previously stated, this is what we're currently doing. Two applications + shared library code all in one repository. The greatest concern has been around the relatively non-existent ability to isolate changes between project one and two and the library. E.g. someone makes changes to both some library code and some application code in a single commit. Then, another developer just wants the changes in the library code.
One nice aspect of single repository is that everything moves in lockstep - nobody has to worry about keeping multiple repository versions matched. If using XCode workspaces, refactorings are even possible across the two applications.
Branching
Another option is to use some kind of branching model, either in a single or multiple repositories, to manage the code.
Ultimately, we're just trying to figure out a good model going forward for managing two or more iOS applications plus shared library code. Whether this be achieved via multiple repositories, submodules, branching models, or something else. Any general suggestions on the pros and cons of the various options?
Use submodules. You don't need to be an expert because they are really easy to use. Especially when combined with a GUI like SourceTree. I had the exact same scenario as you and that is what I did. SourceTree will even warn you if you are trying to commit a repo that has uncommited changes in a submodule.
A single repository is ludicrous. That would mean that every time someone new wanted to download a project, they would have to download them all.
Branching is going to turn out to be too complicated with making bug fixes that apply to all relevant branches.
The structure I have for my current project is:
Project repo (For the project I am personally working on)
-Project base repo (For shared code between team members)
--Utilities repo (For code that is reusable in any project)
Cocoapods, they make managing related code between applications simple.
We had a similar base for a suite of apps and initially it was a huge pain to manage but once you get custom cocoapods running you will never look back. You should check out this for a starting guide on managing your own cocoapods.
It's free, it's powerful and you will wonder why you never used them sooner.
I am developing an iOS app. Right now it is one app and two targets (app and tests).
Getting closer to publishing I want to split this app into three apps with lots of shared code and shared tests. (Think of free version and full version for App Store and prototyping app that will not be published).
Would you set up multiple projects in Xcode (1 library project and 3 app projects) or keep all in one project and only set up multiple targets?
I think you have at least 3 options here:
Separate projects. It is more difficult to share code across projects, but with Xcode workspaces this is quite feasible. If you have a lot of customization for each project, this might make sense.
Same project, more targets. This is the usual way this is done. It is very easy because you have a very neat overview of what files go into which target. If you have around, say, a dozen or so targets, it is really quite easy to handle.
Separate git branches. I have worked with this in the past. The differences between the apps (Info.plist, configuration files, data files) are just swapped in the corresponding git branch. This is practical if you have a lot of data and don't need to have all of it available at all times. However, the complexity of git is considerable if you are not familiar with it. You can create git submodules to change the shared code parts in one go.
I would suggest you a hybrid approach depends on your needs
If you need several applications - create Target, that is exactly what they are for. You can handle sharing files using Target Membership[About]
If you have source code which can be separated into module - create additional Project (for shared source) inside Workspace. This technic is used by CocoaPods
[Xcode Workspace vs Project]
[Xcode components]