以前寫過一篇 iOS 組件化實現的一些思路總結 ,這篇做爲續集,聊一聊使用 Cocoapods
在iOS平臺組件化的實現和集成。html
本文中的兩個例子能夠在 YTThirdPlatformManager 項目中找到。ios
Cocoapods
是iOS/osx平臺的開發庫管理工具,簡單的配置而後執行安裝命令 Cocoapods
會自動去下載第三方庫而且作好相應的配置,簡化了引入第三方庫的流程,讓開發更簡單高效,是iOS開發的必備工具,使用 Cocoapods
做爲組件化的工具是一個不錯的選擇。c++
安裝和設計能夠參考這篇文章: Cocopods安裝和升級備忘錄git
以一個測試模塊解耦的場景實現簡單項目的組件化,主要包含如下內容github
使用 pod lib create
建立項目,會遇到幾個須要輸入的地方,具體的解釋看代碼段中的註釋sql
➜ DevPods pod lib create PTTestKit
Cloning `https://github.com/CocoaPods/pod-template.git` into `PTTestKit`.
Configuring 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 open in a browser. )
# 使用的語言
What language do you want to use?? [ Swift / ObjC ]
> Objc
# 是否包好測試工程,指定YES用於模塊化的解耦測試
Would you like to include a demo application with your library? [ Yes / No ]
>
yes
# 集成的測試模塊,不須要指定None
Which testing frameworks will you use? [ Specta / Kiwi / None ]
> None
# UI測試模塊,不須要指定No
Would you like to do view based testing? [ Yes / No ]
> No
# 指定類前綴
What is your class prefix?
> PT
Running pod install on your new library.
複製代碼
一個簡單的 podspec 文件以下,具體字段的解釋查看代碼中的註釋便可ruby
Pod::Spec.new do |s|
s.name = 'PTTestKit'
s.version = '0.1.0'
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!
# 長的描述信息
s.description = <<-DESC Wow this is a amazing kit, Enjoy yourself! DESC
# 提交到git服務區的項目主頁,沒提交能夠指定任意值,但須要保留這一項,不然會報錯
# attributes: Missing required attribute `homepage`.
s.homepage = 'https://github.com/flypigrmvb/PTTestKit'
# s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
# 受權文件
s.license = { :type => 'MIT', :file => 'LICENSE' }
# 用戶信息
s.author = { 'flypigrmvb' => '862709539@qq.com' }
# 提交到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>'
# 指定最低的ios版本
s.ios.deployment_target = '8.0'
# 源文件的路徑
s.source_files = 'PTTestKit/Classes/**/*'
# 公共的頭文件,按需設置
s.public_header_files = 'PTTestKit/Classes/Public/**/*.h'
# 私有的頭文件,按需設置
s.private_header_files = 'PTTestKit/Classes/Private/**/*.h'
# 依賴的系統Framework,按需設置
# s.frameworks = 'UIKit', 'MapKit'
# 依賴其餘的pod庫,按需設置
# s.dependency 'AFNetworking', '~> 2.3'
end
複製代碼
若是在建立Pod庫項目的步驟集成了 Example 測試項目,在測試項目下的podfile默認包含了當前的Pod庫項目bash
#use_frameworks!
target 'PTTestKit_Example' do
pod 'PTTestKit', :path => '../'
target 'PTTestKit_Tests' do
inherit! :search_paths
end
end
複製代碼
切換到測試項目目錄下,運行 pod install
命令,完了以後測試項目集成了Pod項目。下面是在測試項目中使用Pod庫項目中一些功能的簡單例z微信
#import "PTViewController.h"
#import <PTTestKit/PublicFile.h>
// !!private header 能夠導入
#import <PTTestKit/PrivateFile.h>
// !!報錯
//#import <PTTestKit/ProjectFile.h>
@interface PTViewController ()
@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
複製代碼
以一個第三發組件集成的場景爲例,實現分模塊組件化,主要包含如下內容:app
pod庫項目的建立流程和簡單模塊組件步驟一致,不在贅述
該文件建立了一個Core模塊,用於存放抽象的接口、基類以及一些公用的工具類和頭文件,以及幾個子模塊用於具體的第三方平臺的實現。具體的內容能夠查看如下代碼中的註釋內容
Pod::Spec.new do |s|
s.name = 'PTThirdPlatformKit'
s.version = '0.1.0'
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' => '862709539@qq.com' }
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'
# 設置默認的模塊,若是在pod文件中導入pod項目沒有指定子模塊,導入的是這裏指定的模塊
s.default_subspec = 'Core'
# 定義一個核心模塊,用戶存放抽象的接口、基類以及一些公用的工具類和頭文件
s.subspec 'Core' do |subspec|
# 源代碼
subspec.source_files = 'PTThirdPlatformKit/Classes/**/*'
# 配置系統Framework
subspec.frameworks = 'CoreMotion'
subspec.dependency 'SDWebImage'
# 添加依賴的系統靜態庫
subspec.libraries = 'xml2', 'z', 'c++', 'stdc++.6', 'sqlite3'
end
# 支付寶模塊
s.subspec 'AlipayManager' do |subspec|
# 源代碼
subspec.source_files = 'PTThirdPlatformKit/AlipayManager/**/*'
# 添加資源文件
subspec.resource = 'PTThirdPlatformKit/AlipayManager/**/*.bundle'
# 添加依賴第三方的framework
subspec.vendored_frameworks = 'PTThirdPlatformKit/AlipayManager/**/*.framework'
# 添加依賴系統的framework
subspec.frameworks = 'CoreTelephony', 'SystemConfiguration'
# 依賴的核心模塊
subspec.dependency 'PTThirdPlatformKit/Core'
end
# QQ模塊
s.subspec 'TencentManager' do |subspec|
# 源代碼
subspec.source_files = 'PTThirdPlatformKit/TencentManager/**/*'
# 添加資源文件
subspec.resource = 'PTThirdPlatformKit/TencentManager/**/*.bundle'
# 添加依賴第三方的framework
subspec.vendored_frameworks = 'PTThirdPlatformKit/TencentManager/**/*.framework'
# 添加依賴系統的framework
subspec.frameworks = 'SystemConfiguration'
# 依賴的核心模塊
subspec.dependency 'PTThirdPlatformKit/Core'
end
# 微博模塊
s.subspec 'WeiboManager' do |subspec|
# 源代碼
subspec.source_files = 'PTThirdPlatformKit/WeiboManager/**/*'
# 依賴的微博pod庫
subspec.dependency 'WeiboSDK'
subspec.dependency 'PTThirdPlatformKit/Core'
end
# 微信模塊
s.subspec 'WXManager' do |subspec|
# 源代碼
subspec.source_files = 'PTThirdPlatformKit/WXManager/**/*'
# 依賴的微信pod庫
subspec.dependency 'WechatOpenSDK'
subspec.dependency 'PTThirdPlatformKit/Core'
end
end
複製代碼
podfile文件以下,能夠導入主模塊和任意的子模塊的組合
#use_frameworks!
platform :ios, '8.0'
target 'PTThirdPlatformKit_Example' 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
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
複製代碼
參考: guides.cocoapods.org/syntax/pods…
podspec文件添加添加
s.vendored_frameworks = 'PTDataModule/Frameworks/*.framework'
複製代碼
須要用到podspec規則中的subspec和requires_arc
參考:
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
複製代碼
參考: guides.cocoapods.org/syntax/pods…
podspec指定 PTDataModule-prefixheader.pch 文件
s.prefix_header_file = 'PTDataModule/SupportFiles/PTDataModule-prefixheader.pch'
複製代碼
PTDataModule-prefixheader.pch 文件內容
#import "UtilMacro.h"
#import "DebugConfig.h"
#import "TIMAdapter.h"
複製代碼
有個坑,使用pod install 以後自定義的pch文件在項目中找不到了,可是內容會添加到PTDataModule-prefix.pch文件中
可使用這種方式,直接把須要導入的頭文件使用參數的方式指定
參考:
guides.cocoapods.org/syntax/pods…
spec.prefix_header_contents = '#import <UIKit/UIKit.h>', '#import <Foundation/Foundation.h>'
複製代碼
[!] 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/libWeChatSDK.a and /Users/aron/PuTaoWorkSpace/Plush_devpods_developer/DevPods/PTThirdPlatformKit/Example/Pods/WeiboSDK/libWeiboSDK/libWeiboSDK.a)
複製代碼
解決辦法:
#use_frameworks! (註釋這個)
s.public_header_files = 'PTBehaviorStat/Classes/**/*.h', 'PTBehaviorStat/vendor/**/*.h'
s.vendored_library = 'PTBehaviorStat/**/*.a'
複製代碼
--template 參數指定本地的 模板數據
參考:
stackoverflow.com/questions/1…
好比Pod開發庫A依賴Pod開發庫B,依賴的信息填寫以下便可,不須要指定路徑獲取其餘信息
s.dependency 'DevLibB'
複製代碼
在測試工程或者客戶端工程的的podfile文件中須要顯示的導入DevLibB,這樣便可
pod 'DevLibB', :path => '../../DevLibB'
複製代碼
subspec.source_files = 'PTThirdPlatformKit/WeiboManager/**/*'
複製代碼
若是配置(以下所示)是錯誤的路徑,在客戶端是找不到這個類的,須要檢查源文件配置的是否正確
subspec.source_files = 'PTThirdPlatformKit/WeiboManager111/**/*'
複製代碼
以上是我在使用cocoapods作組件化集成實踐的一些總結和遇到的一些問題,但願對有須要的朋友有幫助。