Best way to Whitelabel an existing iOS App - ios

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.

Related

Having one template app and making multiple different apps from it

I am trying to figure out what would be a good way of setting up application architecture and how to setup Xcode project itself, in the case where I have one base application, and I need to make multiple applications of it where the all apps will have those same base functionalities but will differ in a way that:
Assets may be different
Some features can be added ( new screens that uses new endpoints that are not defined in base app)
Localization can be differ (eg. one app can only be translated to english, and other can support multilanguages)
and probably some more, but you get an idea of what kind of an app (kinda template app) I am referring to.
What would be a preferred way to implement something like this? I guess targets and making a framework for a shared code is one way to go? Or there is something else that would be suitable too?
Target is a good start. Thanks to target memberships, you can "share" storyboards, source files and whatever you want between several targets. Then within each specific target, you add your assets and specific functionalities.
Frameworks can be also a good way to share functionalities between apps. But you can start and try simply with targets, and then later factorize code within frameworks.
The way I would do it could be this way :
Create your project with a single target, let's call it "Blank App"
Develop functionalities and prepare generic assets for this app
When you want to add a new App, duplicate the "Blank App" target, remove membership of default assets, add new ones, add also specific source and resource files, and that's it.
After a few targets, you can spot what can be factorized within frameworks. Add a new framework target, migrate your sources in it, make all apps use this framework, and you'll have a nice system.

What's the difference between Build Configurations and Targets?

We have five practically identical apps, with a few different icons/names/settings. They are different "brands" of the same app, only differentiated in a few different icons, separate AppGroups, and a few default settings in code. These are created as their own targets in Xcode. It's one codebase, but 5 targets pointing to it.
It started out looking really nice, with five different targets. However, we have now added two extensions to the app. One custom "NotificationContentExtension", and one "TodayExtension"(Widget). Since we have 5 different targets with 5 different entitlements/groups, we found no other way to achieve this than to add these extensions to EACH target. Since an extension is another target, that means we now have 15 different targets.
We're now experiencing extremely slow compile-times, because every time we as much as open the storyboard, Xcode compiles the entire thing once for EVERY (main)target. I don't need to build my storyboard 5 times. Or any of my other files. I have ONE app, but a few different files, and a few runtime-settings.
This made me wonder - each and every one of these 15 targets have two build configurations by default: RELEASE and DEBUG. I noticed it's possible to customise these, and add more. Why not add configurations instead of targets?
E.g instead of "RELEASE" and "DEBUG", make them "MYAPP1", "MYAPP2", "MYAPP3" etc. Each configuration can have their own product name, icons, and whatever, right?
Are there any good reasons not to do this? Is it possible, when dealing with different AppGroups/Entitlements etc.? We have CoreData-databases stored in AppGroups. It is important that these apps can all be installed on the same device without being corrupted by each other.
As far as I can think, this shouldn't be a problem as long as there are a few different FLAG's for each configuration, and customising the code as such.
What about signing?
I read this article/tutorial on the subject, which explained the basics and got me started, but it will be a huge amount of work to actually test it with databases and entitlements and all.
Answering a few years later: The answer was yes btw. Using BuildConfigurations is safe and works perfectly fine. It also removed all the unnecessary build times. We converted the project setup and ended up with three targets (app, widget1, widget2), and multiple BuildConfigurations.
To customize build configs, click on your project in the Project Navigator, then click on the blue "MyApp" (under PROJECT, not under TARGETS), then select "Info" in the top bar. You'll see a list of your configurations. They'll be "DEBUG" and "RELEASE" by default. You can add/remove/customize here. Make it "MyApp1", "MyApp2" and "MyApp3". Then click on your "MyApp" under "Targets", go to "Build Settings", and search for e.g "Product Name". If you hover over it, an arrow will appear next to "Product Name", click it to expand it, then you'll see you can change the value individually for your different configurations, so "MyApp3" can be named "MyApp3" without affecting the others.
This can be done for all Build Settings.
If you have several "flavors", and potentially have to add more later, I recommend NOT changing the individual values directly in "Build Settings", as they're harder to find and easier to forget. You should rather make each relevant value (such as ProductName) inherit from an external key, and create your own .xcconfig-files for each "flavor", which contains all the individual values for these keys. That way, if you need to add another flavor, you can simply add another .xcconfig-file which has all the relevant changes, and you don't have to look through all values in BuildSettings and potentially forget some of them.
When you've done this, to be able to actually build/run each configuration, you'd have to add a scheme to each config.
The only negative side effect I've noticed from this approach is that the app's icon in the scheme-dropdown-list is wrong. They'll all be the same, even if the "App Icon Set Name" is different. The app's icon will be correct when run/installed, but it will display wrong in Xcode's built-in drop-down-list.
Be careful though, you should know what you're doing when changing the build-settings. By default, when you run an app, the DEBUG-config runs, and RELEASE is used for when you "Archive" (when you release). If you don't respect the differences between these two, and just create ONE build config for each of your apps/flavors, you'll either get longer build-times when developing, or poorer performance after release. This is depending on build settings like "Optimization Level" etc. So to be safe you should create "MyApp1DEBUG" and "MyApp1Release" for every app, which are clones of the original "DEBUG" and "RELEASE" respectively.

Is there is any way to create a IOS app as build for another app?

I have an IOS app which holds lot of Configuration settings to use the app and also this app is used in 5 warehouses, settings will be differ from one warehouse to another warehouse. So it becomes more painful for the users using this app.. Even ever they install the app then need to set the configuration settings.
So my problem is If i hardcode the settings value, it is very difficult to maintain the code for all the different warehouse. if i do small change in my app have to change in all of the 5 source code.. Even if i decide to maintain 1 code .. i have to change the setting value every time before setting the build.. It is more painful for me.
so my question is..
Is there any way to run a app and set values in configuration settings. And generate this setting app as a build ?? i don't know it will workout or not please share me some ideas..
If I understand correctly, you want to have 1 source code and there is possibility to create different Targets. Each target can have it's own configuration plist file and you can set also different preprocessor macros for each target.
How to use preprocesor macros you can see here: How can I differentiate between multiple targets in xcode at runtime
How to create targets you can see here: Add preprocessor macro to a target in xcode 6
One more possibility (besides targets) is to create a shared library and if you want to apply some configs after installation you can prompt user to download one from a server (for instance)
Yes, you can create different schemas.
For example, you can create an application for Development, Staging, Production.
You can have configurations in plist file and make it variable according to the schemas.
When your application opens it will take the values according to the schema with which it was built.
Follow this guide to create different schemas.
Also, you can integrate Fastlane to generate builds easily with different schemas with simple commands.
Yes you can have one app with different targets and schema. Then just google it there's many articles about.

Build variants (different files for different brands) in Xcode / iOS

Android has very good tools for creating different variants of an app (for example, the exact same code but with a different logo). You just create a different flavour and put a different image for each flavour's directory. How do I achieve this in Xcode? The information I have found on the web is very bad. I tried creating a new target for my project but that created a new storyboard, AppDelegate etc. It just created a new app altogether. I want different resource folders for different brands of the app. I'm using Swift.
You're not likely to get the same kind of setup you could have with Android. There are a bunch of features you could use individually or in combination. rmaddy's comments are good. Another option is creating additional schemes and setting the properties of the project for each one. The important thing to keep in mind is that the simplest solution may not look the way you're expecting.

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.

Resources