Series of articles:OC Basic principle series.OC Basic knowledge series.Swift bottom exploration series.IOS Advanced advanced series
preface
Originally wanted to write to continue to write interface optimization, but because the previous period of time the project is more busy, has not done! In addition, the recent project is also sorting out the componentization things, so I decided to write an article about componentization.
componentization
When we talk about componentization, the first thing that comes to mind is decoupling and modularization. In fact, componentalization is a way to decouple the modularization from the layer and develop the communication mode between modules, which is mainly used in team development
A little bit of componentization
Componentization has two main advantages
- 1.
Decoupling between modules
- 2.
Module reuse
- 3.
Improve team collaboration and development efficiency
- 4.
Facilitate unit testing
When the project is getting bigger and bigger due to various requirements, if the various modules are calling each other, that is, there is a me in each other, there is a you in each other, this situation will result in high coupling. Once we need to modify a piece of code, it will cause problems with a wide range of influences and multiple functions, which makes it difficult to maintain the project. The problems are mainly reflected in the following aspects
- 1. When modifying a function, you need to modify the code of other modules because the module is referenced in other modules. Can be understood as
High coupling makes code modification difficult
- 2. The external interface of the module is not clear, and even exposes the private interface that should not be exposed, which takes time and effort to modify. Can be understood as
Interface confusion caused by unfixed interfaces
- 3. The consequence of highly coupled code is that it affects the development of the rest of the team,
Create code conflicts
- 4. When modules need to be reused to other projects,
It's hard to separate
- 5. The coupling taboo between modules leads to the confusion of interfaces and dependencies.
Unable to unit test
So in order to solve the above problems, we need to adopt a more standardized way to reduce the coupling degree between modules, and then the componentization came into being, componentization can also be understood as modularization
Description of application of componentization
The benefits of componentization are mentioned above, but because componentization is also costly, requiring time to design interfaces, separate code, etc., not all projects need to be componentized. Your project does not need to be componentized if it has three or more of the following characteristics:
- 1.
Smaller projects
, simple interaction between modules, less coupling - 2. The project
Not referenced by multiple external modules
, is just a single little module - 3.
Modules do not need to be reused
.Code is rarely changed
- 4. Team
small
- 5.
No unit tests need to be written
If you have more than three of the following characteristics, you need to consider componentization:
- 1. The module
Complex logic
, between multiple modulesFrequent cross-references
- 2. The project
It's getting bigger
.Modify the code
More and moredifficult
(If you change one part of the code, you need to change several other places at the same time.) - 3. The team
The number of more
Submitted,code
Often with other membersconflict
- 4. Project
Large compilation time
- 5. The module
Unit testing
Often due toOther modules
Modifications andfailure
Componentization scheme
Componentized indicators
How to judge whether the componentization of a project is thorough or excellent after componentization can be judged from the following aspects:
- 1.
There is no coupling between modules
Changes made within a module do not apply to other modules - 2.
Modules can be compiled separately
- 3.
Clear data transfer between modules
- 4.
The module
canAt any time
By another module that provides the same functionalityreplace
- 5.
The external interface of the module is clear and easy to maintain
- 6. When
Module interface change
When, of this moduleExternal code
It can beEfficient refactoring
- 7. As far as possible
With minimal modifications and code
Let the existingProject implementation modularization
- Support 8.
OC and Swift, and remix
The first four are used to measure whether a module is truly decoupled, while the last four are used to measure how easy it is to use in practice in a project
Principle of componentization
Generally, a project is divided into three levels:The business layer
.General layer
.Base layer
, as shown in the figure below:When componentizing, there are several points to note:
- 1.
Only the top can depend on the bottom
.There can be no dependence of the lower on the higher
Because the lower layer is an abstraction from the upper layer - 2. The project
Common code resources sink
- 3.
Horizontal dependencies should be minimized
, it is best to follow horizontally· Sink to universal module
orBasic module
Componentization scheme
Currently, there are two common componentization schemes:
- 1,
Local componentization
: Mainly throughCreate the Library in the project
, the use ofThe cocoapods workspec
forLocal management
.Don't need
The projectUpload the git
, butdirectly
inProject in framework mode
forcall
- 2.
Cocoapods componentization
: Mainly usecocoapods
To carry outThe module
theRemote management
, you need toUpload your project to Git
(where theComponentized modules
Divided intoThe public library
andPrivate libraries
forThe company is concerned
, usuallyPrivate libraries
)
Let’s talk about local componentization
Local componentization
1. Create a main project
- Create the main project first
- Integrate Cocopods for local management
$CD Project directory $pod initCopy the code
- Edit the podfile and execute Pod Install
2. Create a component
Create your own module:
The main project
: Mainly implements the surface business codeBase
Base class encapsulationTools
: tools (strings, colors, fonts, etc.)Service
: service layer, which encapsulates business tool classes, such as network layer services and persistence servicesPods
: Third-party dependencies
The relationship of each module is as follows:Now let’s do a simple module creationService
For example:
- 1. Choose choices
new -> project -> iOS -> Framework
, create a new oneThe module
- 2. Choose the right one
Group
andWorkSpace
One thing to note here: the library you createdPreferably in the main project root directory
Under, otherwise follow-upPodfile receives an error when executing pod Install
)
- 3. To be created
library
theBuild Settings -> Mach-O Type
Modified toStatic Library
- 4. Write the required code in LjComponentA
- In 5.
Build Phases -> Headers -> Public
Add the newly created file to public so that the main project can access it
- 6. In the main project, choose
target -> Linked Binary With Libraries
To add LjComponentA, only need to build the main project, library can automatically link
- 7. Main project invocation
The important thing to note here is,Calls between child libraries
, andThe main project calls library similarly
The main needAdd the dependent
,Exposure to the header
Can be
- 8. Use Cocoapods to manage third-party dependencies
So let’s say we need to be inLjComponentA encapsulates network layer code
, need to useThree party libraries Alamofire
Make the following changes in your podfilethenpod install
After success can be inLjComponentA uses the Alamofire library
theAt this point, a local componentized module is configured
Cocoapods componentization
In addition to local componentization, you can also use Cocoapods, which works as shown belowAgain, take local componentization services as an example
Create a private repository
- 1. Create a TestPodsComponent repository on Github
To do this, go to Github and click “+” in the upper right corner. Select New Repository. Enter Repository name as TestPodsComponent, select repository type as private, and click Create Repository.
- 2. Add the private repository to the local ~/.cocoapods/repos directory
pod repo add TestPodsComponent https://github.com/xxxx/TestPodsComponent.git
Copy the code
Create the PODS project, or componentized project
- 1. Create a vm using a terminal
TestPodsComponent
The module
pod lib create TestPodsComponent
Copy the code
- 2. Select a value as prompted
IOS, Swift, Yes, None, No
- 3. Go to the module directory and will need the files
copy
toTestPodsComponent -> Classes
In the
- 4. Perform
pod install
, updates the Classes content to pods
Configure PODS project
Modify the configuration files of the modules, namely TestPodsComponent podspec
- To rely on third-party libraries, you need to configure S. dependency
S.dependency 'AFNetworking' # rely on AFNetworkingCopy the code
- If modules need to reference each other, s.dependency must also be configured. For example, LjBase must reference LjService
//********1, modify podspec file pod 'LjServices' //********2, modify podfile pod 'LjServices' :path => '.. /.. /LjServices'Copy the code
- If you need to load resources, such as images, JSON, bundles, etc
- 1. Add the resource file to the Assets folder of the module
- 2. Configure resource paths in the specs (mandatory!! Otherwise the resource cannot be read.
- 3. Specify the path of the resource file
//*****1. Modify podspec s.lesource_bundles = {'LjBase' => ['LjBase/Assets/*']} //***** String = Bundle.init(for: dynamicClass.self).resourcePath! + "/LjBase.bundle" let bundle = Bundle(path: bundlePath) if let path = bundle? .path(forResource: "mouse", ofType: "jpg"){ self.imgView.image = UIImage(contentsOfFile: path) }Copy the code
Similarly, the xiB and JSON files in the module are obtained in the same way
Submitted to git
The TestPodsComponent is a private library we have just built in Git: TestPodsComponent
- Run the following terminal command
[Note] : After executing git add., you’d better run git status to check the status
Verify the PodSpec file
Run the terminal command pod spec lint
pod spec
Relative to thepod lib
willmore
foraccurate
pod lib
The equivalent of onlyvalidation
aLocal repository
pod spec
willAlso validate the local repository
andRemote warehouse
Add —-allow-warnings to remove warnings
[if there is an ERROR: – ERROR | (iOS) file patterns: The “source_files” pattern did not match any file.”
This is because the corresponding folder is not found in CocoapOS. You can do the following
Go to/Users/username/Library/Caches/CocoaPods/Pods/External/your project name
Go to the latest log file and place it in the same path as the source_files file
Commit to a private repository
Execute the following command: pod repo push [local Spec repo name][Podspec file path]Once submitted successfully, the following is ready to use
use
- To create a new project, add the following to the new project’s podfile:
- Perform pod install
Now that we’ve componentized Cocoapods, we’ll look at communication between componentization in the next article
Related articles recommended links
IOS componentization – Basics
expand
The above we can see TestPodsComponent. Podspec content: s.n ame, s.v ersion let’s explain each item is what mean
s.name
= “TestPodsComponent”The project name
s.version
= “0.1.0 from”The version number corresponds to the label number in your warehouse
s.summary
= ‘ this is a Test Pods Component.’Project introduction
s.license
= { :type => “MIT”, :file => “LICENSE” }Open Source License
s.homepage
=”git.com/xxx”Warehouse home page
s.source
= { :git => “git.com/xxx.git”, :branch => ‘master’, :tag => “#{s.version}” }Your warehouse address, not your SSH address
s.source_files
= “TestPodsComponent/Classes/. {h, m} or TestPodsComponent/Classes /”Location of code
s.requires_arc
= trueWhether to enable ARC
s.platform
= : ios, “9.0”Platform and the lowest supported version
s.xcconfig
= { ‘OTHER_LDFLAGS’ => ‘-Objc -all_load -fobjc-arc’ ,’ENABLE_BITCODE’ => ‘NO’}Target related Settings
s.author
= { “author” => “xxx.com” }Author information, open source online may be sent by email
s.frameworks
= “UIKit”, “Foundation”Supported frameworks
s.resource_bundles
= {‘TestPodsComponent’ => [‘TestPodsComponent/Assets/*.png’]}Resource file
s.dependency
= “AFNetworking”Dependency libraries, write as many dependency libraries as possible
s.dependency
‘AFNetworking’, ‘~ > 4.0’You can specify the version