1.0 What is modularity

In many presentations of refactoring and design patterns, the terms reuse and decoupling are often used.

Modularization is proposed, but also more to solve these problems.

Reuse reduces the amount of reinventing wheels, and it’s easy to see how the github third-party frameworks we use a lot, such as AFNetworking, don’t need to write again.

Decoupling reduces the association between classes or files. If a class references 10 other classes, then when we look at that class or modify that class, we also need to look at the other 10 classes to see how they are related to that class. If your class is not associated with any other class, you can read the code, forget about the other code, and just look at this file.

We can see that low-coupling systems can combine numerous simple modules into complex projects. Reuse obviously improves work efficiency and liberates productivity.

This way, your system is simple and clear, and you don’t have to worry about refactoring or modifying it.

The way to achieve low coupling and reuse is often called modularity.

In practical development, modules are often defined as units of code that can independently implement a single task.

From a code point of view, a function, a file, a class, or even a function, can be a module.

In addition to the above advantages, after modularization, each module can be developed separately, separately tested, but also easier to do internal code permission management.

As mentioned above, the whole system is made up of different modules. The difficulty then lies in how to define the boundaries of modules.

2.0 module division and communication

In the actual development of the client, according to the use of modules, can be roughly divided into two types.

The first provides very basic functionality that is frequently referenced by other modules, which can be called directly from those modules’ apis. For example: network modules, common utility classes, layouts, images, and other dependent third party frameworks.

The second, which provides valuable product functionality, is more of a presentation interface to the page, which is never directly referenced by other modules and communicates more asynchronously (using routing). For example: membership module, payment module, short video module and so on.

In addition to these two modules, there is a module that is both frequently referenced by other modules and provides a presentation interface to the page. For example: login, collection, attention and other functions. Such modules need to provide data and modification interfaces to other modules, and sometimes need to present the UI.

In fact, the third module can be divided into two modules according to the data and presentation: one module is used to provide data to the outside, which can be directly referenced by other modules; Another module is used to display pages asynchronously.

3.0 iOS modularization practices

3.1 Modular workflow

Modularity in iOS, different modules are introduced into the main project by way of dynamic/static libraries.

The difference between a dynamic library and a static library is needless to say, you can choose according to your needs.

Cocoapods is an excellent module management tool.

When we use Cocoapods to manage different modules, the code can exist in three forms: source code, static libraries, and dynamic libraries.

So before modularization, we need to carry out the following work in advance:

  • Install cocoapods
  • Create a pod private library to store podSpec files for all our modules

Our workflow for creating a new module should look like this:

  • Create a new project and modify the necessary Settings
  • Create the Podfile, add the dependency, and then run Pod Install to install the dependency
  • To start development, you may need to set up a Demo project or Demo target to test your static library APIS during development
  • Writing unit tests
  • Once the test passes, you need to commit the code to Git and tag it
  • Write podSpec files
  • Check the podSpec file for correctness
  • Use the POD repo push command to push the PodSpec file to the POD private library
  • If other modules want to reference this module, install the dependencies as standard POD usage

3.2 Possible problems

Problems that may be encountered in the above process include:

  1. How to write a podSpec file?
  2. How do I submit and update podSpec files?
  3. How do I write my Podfile?
  4. What if the module I developed depends on other modules we developed before? What if my dependent modules also need to be modified?
  5. What about circular dependencies? A depends on B, and B depends on A.
  6. How to handle resource files such as images
  7. How to mix OC and SWIFT
  8. How to compile the framework, how to lose weight, how to merge

4.0 Process Automation

As you can see, there are many processes involved in creating modularity, including Cocoapods, Xcode Settings, resource management, Swift&OC build management, static library access, and so on.

Many of the technical content is not commonly used, in the development process, we encountered problems, immediately refer to the document to solve, after a period of time, encounter the same problem may need to refer to again.

Moreover, different people may encounter the same problem in the process of practice, and everyone needs to solve it once.

The process is too much, but also easy to produce errors because of misoperation, this kind of problem is difficult to solve, often encountered will take a lot of time to deal with.

Looking back at the workflow, much of the work is fixed and the same process is repeated every time a new module is created, so this part of the process can be automated through automated scripts.

What can we do with scripts?

  1. createModule projectandDemoEngineering, automatic setting insideBuild SettingOption, and manage it using.xcWorkspace
  2. Some content is automatically created based on user inputpodspecFile and check its correctness
  3. According to the user input dependency module, automatically create different projectsPodfileFile and usepod installInstall dependencies
  4. Management module directory structure, script can be convenient to add, delete, change and check the module
  5. If a module depends on other modules developed by us, then the dependent module will be used aslocal pathIn this way, we can directly modify the dependent module code and test in the current module project, without opening multiple projects. Once the development is complete, submit them separately.
  6. Automatically install the software and environment on which the script depends
  7. Record modules that have been pushed to a private library to facilitate the development of multi-dependency modules
  8. After the development is completed, the script is pushed to the POD library with one click
  9. Secondary development of modules already in the POD library allows you to pull the project and install all dependencies with one click

After completing the above functions, we can find:

  1. For a brand new module, you can use a script, create a project with one click, and then do business development. After development, you only need to execute one more script and push it to a private library without knowing any details about Cocoapods and Xcode Settings.
  2. For secondary development modules, we also apply scripting, one-click pull engineering and all dependencies, just focusing on business development. After the development is completed, the script is also pushed to the private library with one click.

– the –

  1. IOS application modularization thinking and landing scheme (A) module division and modular workflow
  2. IOS application modularization thinking and landing scheme (2) the use of modular automatic construction tools