background
As a sequel to my previous post on iOS componentization, I’ll talk about componentization implementation and integration on iOS using Cocoapods.
The results of
The two examples in this article can be found in the YTThirdPlatformManager project.
Tool is introduced
Cocoapods is a development library management tool for iOS/ OSX platforms. After simple configuration and installation commands are executed, Cocoapods automatically downloads third-party libraries and performs corresponding configuration, simplifying the process of introducing third-party libraries and making development easier and more efficient. It is a necessary tool for iOS development. Using Cocoapods as a componentized tool is a good choice.
Installation and Setup
Installation and design can be referred to this article: Cocopods Installation and Upgrade Memo
implementation
Simple project componentization
Componentization of a simple project with a test module decoupling scenario consists of the following
- Pod library project creation
- Explains the most basic podSpec file written
- Client integration
Create a project
When creating a project using pod Lib Create, you will encounter several areas that require input. See the comments in the code snippet for details
➜ DevPods pod lib create PTTestKit Cloning ` https://github.com/CocoaPods/pod-template.git ` into ` PTTestKit `. You PTTestKit template. ------------------------------ To get you started we need to ask a few questions, this should only take a minute. If this is your first time we recommend running through with the guide: - http://guides.cocoapods.org/making/using-pod-lib-create.html ( hold cmd and double click links to openin a browser. )
# The language used
What language do you want to use?? [ Swift / ObjC ]
> Objc
Specify YES for modular decoupling tests
Would you like to include a demo application with your library? [ Yes / No ]
>
yes
No need to specify None for integrated test modules
Which testing frameworks will you use? [ Specta / Kiwi / None ]
> None
# UI test module, No need to specify No
Would you like to do view based testing? [ Yes / No ]
> No
# specify the class prefix
What is your class prefix?
> PT
Running pod install on your new library.
Copy the code
Podspec file
A simple PodSpec file is shown below, and you can see the comments in the code for explanations of specific fields
Pod::Spec.new do |s|
s.name = 'PTTestKit'
s.version = '0.1.0 from'
s.summary = 'Wow PTTestKit.'
# This description is used to generate tags and improve search results.
# * Think: What does it do? Why did you write it? What is the focus?
# * Try to keep it short, snappy and to the point.
# * Write the description between the DESC delimiters below.
# * Finally, don't worry about the indent, CocoaPods strips it!
# Long description
s.description = <<-DESC Wow this is a amazing kit, Enjoy yourself! DESC
If you do not commit, you can specify any value, but you need to keep this item, otherwise you will get an error
# attributes: Missing required attribute `homepage`.
s.homepage = 'https://github.com/flypigrmvb/PTTestKit'
# s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
# License file
s.license = { :type= >'MIT'.:file= >'LICENSE' }
# User information
s.author = { 'flypigrmvb'= >'[email protected]' }
Git git git git git git git git git git git git git git
# attributes: Missing required attribute `source`.
s.source = { :git= >'https://github.com/flypigrmvb/PTTestKit.git'.:tag => s.version.to_s }
# s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'
# specify the lowest ios version
s.ios.deployment_target = '8.0'
The path to the source file
s.source_files = 'PTTestKit/Classes/**/*'
Public header file, set as needed
s.public_header_files = 'PTTestKit/Classes/Public/**/*.h'
# Private header file, set as needed
s.private_header_files = 'PTTestKit/Classes/Private/**/*.h'
# Dependent system Framework, set as needed
# s.frameworks = 'UIKit', 'MapKit'
# Rely on other POD libraries, as needed
# s.dependency 'AFNetworking', '~> 2.3'
end
Copy the code
Client integration
If you integrate the Example test project in the step of creating the Pod library project, the podfile under the test project contains the current Pod library project by default
#use_frameworks!
target 'PTTestKit_Example' do
pod 'PTTestKit'.:path= >'.. / '
target 'PTTestKit_Tests' do
inherit! :search_paths
end
end
Copy the code
Switch to the test project directory and run the pod install command. After that, the test project integrates with the POD project. Here is a simple example z of using some of the Pod library project features in your test project
#import "PTViewController.h"
#import <PTTestKit/PublicFile.h>
/ /!!!!! Private Headers can be imported
#import <PTTestKit/PrivateFile.h>
/ /!!!!! An error
//#import <PTTestKit/ProjectFile.h>
@interface PTViewController(a)
@end
@implementation PTViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self addActionWithName:@"Test" callback:^{
NSLog(@ "= = = =");
}];
[self addActionWithName:@"PrivateFile" callback:^{
[PrivateFile test];
}];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[PrivateFile test];
}
@end
Copy the code
Modular componentization
Take a third-generation component integration scenario as an example to realize modular componentization, which mainly includes the following contents:
- Create core modules
- Creating submodules
- Client integration
The process of creating a POD library project is the same as the simple module component steps, which will not be described here
Podspec file
This file creates a Core module that houses abstract interfaces, base classes, and some common utility classes and header files, as well as several submodules for specific third-party platform implementations. For details, see the comments in the code below
Pod::Spec.new do |s|
s.name = 'PTThirdPlatformKit'
s.version = '0.1.0 from'
s.summary = 'A short description of PTThirdPlatformKit.'
# This description is used to generate tags and improve search results.
# * Think: What does it do? Why did you write it? What is the focus?
# * Try to keep it short, snappy and to the point.
# * Write the description between the DESC delimiters below.
# * Finally, don't worry about the indent, CocoaPods strips it!
s.description = <<-DESC TODO: Add long description of the pod here. DESC
s.homepage = 'https://github.com/flypigrmvb/PTThirdPlatformKit'
# s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
s.license = { :type= >'MIT'.:file= >'LICENSE' }
s.author = { 'flypigrmvb'= >'[email protected]' }
s.source = { :git= >'https://github.com/flypigrmvb/PTThirdPlatformKit.git'.:tag => s.version.to_s }
# s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'
s.ios.deployment_target = '8.0'
If the pod project in the POD file does not specify a submodule, import the module specified here
s.default_subspec = 'Core'
Define a core module where users hold abstract interfaces, base classes, and some common utility classes and header files
s.subspec 'Core' do |subspec|
# source code
subspec.source_files = 'PTThirdPlatformKit/Classes/**/*'
Configure the system Framework
subspec.frameworks = 'CoreMotion'
subspec.dependency 'SDWebImage'
Add a dependent system static library
subspec.libraries = 'xml2'.'z'.'c++'.'stdc++.6'.'sqlite3'
end
# Alipay module
s.subspec 'AlipayManager' do |subspec|
# source code
subspec.source_files = 'PTThirdPlatformKit/AlipayManager/**/*'
Add resource file
subspec.resource = 'PTThirdPlatformKit/AlipayManager/**/*.bundle'
# Add a framework that relies on third parties
subspec.vendored_frameworks = 'PTThirdPlatformKit/AlipayManager/**/*.framework'
Add a framework that depends on the system
subspec.frameworks = 'CoreTelephony'.'SystemConfiguration'
# Dependency core modules
subspec.dependency 'PTThirdPlatformKit/Core'
end
Module # QQ
s.subspec 'TencentManager' do |subspec|
# source code
subspec.source_files = 'PTThirdPlatformKit/TencentManager/**/*'
Add resource file
subspec.resource = 'PTThirdPlatformKit/TencentManager/**/*.bundle'
# Add a framework that relies on third parties
subspec.vendored_frameworks = 'PTThirdPlatformKit/TencentManager/**/*.framework'
Add a framework that depends on the system
subspec.frameworks = 'SystemConfiguration'
# Dependency core modules
subspec.dependency 'PTThirdPlatformKit/Core'
end
# Microblog module
s.subspec 'WeiboManager' do |subspec|
# source code
subspec.source_files = 'PTThirdPlatformKit/WeiboManager/**/*'
# Rely on the Pod library of microblogging
subspec.dependency 'WeiboSDK'
subspec.dependency 'PTThirdPlatformKit/Core'
end
# wechat module
s.subspec 'WXManager' do |subspec|
# source code
subspec.source_files = 'PTThirdPlatformKit/WXManager/**/*'
# Rely on wechat POD library
subspec.dependency 'WechatOpenSDK'
subspec.dependency 'PTThirdPlatformKit/Core'
end
end
Copy the code
Client integration
The podfile file is shown below and you can import the main module and any combination of submodules
#use_frameworks!
platform :ios.'8.0'
target 'PTThirdPlatformKit_Example' do
pod 'PTTestKit'.:path= >'.. /.. /PTTestKit'
# main module
pod 'PTThirdPlatformKit'.:path= >'.. / '
# Submodules are fast
pod 'PTThirdPlatformKit/AlipayManager'.:path= >'.. / '
pod 'PTThirdPlatformKit/TencentManager'.:path= >'.. / '
pod 'PTThirdPlatformKit/WeiboManager'.:path= >'.. / '
pod 'PTThirdPlatformKit/WXManager'.:path= >'.. / '
end
target 'PTThirdPlatformKit_Example_Developer' do
pod 'PTTestKit'.:path= >'.. /.. /PTTestKit'
pod 'PTThirdPlatformKit'.:path= >'.. / '
pod 'PTThirdPlatformKit/AlipayManager'.:path= >'.. / '
pod 'PTThirdPlatformKit/TencentManager'.:path= >'.. / '
pod 'PTThirdPlatformKit/WeiboManager'.:path= >'.. / '
pod 'PTThirdPlatformKit/WXManager'.:path= >'.. / '
end
Copy the code
Have a problem
The Pod library under development depends on the processing of another Pod library
Reference: guides.cocoapods.org/syntax/pods… Podspec file to add
s.vendored_frameworks = 'PTDataModule/Frameworks/*.framework'
Copy the code
Configure non-ARC files in the ARC environment
Need to use podspec subspec and requires_arc reference in the rule: guides.cocoapods.org/syntax/pods… Guides.cocoapods.org/syntax/pods…
s.requires_arc = true
# no arc files rules
non_arc_files = 'PTDataModule/Classes/**/JSONKit.{h,m}'
s.exclude_files = non_arc_files
s.subspec 'no-arc' do |sna|
sna.requires_arc = false
sna.source_files = non_arc_files
end
Copy the code
PrefixHeader
Reference: guides.cocoapods.org/syntax/pods…
Podspec specifies the PTDataModule-prefixheader. PCH file
s.prefix_header_file = 'PTDataModule/SupportFiles/PTDataModule-prefixheader.pch'
Copy the code
PTDataModule- prefixHeader. PCH file contents
#import "UtilMacro.h"
#import "DebugConfig.h"
#import "TIMAdapter.h"
Copy the code
There is a bug where the custom PCH file is not found in the project after using Pod Install, but the content is added to PTDataModule- prefix-pch file
Can use this way, the need to import directly to the header files using parameters specified reference: guides.cocoapods.org/syntax/pods…
spec.prefix_header_contents = '#import <UIKit/UIKit.h>'.'#import <Foundation/Foundation.h>'
Copy the code
Pod update failure
[!] The'Pods-PTThirdPlatformKit_Example'target has transitive dependencies that include static binaries: (/ Users/aron/PuTaoWorkSpace/Plush_devpods_developer/DevPods/PTThirdPlatformKit/Example/Pods/WechatOpenSDK/OpenSDK1.8.0 / l ibWeChatSDK.a and /Users/aron/PuTaoWorkSpace/Plush_devpods_developer/DevPods/PTThirdPlatformKit/Example/Pods/WeiboSDK/libWeiboSDK/libWeibo SDK.a)Copy the code
#use_frameworks! (Note this)
Add. A static library and the corresponding header PTBehaviorStat
s.public_header_files = 'PTBehaviorStat/Classes/**/*.h'.'PTBehaviorStat/vendor/**/*.h'
s.vendored_library = 'PTBehaviorStat/**/*.a'
Copy the code
Pod lib create problem with GitHub template data
The –template argument specifies the local template data
The Pod development library relies on the local development library
Reference: stackoverflow.com/questions/1… For example, Pod development library A depends on Pod development library B. The dependency information is as follows. You do not need to specify A path to obtain other information
s.dependency 'DevLibB'
Copy the code
Import DevLibB in the podfile of the test project or client project that needs to be displayed
pod 'DevLibB'.:path= >'.. /.. /DevLibB'
Copy the code
Source files cannot be found without configuration pairs
subspec.source_files = 'PTThirdPlatformKit/WeiboManager/**/*'
Copy the code
If the configuration (as shown below) is the wrong path, the class will not be found on the client side, and you need to check that the source file is configured correctly
subspec.source_files = 'PTThirdPlatformKit/WeiboManager111/**/*'
Copy the code
conclusion
The above is a summary of my componentized integration practice using Cocoapods and some of the problems I encountered. I hope it will be helpful to those who need it.
Refer to the link
Cocoapods project home page