Two projects with same code base - ios

Is it possible to have two projects in XCode using the same codebase?
I have an app which offers a demo version and a full version. They both share the same code and I just set a flag in my plist file, and somewhere in my code I do
if (demo_mode) {
// ...
} else {
// ...
}
This is easy for testing, but not suitable for the app store, since I want slightly different app icons and app names for them.
I could as well make a copy of the project, but then I'd have to apply changes in one project to the other (bugfixes, UI changes etc). That's why I want to use the same source folder for two projects.

All you need is one project with two target.
You can make different config or file with different target, also share the same code, but submit to App Store separately.
Let me know if you need more help.

You are probably going to use StoreKit to provide a non-consumable purchase for users to upgrade, and use this as your flag. StoreKit usually involves a good deal of boilerplate, so you might consider implementing something like MKStoreKit to handle some of that for you. You can use MKStoreKit to easily check if the user has purchased the upgrade or not. Restoring purchases is also relatively easy.

Related

Best way to Whitelabel an existing iOS App

I started working at a company which developed an App for mobile payment. There is a "Terminal"-App, which receives payments of customers and then there's the "Wallet"-App, which users can download and use to pay (at those terminals).
The project consists out of 2 targets - one for the Wallet and one for the Terminal. The App is used only in 2 Countries. It's all quite sophisticated and has a huge code base.
Now I need to whitelabel the whole product for a client, who wants to use our App (both targets) with his own branding (and maybe some additional features or without some specific features) and I'm not sure what the best way would be to achieve that.
Currently I see 3 options:
Duplicate whole project
To copy the whole project to a new folder and make my changes in that new folder would probably be the most "dirty" approach. At some point, my first code base could differ from the duplicated one too much. Additionally, if any security-related issues would come up, I would have to fix it in both projects.
Create another 2 targets
I was actually thinking that this would be the best way to go. Creating a new target for the Wallet and the Terminal and then checking the current target in the source code to decide which features should be enabled or disabled sounded pretty good to me at the beginning. But then I created the new target and noticed that I will have to set that checkmark on EVERY single class for that new target. Besides that, I'm not sure any more if that's really the best way to go.
Use If-conditions
The third option would be to wrap every function, that will be available in only one of the apps, with an if loop. I see this as the "cheapest" option because it's easy to set up and I can still maintain my code base pretty well.
Is there any other option I have? Which way would yo go?
The most significant difference between the base App and the whitelabeled one will be its language. The whitelabeled version will be right to left, but iOS does a pretty good job on that without needing me to do all the mirroring.
You definitely want the extra targets. Having a new target means it's easy to use a separate bundle identifier, signing settings and more. It might seem like a pain to have to tick a bunch of boxes to add your files to the new target (perhaps quicker to use the target's Build Phase|Compile Sources list in Xcode) but it's worth it to create a real separation between the apps.
Instead of using a bunch of source code checks to determine which white label app you're in, consider making your app more data-driven. A plist file could be used to determine which capabilities your app has, and a different plist file can be used for each target.
For example, it might contain a top-level dictionary called features, with true/false values for a bunch of feature names. You have a FeatureManager that reads the file and is the single source of truth for all app components that want to know if something should be available or not.

How to reuse an Xcode project into a new project? Static library, Framework, Targets?

I built an iOS project (actually workspace because of Pods) that is 100% functional, with its logic and UI (Storyboard and xibs). Now I would like to reuse this app/project as a "core" for future apps.
I've been searching about it and there are several solutions like Static libraries, Frameworks and Targets. But I am not sure which one would be the best in my case. I would like to reuse all the UI part as well.
I saw that most of the people agree that the best approach for reusing code is static libraries, even thought it looks not so straight forward. But I think for reusing UI probably Targets is the best solution. The problem I see is that if a build 10 apps based on my core project, the new project will be huge, so probably it is not the best option.
I don't know if you guys have any better idea or opinion.
Thanks in advance!!
There are several things you can do, and I will try to go through them.
If you have minor changes on your "base" app, then the best thing would be using targets(build schemes). This way you can add things to build phases and therefore, add files that you need. This might be the quickest possible way to do what you want but here are some drawbacks: What if you have 5 apps, and for each one you have QA and prod. That 10 build phases. If you keep using your app in no time you will find hard to manage it.
Another thing could be to create different project, and include all the files you have (and you need), inherit from there and have extended functionality/UI/UX. This is slower approach then number 1, but you will have dependency on the files that you might change in one app and don't want to propagate that change in other apps. So the drawback would be that you have to be extra careful, and plan a lot of things in advance.
Third thing could be to create base app group(or project) and then you are certain what to do, where and what that change could do to other apps(since you know that this file is actually being reused).
And finally, there is a framework, which is my favorite. I am working on one project that inherits base app and we found that is a huge problem. You start separated and then, one thing by one, you have entangled code for specific app and base app like headphones in pocket. And if you don't refactor it ASAP, it will became really hard to resolve these kind of issue. Not to mention merging and other stuff. Here is an excellent article about creating framework http://www.raywenderlich.com/65964/create-a-framework-for-ios . Off course, there is a price to pay and that's every change that you create you must update library and add it again to project. This thing can be easily forgotten and if you are working in team could produce build crash.
All after all, you predicate that you will have more then 5 apps, so I would say go with the framework. This way you will have much cleaner and separated app, and won't have to think about changing things and how these changes would affect your other apps.
I recommend you use a custom project template. I did it perfectly today. I had the same needs as your. Follow this link: https://github.com/reidmain/Xcode-6-Project-Templates/tree/master/iOS%20Application.xctemplate
Download it. You can add all the files from existing project into this template, storyboards too. If you have any doubts I will help you.

