Modularize Domain-Specific Module (Part 1)

In this whole Modularize Domain-Specific Module series, we will look at different ways to Modularize your module According to your needs

Domain-Specific Module

Domain modules contain features specific to an area of the product. The sum of all those parts makes up the application. In your application, there can be a Home screen, Checkout, and many types of screen. Putting these modules in a separate private pod is not a good idea since it has business logic. Putting in the separate repo will also increase development time as well. In the previous blog we made a private pod for Networking and Extension because they contain the generic logic and can be used by multiple projects in the organization.

Note:

Every isolated module feature will have its own Dependency Injection Container to have one entry point where we can see all dependencies and injections of the module.

Every isolated module should have an example app as well to get faster build time , testing unit test and development time to debug and test

In the domain-specific module, there can be lots of interaction between module so be care

Getting Started

Step 1 Consumer app (Main App)

Create a Single View Application and create workspace by running pod innit and pod install. Follow the previous part if you don’t know

Step 2 create an actual framework

As shown in Gif 1 we first we created a folder DomainPods into the filesystem

As shown in Gif 2 we did a few things

  1. Open terminal ad land into the DomainPods folder
  2. Run pod lib create Home it will download the template to create a library
  3. When creating a library it asks a few questions platform, language, demo application, testing framework
Input asks : 
What platform do you want to use?? [ iOS / macOS ]
> iOSWhat language do you want to use?? [ Swift / ObjC ]> SwiftWould you like to include a demo application with your library? [ Yes / No ]> YesWhich testing frameworks will you use? [ Quick / None ]> NoneWould you like to do view based testing? [ Yes / No ]> NoRunning pod install on your new library.

Now directory structure would like something as shown in Figure 3

This step is very important as shown in Figure 4, to select these files and move to Bin. Following are the important files and folder need to delete

  1. Pod folder and files are important to delete since we will add all pod to our main app and this Home module we will add as embedded
  2. git folder since our main app will do this module versioning thing, this is very important and if you didn’t delete this our main app git will ignore this module changes

As shown in Figure 5, we first deleted the Assets and Classes folder and created Module folder, here we will put this module coding files and also we simplify .podspec file and updated the source_files to point to Module folder and expect only swift code. Please refer to the previous blog if you don’t know .podspec file

Open Home.xcworkspace

Update swift version to 5

Change the minimum iOS version to 11.0, These 3 steps are optional According to your requirements

Delete these files

As shown in Figure 10 and 11 we did a few things

  1. add pod ‘Home’, :path => ‘DomainPods/Home’ to our main App podfile
  2. Run pod install
  3. Open the Main app and run the application
  4. :path => ‘DomainPods/Home’ will create a Development Pods folder and installed pod on it
  5. Its references to Home (0.1.0), Remember we added line s.version = ‘0.1.0’ in .podspec file

Open Home.xcodeproj as shown in Figure 12 and copy Home_Example target name, I the next step we will be embedded Home_Example our demo app in main workspace

As shown in Figure 13 we did a few things

  1. first, we embedded a demo app target using the script in podfile and tell it’s a dependency and project reference
  2. pod install
  3. As shown in Figure 13 Demo app is embedded in the main workspace

As shown in Figure 14 we run our demo app as well, by selecting our target at the top, this is very helpful when you want to run your module independently. And we get an error on Appdelegate. Remember we change the swift version to 5 on our Example app

Again when you run the application you get error on Test remove import home and run the application

As shown in Figure 16 we run our demo application successfully

As shown in Figure 17 we run our main app application successfully

Use Home Module

Step 1 : Drag and Drop Domain Pods into Main target

Step 2: Make sure it is added as Create folder references

Create New file on Development Pods

As shown in Figure 21 we created Entry.swift file with some code

We updated podspec s.source to use local path

As shown in Figure 23, we used Home module successfully in our main app

As shown in Figure 23, we used Home module successfully in our Demo app

Running Home Module Unit Test

Step 1 : Create Tests folder with the same level as Module

Drag ad Drop Tests.swift into new folder (Tests) we created

Delete this file from Example Home app

Updated podspec and podfile , run pod install on Main and demo app

As shown in Figure 30 and 31 we run the unit tests

Put Main Repo on Git

Open Source Tree → New → Add Existing Local Repo → Commit

If we need to Add New file to our Home pod, For this strategy to create domain module, is annoying, if anyone has another alternative let me know, we will see in new part this will fix but for this strategy, it is the problem, change in the file is not a problem

Step 1: On the development Pod, Create New file as shown in Figure 33 and Figure 34

Drag and drop file to DomainPods the blue color folder which represents file system data

As shown in below we used this new file , if not work run pod install

Add Unit test and if not added, you can see I Figure 38 our new file test succeeded

Real Benefit

As shown in Figure 39,

  1. our main app git is capturing our pod changes, this is the purpose of the domain module that it is embedded in our application and the main application handling its changes
  2. Another benefit is that the reviewer can easily identify the Home domain module is effected.
  3. we can automate this script that If let’s say Person A is the owner of Home module until it approved their file changes PR can’t merge

Dependency between Modules

Let’s create another Module with all the steps we follow to create Home, Call it as Offer Module

Go to Domain Folder → pod lib create Offer → Open Offer.xcworkspace → Deployment Info 11.0 → Change Swift version to 5 → Update App delegate file Build Offer.xcworkspace

Build Succeeded, Now close the Offer.xcworkspace project

Move to Bin these files and folder

Create a Module and Tests folder

Update podspec file , make sure to save file as well

The close Main app, Update podfile, Run pod install ,

As show dependency installed, Now open MainApp.xcworkspace

Created OfferEntry.swift file and drag into the blue folder under Module

Delete these file, for cleanup only

If you get any error like that

New File → unit test file → OfferEntryTests.swift

Drag ad drop file to blue Domain folder

Now run pod install on Main app ,

As shown in Figure 52, we used Offer module on Main app

The question is How can we use Offer module in Home app

As shown in Figure 53 we added Offer dependency on Home podspec file . One thing to note Offer pod will install by Main App.

Finally, you can see we used Offer pod in Home pod

Upcoming

In the next part, we will look at another technique, to Modularize Domain-specific module using multiple projects within one workspace

Useful Links

https://tech.olx.com/modular-architecture-in-ios-c1a1e3bff8e9