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
- Open terminal ad land into the DomainPods folder
- Run
pod lib create Home
it will download the template to create a library - 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
- 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
- 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
- add
pod ‘Home’, :path => ‘DomainPods/Home’
to our main Apppodfile
- Run
pod install
- Open the Main app and run the application
:path => ‘DomainPods/Home’
will create aDevelopment Pods
folder and installed pod on it- 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
- first, we embedded a demo app target using the script in
podfile
and tell it’s a dependency and project reference pod install
- 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,
- 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
- Another benefit is that the reviewer can easily identify the Home domain module is effected.
- 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