how to manage 2 version of a single app for different regions and languages?

I am deploying an iOS application in both US and China. App behaves pretty much the same but has slightly different logic. For example: we use email to register account but use phone number in China. Other than this obviously the languages used in app are different.
We are going to submit two different apps to US and China app store but we have this problem: two versions share considerable amount of code base(95%). That being said if in the future we ever need to add future to the app we have to manually migrate changes since we won't be able to use git(I assume so because they are different projects right?). This is surely not desirable. But by now I see no way to go around it.
Can any one offer any suggestions about approaching such issue? Maybe there is a git trick? Or we should not use two different projects in the first place? If not, what's the better way?
Thanks in advance.
Per our discussion, it is suggested to use Targets in the same project, the code is reused and can be checked in to one repo. Following is what I would do to maintain multiple Targets within the same project.
In Target US Build Settings, Preprocessor Macros, add following:
TARGET='TARGET_US'
In Target China Build Settings, Preprocessor Macros, add following:
TARGET='TARGET_CN'
Then in code, use preprocessors to check:
#define STRINGIZE(str) #str
#define STRINGIZE_MACRO(str) STRINGIZE(str)
#ifdef TARGET
if (STRINGIZE_MACRO(TARGET)=="TARGET_US") {
// US app logic goes here
} else if (STRINGIZE_MACRO(TARGET)=="TARGET_CN") {
// China app logic goes here
}
#endif
Also just want to point out that there is a way of associating Compiled source files with Targets, it is found in Build Phases. You can make a selection of code files that is needed to compile. E.g for Target US, Add main-us.m and USAppDelegate.m for compilation, for Target China use main-china.m and ChinaAppDelegate.m.

What is the best method to build a free and paid app in the same project?

I am finishing up my first application and researched some methods to make use of two targets in the same project. There are few functions that will reduce the free version and will add adbmob banner.
The various tutorials that follow, the one who worked to differentiate the targets was this:
How to get Target name?
I researched other ways to accomplish this task are old threads and could not make it work.
I tried to add in FREE_VERSION Precompiler macros and many errors occurred. I also tried to add FREE_VERSION in Other C flags within LLVM 5.1 - Custom Compiler flags.
I'm not sure if these methods still work, or if there are better. Does anyone have a more current way to accomplish this or can I use the method I quoted at the beginning of the topic?
You can use a Preprocessor macro to mask off code that should run only in one version or the other, and you can use User-Defined Build Settings to differentiate important fields in your app's property list. Just make sure you produce archives for each version while in the correct build scheme when you're submitting.
However, Apple is becoming less friendly to "upselling", so if your free version asks the user to consider downloading the paid version, it will likely be rejected (they will cite guideline 2.9). To avoid that, you can either make a single version which is free and upgrades with an In-App Purchase, or you can be careful to make sure that the free version doesn't push the user toward the paid version.

Reuse Xcode project for new app

Similar questions have been asked before, but I can't find the specific details I'm looking for. I have an Xcode project which has been completed and submitted and is on the App Store. I want to make a similar app for release in a different country. To avoid complications, I want to use a fresh project in which to make the changes. I intend to make a copy of the original project, tweak it, and then release it (this is not about language so localization is not the answer).
Because Xcode is doing so much complicated stuff under the hood, and because I'm unsure of exactly which details are being validated when submitting to the App Store, I don't know which details I need to change to ensure two separate projects on my Mac and two separate apps in iTunes Connect.
Obviously I will need new provisioning profiles for the new project. What else do I need to change once I've duplicated my project? The bundle identifier maybe? Anything else? Any advice much appreciated.
The thing that must change between projects is the application ID (or bundle identifier, as you called it).
And yes, when you change the application ID, you do need to create new provisioning profiles to go with it.
If you're feeling really ambitious, you can use the exact same project as your original one and merely create a new target (and application). That way any code changes you make to one can be picked up by the other and the differences would be the ID and maybe the localizations/resources used in each app. Here is a related question that talks about that.

Resources