Sagar D
Sagar D

Reputation: 2618

iOS App modularization at build time

I have my app's home screen as the following prototype : enter image description here Considering this home screen, I have to develop the app in such a way that every feature among these four should be pluggable at build time. For example,

If I set a macro like

#define FEATURE_1  0

then, the home screen will have only 3 tiles for the remaining three features. Also, the files that are related to feature-1 should not get compiled in the resulting .ipa .

When i was developing these four modules, I have kept all the classes independent of each other. But the problem is I have a single storyboard which contains the whole UI. Now, I have to separate the UI and resources in such a way that if any of features is turned off, no files related to that feature should get compiled.

What i have tried : I read somewhere that making each feature as a static library would get my job done, however, I couldn't figure out how would I include/exclude a static library at build time. Also, it doesn't solve my problem of separating the views in the storyboard.

Specifically, the questions I have are :

1) How can I copy specific files to my project and leave out specific files depending upon the macro as a defined above? If it is possible, please direct me towards a good way of doing it.

2) How can I separate out the views on storyboard? May be define multiple storyboards and include the required ones at build time? Please guide.

Upvotes: 5

Views: 423

Answers (4)

Sagar D
Sagar D

Reputation: 2618

What I ended up doing :

Consider I have two features: 1 and 2.

So my requirements would be making three kinds of builds:

  1. A build with only feature 1.
  2. A build with only feature 2.
  3. A build which has both features 1 & 2.

So, I divided the project files in Xcode groups as:

  1. CommonModule – This group consists of files that are needed by both the features.
  2. ModuleOne : This group consists of files that are needed by feature one.
  3. ModuleTwo : This group consists of files that are needed by feature two.

The folder structure I followed for each module is:

my folder structure

It is better to keep the folder structure of the project on disk similar to the group structure of that project. It reduces confusion and adding all files in a particular folder to a particular group becomes possible.

Now I defined three targets corresponding to the three types of builds I listed above.

  1. TargetOne : Files in CommonModule and ModuleOne groups belong to this target.
  2. TargetTwo : Files in CommonModule and ModuleTwo groups belong to this target.
  3. TargetAll : Files in CommonModule, ModuleOne and ModuleTwo groups belong to this target.

Now in CommonModule, I have a BuildConfig.h file which has macros like:

#define IncludeModuleOne  1
#define IncludeModuleTwo  1

So while building, select the appropriate target and toggle the above switches appropriately to get the correct build.

Now in the InitialViewController.m, I checked for the switch values, and depending on the values, I displayed / hid the menu options for that particular feature.

In this way, to sum up, I include only the require files in the build with the use of multiple targets + configuration macros together

I will soon share a link to my Sample Project on GitHub. I hope it will help someone who has similar requirements. Thanks !

Upvotes: 1

eik
eik

Reputation: 4600

Although you could use the build system, in your case it seems easier to you wrap the affected code in

#if FEATURE_1
...
#endif

For hiding the views you could use code in line of

#if !FEATURE_1
    feature1View.hidden = YES;
#endif

depending what exactly you are trying to achieve.

Upvotes: 2

Moose
Moose

Reputation: 2737

Answer for 1 : You can't using only macros.

Create several targets for your different configurations, defines the macros you need on each target and toggle the file include checkbox to only include the needed files during the build.

Upvotes: 4

S.Jain
S.Jain

Reputation: 441

Answer for 2 . Use Either UICollectionView, or use 4 views in your XIB and use this method

-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self){
//        NSArray *nibArray = [[NSBundle mainBundle] loadNibNamed:@"--name of xibs--" owner:nil options:nil];
//        self = [nibArray objectAtIndex:0];
    }
    return self;
}

in nibArray, the views will be stored

Upvotes: 1

Related Questions