S
S
Semyon Semyonov2016-02-19 06:50:52
Android
Semyon Semyonov, 2016-02-19 06:50:52

How to support two versions of the application (paid and free)?

I am making an application and I want to expose two versions: paid and free. But how to support them? Those. repositories to do two or one? If there is one, then you will have to do some inserts, such as if it's free, then we show this thing, but if it's paid, then no. If there are two, then it turns out that you will have to copy pieces of code from one to another.
How are you doing?

Answer the question

In order to leave comments, you need to log in

9 answer(s)
I
Igor Makarov, 2016-02-19
@onqu

Of course, you can use 2 branches, of course, you can do everything in one branch and poke everywhere #ifdef FOR_NISCHEBROD, FOR_REGULAR_CLIENT, FOR_RICH_ONE, of course, you can add tags to make it easier to look for these places in the future.
But, with an increase in the volume of logic, one will have to resort to the use of a shaman's tambourine, the ritual of shooting oneself in the foot and prayers to the forefathers. It will be very difficult to add/edit logic in these pieces.
Another variant.
Make the application modular, where the main application is just a framework with basic functionality, lies in a separate turnip, is tested separately from everything, and where modules are plug-ins (Components, DLC, LIB, Whatever) that have an API interface to extend the functionality of the main application , and each lies in his turnip.
Moreover, they can be tested both together and separately from the main application. When assembling, we specify only the required extensions. Next level - connect extensions dynamically, that is, without assembly with the application.

T
Tiberal, 2016-02-19
@Tiberal

One branch, but different product flavors in the build. You change some pieces of code for different flavors. So you can support both the demo and the paid version in one project
developer.android.com/intl/ru/tools/building/confi...
everything is described here

S
Sergey, 2016-02-19
@begemot_sun

You can use 2 branches in the repository:
master, master2.
But.
I would do everything in one branch, just using the compilation options, I would cut off the necessary functionality during the compilation process.
Ie you need a paid version - set the option - got a paid one.
Need a free one - set an option - got a free one.
Accordingly, you will have to test 2 versions at the same time.

O
one pavel, 2016-02-19
@onepavel

You have one code branch in the repository, one project.
With the help of Gradle and productFlavors, you separate the paid
functionality from the common code.
Split example
https://github.com/bmuschko/gradle-android-example...
www.vogella.com/tutorials/AndroidBuild/article.html
www.sajmons.com/news/gradlebuildwithfreeandpaidflavors

X
xmoonlight, 2016-02-19
@xmoonlight

It is enough to use one repository with connection of different libraries/modules (with remote/separated functionality) to the core (main logic) when compiling versions.

I
Igor Kalashnikov, 2016-02-20
@zo0m

You were offered a lot of good options above, personally I would still use the banal IF
, this is the "cheapest" and easiest option, and you don't have to be afraid that you will have an increase in the number of cases that you will solve in the same way, because the number of application options is unlikely will grow strongly.
My experience is this: I write cross-platform applications, and in my code I periodically need to pull different native APIs, so I have to insert if OS_ANDROID, if OS_IOS, etc. I don't experience any problems or inconvenience. And there is nothing good in overengineering.
In addition, I will add one more option (it is from the category of being too smart):
ACL
i.e. instead of IF in the code
, you will have one method, at the beginning of some "limited" call:

openView = function(viewName, params) {
    try {
      acl.checkAccess(user/system/status/type_of_app) // бросает эксепшен, поэтому можно удобно втыкать где угодно

      rootView = new View()
      if acl.hasAccess("pay_app")
          rootView.add(new Button("HD Quality"))
      ....
    } catch (ACLException e) {
           if (e.code = ACL_PAYMENT_CODE) {
                  showUserMessage("Это премиум контент, вам необходимо купить ... ")
           } else {
                  ...
           }
    }
}

further options to your taste,
for example, if authorization failed, then the method will throw an exception
or javascript style, wrap it in a promise, or an anonymous function
, and for example, depending on these checks, an interface will be drawn, functions will be launched, lisners are the
only thing to manage this business at least "on the fly" or "from the admin panel", it will be necessary to organize a "security matrix", roughly speaking of this type:
_____________________ | BUTTON_1 | VIEW_1 | VIEW_LOADING |
user_1(admin)............| default | enable | default
user_2...........................| hidden | default | default
pay_app......................| default | enable | default
free_app...................... | default | disable | default
status_loading.......... | default | default | show
In my opinion, this is not the best option, this is implemented for projects with a large number of entities. But it might give you some interesting ideas.

S
Stanislav H, 2016-02-26
@shomishinec

It seems to be called Build Variants , isn't it?

S
Sergey Eremin, 2016-03-01
@Sergei_Erjemin

Usually, paid from free differs in separate functions (just those that are paid). So, you simply make each function a separate file (library, module, etc., depending on what your application is made of). Next, a batch file is made that collects (compiles) all this into a single or paid one, or vice versa. Of course, in all places of the basic functionality where the paid functionality can be called, you need to check for their presence, and if they are not there, call to switch to the paid version.

B
Boris K., 2016-03-08
@kaftanati

If the Pro functionality can be unlocked with the same InApp, then both versions should definitely have a code for both Lite and Pro. Therefore, disabling Pro functionality by a key available after unlocking is the easiest option. As a stub for a Lite user, it makes sense to show a separate screen with a list of all blocked features, explanations of "what you also want to eat", etc. with a big "Unblock" button.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question